Skip to content

Commit 8131821

Browse files
committed
Expose Trino backend state via JMX
1 parent 487137c commit 8131821

File tree

3 files changed

+107
-12
lines changed

3 files changed

+107
-12
lines changed

gateway-ha/src/main/java/io/trino/gateway/ha/module/HaGatewayProviderModule.java

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import com.google.common.collect.ImmutableList;
1717
import com.google.inject.AbstractModule;
1818
import com.google.inject.Provides;
19+
import com.google.inject.Scopes;
1920
import com.google.inject.Singleton;
2021
import io.airlift.http.client.HttpClient;
2122
import io.trino.gateway.ha.clustermonitor.ClusterStatsHttpMonitor;
@@ -82,7 +83,6 @@ public class HaGatewayProviderModule
8283
private final LbOAuthManager oauthManager;
8384
private final LbFormAuthManager formAuthManager;
8485
private final AuthorizationManager authorizationManager;
85-
private final BackendStateManager backendStateConnectionManager;
8686
private final ResourceSecurityDynamicFeature resourceSecurityDynamicFeature;
8787
private final HaGatewayConfiguration configuration;
8888
private final ResourceGroupsManager resourceGroupsManager;
@@ -96,6 +96,7 @@ protected void configure()
9696
binder().bind(ResourceGroupsManager.class).toInstance(resourceGroupsManager);
9797
binder().bind(GatewayBackendManager.class).toInstance(gatewayBackendManager);
9898
binder().bind(QueryHistoryManager.class).toInstance(queryHistoryManager);
99+
binder().bind(BackendStateManager.class).in(Scopes.SINGLETON);
99100
}
100101

101102
public HaGatewayProviderModule(HaGatewayConfiguration configuration)
@@ -108,7 +109,6 @@ public HaGatewayProviderModule(HaGatewayConfiguration configuration)
108109

109110
authorizationManager = new AuthorizationManager(configuration.getAuthorization(), presetUsers);
110111
resourceSecurityDynamicFeature = getAuthFilter(configuration);
111-
backendStateConnectionManager = new BackendStateManager();
112112

113113
GatewayCookieConfigurationPropertiesProvider gatewayCookieConfigurationPropertiesProvider = GatewayCookieConfigurationPropertiesProvider.getInstance();
114114
gatewayCookieConfigurationPropertiesProvider.initialize(configuration.getGatewayCookieConfiguration());
@@ -206,13 +206,6 @@ public AuthorizationManager getAuthorizationManager()
206206
return this.authorizationManager;
207207
}
208208

209-
@Provides
210-
@Singleton
211-
public BackendStateManager getBackendStateConnectionManager()
212-
{
213-
return this.backendStateConnectionManager;
214-
}
215-
216209
@Provides
217210
@Singleton
218211
public RoutingGroupSelector getRoutingGroupSelector(@ForRouter HttpClient httpClient)

gateway-ha/src/main/java/io/trino/gateway/ha/router/BackendStateManager.java

Lines changed: 90 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,29 @@
1313
*/
1414
package io.trino.gateway.ha.router;
1515

16+
import com.google.common.collect.ImmutableMap;
17+
import com.google.inject.Inject;
1618
import io.trino.gateway.ha.clustermonitor.ClusterStats;
19+
import io.trino.gateway.ha.clustermonitor.TrinoStatus;
1720
import io.trino.gateway.ha.config.ProxyBackendConfiguration;
21+
import org.weakref.jmx.MBeanExporter;
22+
import org.weakref.jmx.Managed;
1823

1924
import java.util.HashMap;
2025
import java.util.Map;
2126

27+
import static java.util.Objects.requireNonNull;
28+
2229
public class BackendStateManager
2330
{
24-
private final Map<String, ClusterStats> clusterStats;
31+
private final MBeanExporter exporter;
32+
private final Map<String, ClusterStats> clusterStats = new HashMap<>();
33+
private final Map<String, ClusterStatsJMX> clusterStatsJMXs = new HashMap<>();
2534

26-
public BackendStateManager()
35+
@Inject
36+
public BackendStateManager(MBeanExporter exporter)
2737
{
28-
this.clusterStats = new HashMap<>();
38+
this.exporter = requireNonNull(exporter, "exporter is null");
2939
}
3040

3141
public ClusterStats getBackendState(ProxyBackendConfiguration backend)
@@ -36,6 +46,83 @@ public ClusterStats getBackendState(ProxyBackendConfiguration backend)
3646

3747
public void updateStates(String clusterId, ClusterStats stats)
3848
{
49+
if (!clusterStatsJMXs.containsKey(clusterId)) {
50+
ClusterStatsJMX clusterStatsJMX = new ClusterStatsJMX(stats);
51+
exporter.exportWithGeneratedName(
52+
clusterStatsJMX,
53+
ClusterStatsJMX.class,
54+
ImmutableMap.<String, String>builder()
55+
.put("name", "ClusterStats")
56+
.put("cluster_id", clusterId)
57+
.build());
58+
clusterStatsJMXs.put(clusterId, clusterStatsJMX);
59+
}
60+
else {
61+
clusterStatsJMXs.get(clusterId).updateFrom(stats);
62+
}
3963
clusterStats.put(clusterId, stats);
4064
}
65+
66+
public static class ClusterStatsJMX
67+
{
68+
int runningQueryCount;
69+
int queuedQueryCount;
70+
int numWorkerNodes;
71+
TrinoStatus trinoStatus;
72+
73+
public ClusterStatsJMX(ClusterStats clusterStats)
74+
{
75+
updateFrom(clusterStats);
76+
}
77+
78+
public void updateFrom(ClusterStats clusterStats)
79+
{
80+
runningQueryCount = clusterStats.runningQueryCount();
81+
queuedQueryCount = clusterStats.queuedQueryCount();
82+
numWorkerNodes = clusterStats.numWorkerNodes();
83+
trinoStatus = clusterStats.trinoStatus();
84+
}
85+
86+
@Managed
87+
public int getRunningQueryCount()
88+
{
89+
return runningQueryCount;
90+
}
91+
92+
@Managed
93+
public int getQueuedQueryCount()
94+
{
95+
return queuedQueryCount;
96+
}
97+
98+
@Managed
99+
public int getNumWorkerNodes()
100+
{
101+
return numWorkerNodes;
102+
}
103+
104+
@Managed
105+
public int getTrinoStatusPending()
106+
{
107+
return trinoStatus == TrinoStatus.PENDING ? 1 : 0;
108+
}
109+
110+
@Managed
111+
public int getTrinoStatusHealthy()
112+
{
113+
return trinoStatus == TrinoStatus.HEALTHY ? 1 : 0;
114+
}
115+
116+
@Managed
117+
public int getTrinoStatusUnhealthy()
118+
{
119+
return trinoStatus == TrinoStatus.UNHEALTHY ? 1 : 0;
120+
}
121+
122+
@Managed
123+
public int getTrinoStatusUnknown()
124+
{
125+
return trinoStatus == TrinoStatus.UNKNOWN ? 1 : 0;
126+
}
127+
}
41128
}

gateway-ha/src/test/java/io/trino/gateway/ha/TestGatewayHaMultipleBackend.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,21 @@ void testHealthCheckEndpoints()
387387
throw new IllegalStateException("Trino Gateway health check failed");
388388
}
389389

390+
@Test
391+
void testClusterStatsJMX()
392+
throws Exception
393+
{
394+
Thread.sleep(5000); // Wait for first health check to run
395+
Request request = new Request.Builder()
396+
.url("http://localhost:" + routerPort + "/metrics")
397+
.get()
398+
.build();
399+
Response response = httpClient.newCall(request).execute();
400+
String body = response.body().string();
401+
assertThat(body).contains("trino1_TrinoStatusHealthy");
402+
assertThat(body).contains("trino2_TrinoStatusHealthy");
403+
}
404+
390405
@AfterAll
391406
void cleanup()
392407
{

0 commit comments

Comments
 (0)