Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions presto-docs/src/main/sphinx/admin/properties.rst
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,15 @@ Maximum object size in bytes that can be considered serializable in a function c

The corresponding session property is :ref:`admin/properties-session:\`\`max_serializable_object_size\`\``.

``cluster-tag``
^^^^^^^^^^^^^^^

* **Type:** ``string``
* **Default value:** (none)

An optional identifier for the cluster. When set, this tag is included in the response from the
``/v1/cluster`` REST API endpoint, allowing clients to identify which cluster provided the response.

Memory Management Properties
----------------------------

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ public class ServerConfig
private Duration clusterStatsExpirationDuration = new Duration(0, MILLISECONDS);
private boolean nestedDataSerializationEnabled = true;
private Duration clusterResourceGroupStateInfoExpirationDuration = new Duration(0, MILLISECONDS);
private String clusterTag;

public boolean isResourceManager()
{
Expand Down Expand Up @@ -240,4 +241,16 @@ public ServerConfig setClusterResourceGroupStateInfoExpirationDuration(Duration
this.clusterResourceGroupStateInfoExpirationDuration = clusterResourceGroupStateInfoExpirationDuration;
return this;
}

public String getClusterTag()
{
return clusterTag;
}

@Config("cluster-tag")
public ServerConfig setClusterTag(String clusterTag)
{
this.clusterTag = clusterTag;
return this;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ public class DistributedClusterStatsResource
private final ResourceManagerClusterStateProvider clusterStateProvider;
private final InternalNodeManager internalNodeManager;
private final Supplier<ClusterStats> clusterStatsSupplier;
private final String clusterTag;

@Inject
public DistributedClusterStatsResource(
Expand All @@ -61,7 +62,9 @@ public DistributedClusterStatsResource(
this.isIncludeCoordinator = requireNonNull(nodeSchedulerConfig, "nodeSchedulerConfig is null").isIncludeCoordinator();
this.clusterStateProvider = requireNonNull(clusterStateProvider, "nodeStateManager is null");
this.internalNodeManager = requireNonNull(internalNodeManager, "internalNodeManager is null");
Duration expirationDuration = requireNonNull(serverConfig, "serverConfig is null").getClusterStatsExpirationDuration();
ServerConfig config = requireNonNull(serverConfig, "serverConfig is null");
this.clusterTag = config.getClusterTag();
Duration expirationDuration = config.getClusterStatsExpirationDuration();
this.clusterStatsSupplier = expirationDuration.getValue() > 0 ? memoizeWithExpiration(this::calculateClusterStats, expirationDuration.toMillis(), MILLISECONDS) : this::calculateClusterStats;
}

Expand Down Expand Up @@ -126,7 +129,8 @@ else if (query.getState() == QueryState.RUNNING) {
totalInputRows,
totalInputBytes,
totalCpuTimeSecs,
clusterStateProvider.getAdjustedQueueSize());
clusterStateProvider.getAdjustedQueueSize(),
clusterTag);
}

@GET
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ public class ClusterStatsResource
private final InternalResourceGroupManager internalResourceGroupManager;
private final ClusterTtlProviderManager clusterTtlProviderManager;
private final Supplier<ClusterStats> clusterStatsSupplier;
private final String clusterTag;

@Inject
public ClusterStatsResource(
Expand All @@ -96,7 +97,9 @@ public ClusterStatsResource(
this.proxyHelper = requireNonNull(proxyHelper, "internalNodeManager is null");
this.internalResourceGroupManager = requireNonNull(internalResourceGroupManager, "internalResourceGroupManager is null");
this.clusterTtlProviderManager = requireNonNull(clusterTtlProviderManager, "clusterTtlProvider is null");
Duration expirationDuration = requireNonNull(serverConfig, "serverConfig is null").getClusterStatsExpirationDuration();
ServerConfig config = requireNonNull(serverConfig, "serverConfig is null");
this.clusterTag = config.getClusterTag();
Duration expirationDuration = config.getClusterStatsExpirationDuration();
this.clusterStatsSupplier = expirationDuration.getValue() > 0 ? memoizeWithExpiration(this::calculateClusterStats, expirationDuration.toMillis(), MILLISECONDS) : this::calculateClusterStats;
}

Expand Down Expand Up @@ -170,7 +173,8 @@ else if (query.getState() == QueryState.RUNNING) {
totalInputRows,
totalInputBytes,
totalCpuTimeSecs,
internalResourceGroupManager.getQueriesQueuedOnInternal());
internalResourceGroupManager.getQueriesQueuedOnInternal(),
clusterTag);
}

@GET
Expand Down Expand Up @@ -238,6 +242,8 @@ public static class ClusterStats
private final long totalCpuTimeSecs;
private final long adjustedQueueSize;

private final String clusterTag;

@JsonCreator
@ThriftConstructor
public ClusterStats(
Expand All @@ -251,7 +257,8 @@ public ClusterStats(
@JsonProperty("totalInputRows") long totalInputRows,
@JsonProperty("totalInputBytes") long totalInputBytes,
@JsonProperty("totalCpuTimeSecs") long totalCpuTimeSecs,
@JsonProperty("adjustedQueueSize") long adjustedQueueSize)
@JsonProperty("adjustedQueueSize") long adjustedQueueSize,
@JsonProperty("clusterTag") String clusterTag)
{
this.runningQueries = runningQueries;
this.blockedQueries = blockedQueries;
Expand All @@ -264,6 +271,7 @@ public ClusterStats(
this.totalInputBytes = totalInputBytes;
this.totalCpuTimeSecs = totalCpuTimeSecs;
this.adjustedQueueSize = adjustedQueueSize;
this.clusterTag = clusterTag;
}

@JsonProperty
Expand Down Expand Up @@ -342,5 +350,12 @@ public long getAdjustedQueueSize()
{
return adjustedQueueSize;
}

@JsonProperty
@ThriftField(12)
public String getClusterTag()
{
return clusterTag;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,7 @@ else if (serverConfig.isCoordinator()) {

install(new InternalCommunicationModule());

configBinder(binder).bindConfig(ServerConfig.class);
configBinder(binder).bindConfig(FeaturesConfig.class);
configBinder(binder).bindConfig(FunctionsConfig.class);
configBinder(binder).bindConfig(JavaFeaturesConfig.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ public class TestThriftClusterStats
public static final long TOTAL_INPUT_BYTES = 1003;
public static final long TOTAL_CPU_TIME_SECS = 1004;
public static final long ADJUSTED_QUEUE_SIZE = 1005;
public static final String CLUSTER_TAG = "test-cluster";
private static final ThriftCodecManager COMPILER_READ_CODEC_MANAGER = new ThriftCodecManager(new CompilerThriftCodecFactory(false));
private static final ThriftCodecManager COMPILER_WRITE_CODEC_MANAGER = new ThriftCodecManager(new CompilerThriftCodecFactory(false));
private static final ThriftCodec<ClusterStats> COMPILER_READ_CODEC = COMPILER_READ_CODEC_MANAGER.getCodec(ClusterStats.class);
Expand Down Expand Up @@ -111,6 +112,7 @@ private void assertSerde(ClusterStats clusterStats)
assertEquals(clusterStats.getTotalInputBytes(), TOTAL_INPUT_BYTES);
assertEquals(clusterStats.getTotalCpuTimeSecs(), TOTAL_CPU_TIME_SECS);
assertEquals(clusterStats.getAdjustedQueueSize(), ADJUSTED_QUEUE_SIZE);
assertEquals(clusterStats.getClusterTag(), CLUSTER_TAG);
}

private ClusterStats getRoundTripSerialize(ThriftCodec<ClusterStats> readCodec, ThriftCodec<ClusterStats> writeCodec, Function<TTransport, TProtocol> protocolFactory)
Expand All @@ -134,6 +136,7 @@ private ClusterStats getClusterStats()
TOTAL_INPUT_ROWS,
TOTAL_INPUT_BYTES,
TOTAL_CPU_TIME_SECS,
ADJUSTED_QUEUE_SIZE);
ADJUSTED_QUEUE_SIZE,
CLUSTER_TAG);
}
}
92 changes: 63 additions & 29 deletions presto-ui/src/components/PageTitle.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ export const PageTitle = (props: Props): React.Node => {
modalShown: false,
errorText: null,
});
const [clusterTag, setClusterTag] = useState(null);

const timeoutId = useRef<TimeoutID | null>(null);

Expand Down Expand Up @@ -120,6 +121,17 @@ export const PageTitle = (props: Props): React.Node => {
};
}, []);

useEffect(() => {
fetch("/v1/cluster")
.then((response) => response.json())
.then((clusterResponse) => {
setClusterTag(clusterResponse.clusterTag);
})
.catch((error) => {
console.error("Could not fetch cluster response:", error);
});
}, []);

const renderStatusLight = () => {
if (state.noConnection) {
if (state.lightShown) {
Expand All @@ -140,7 +152,7 @@ export const PageTitle = (props: Props): React.Node => {
return (
<div>
<nav className="navbar navbar-expand-lg navbar-dark bg-dark">
<div className="container-fluid">
<div className="container-fluid gap-4">
<div className="navbar-header">
<table>
<tbody>
Expand Down Expand Up @@ -170,39 +182,61 @@ export const PageTitle = (props: Props): React.Node => {
>
<span className="navbar-toggler-icon"></span>
</button>
<div id="navbar" className="navbar-collapse collapse">
<ul className="nav navbar-nav navbar-right ms-auto">
<li>
<span className="navbar-cluster-info">
<span className="uppercase">Version</span>
<br />
<span className="text" id="version-number">
<div id="navbar" className="navbar-collapse collapse min-width-0">
<ul className="nav navbar-nav navbar-right gap-3 flex-nowrap justify-content-end align-items-center min-width-0 flex-grow-1">
<li className="flex-basis-40 min-width-0 flex-grow-1">
<div className="navbar-cluster-info">
<div className="uppercase">Version</div>
<div
title={info?.nodeVersion?.version}
className="text text-truncate"
id="version-number"
>
{isOffline() ? "N/A" : info?.nodeVersion?.version}
</span>
</span>
</div>
</div>
</li>
<li>
<span className="navbar-cluster-info">
<span className="uppercase">Environment</span>
<br />
<span className="text" id="environment">
<li className="flex-basis-20 min-width-0 flex-shrink-0">
<div className="navbar-cluster-info">
<div className="uppercase">Environment</div>
<div className="text" id="environment">
{isOffline() ? "N/A" : info?.environment}
</span>
</span>
</div>
</div>
</li>
<li>
<span className="navbar-cluster-info">
<span className="uppercase">Uptime</span>
<br />
<span data-bs-toggle="tooltip" data-bs-placement="bottom" title="Connection status">
{renderStatusLight()}
</span>
&nbsp;
<span className="text" id="uptime">
{isOffline() ? "Offline" : info?.uptime}
</span>
</span>
<li className="flex-basis-20 min-width-0 flex-shrink-0">
<div className="navbar-cluster-info">
<div className="uppercase">Uptime</div>
<div>
<span
data-bs-toggle="tooltip"
data-bs-placement="bottom"
title="Connection status"
>
{renderStatusLight()}
</span>
&nbsp;
<span className="text" id="uptime">
{isOffline() ? "Offline" : info?.uptime}
</span>
</div>
</div>
</li>
{clusterTag && (
<li key="cluster-tag" className="min-width-0 flex-shrink-0">
<div className="navbar-cluster-info">
<div className="uppercase">Tag</div>
<div className="text" title="Cluster Tag">
<span
title={clusterTag}
className="badge bg-secondary truncated-badge d-inline-block"
>
{clusterTag}
</span>
</div>
</div>
</li>
)}
</ul>
</div>
</div>
Expand Down
20 changes: 19 additions & 1 deletion presto-ui/src/static/assets/presto.css
Original file line number Diff line number Diff line change
Expand Up @@ -260,8 +260,8 @@ pre {
.navbar-cluster-info {
display: block;
box-sizing: border-box;
padding: 15px;
position: relative;
padding: 15px 0;
color: #666;
font-size: 11px;
}
Expand All @@ -271,6 +271,24 @@ pre {
font-size: 16px;
}

.min-width-0 {
min-width: 0;
}

.flex-basis-40 {
flex-basis: 40%;
min-width: 0;
}

.flex-basis-20 {
flex-basis: 20%;
min-width: 0;
}

.truncated-badge {
white-space: unset;
}

#page-subtitle {
color: #8c8c8c;
padding-left: 3px;
Expand Down
Loading