Skip to content

Commit b4b7674

Browse files
pujaganidiemol
andauthored
Expose server config, session queue and node as MBeans for JMX monitoring. (#8838)
* Expose server config, session queue and node as MBeans for JMX monitoring. * Making tests compile again * [grid] Add JMX queuer tests. Fix indentation. * [grid] Use isZero() in JMXTest * [grid] Fix newsessionqueue config test. * [grid] Update assert for JMXTest. * [grid] Fix node JMXTest. * [grid] Avoid starting the server to test JMX registration. * [grid] Unregister MXBean before testing. * Addressing comments to merge this PR Co-authored-by: Diego Molina <[email protected]> Co-authored-by: Diego Molina <[email protected]>
1 parent 4088ef7 commit b4b7674

File tree

13 files changed

+329
-2
lines changed

13 files changed

+329
-2
lines changed

java/server/src/org/openqa/selenium/grid/node/BUILD.bazel

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ java_library(
2121
"//java/server/src/org/openqa/selenium/grid/security",
2222
"//java/server/src/org/openqa/selenium/grid/web",
2323
"//java/server/src/org/openqa/selenium/status",
24+
"//java/server/src/org/openqa/selenium/remote/server/jmx",
2425
artifact("com.google.guava:guava"),
2526
],
2627
)

java/server/src/org/openqa/selenium/grid/node/local/BUILD.bazel

+1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ java_library(
2525
"//java/server/src/org/openqa/selenium/grid/node/config",
2626
"//java/server/src/org/openqa/selenium/grid/security",
2727
"//java/server/src/org/openqa/selenium/grid/server",
28+
"//java/server/src/org/openqa/selenium/remote/server/jmx",
2829
artifact("com.google.guava:guava"),
2930
],
3031
)

java/server/src/org/openqa/selenium/grid/node/local/LocalNode.java

+50
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import org.openqa.selenium.WebDriverException;
3232
import org.openqa.selenium.concurrent.Regularly;
3333
import org.openqa.selenium.events.EventBus;
34+
import org.openqa.selenium.grid.data.Availability;
3435
import org.openqa.selenium.grid.data.CreateSessionRequest;
3536
import org.openqa.selenium.grid.data.CreateSessionResponse;
3637
import org.openqa.selenium.grid.data.NodeDrainComplete;
@@ -53,6 +54,9 @@
5354
import org.openqa.selenium.remote.SessionId;
5455
import org.openqa.selenium.remote.http.HttpRequest;
5556
import org.openqa.selenium.remote.http.HttpResponse;
57+
import org.openqa.selenium.remote.server.jmx.JMXHelper;
58+
import org.openqa.selenium.remote.server.jmx.ManagedAttribute;
59+
import org.openqa.selenium.remote.server.jmx.ManagedService;
5660
import org.openqa.selenium.remote.tracing.AttributeKey;
5761
import org.openqa.selenium.remote.tracing.EventAttribute;
5862
import org.openqa.selenium.remote.tracing.EventAttributeValue;
@@ -91,6 +95,8 @@
9195
import static org.openqa.selenium.remote.http.Contents.string;
9296
import static org.openqa.selenium.remote.http.HttpMethod.DELETE;
9397

98+
@ManagedService(objectName = "org.seleniumhq.grid:type=Node,name=LocalNode",
99+
description = "Node running the webdriver sessions.")
94100
public class LocalNode extends Node {
95101

96102
private static final Json JSON = new Json();
@@ -173,6 +179,8 @@ private LocalNode(
173179
}
174180
}
175181
}));
182+
183+
new JMXHelper().register(this);
176184
}
177185

178186
@Override
@@ -181,11 +189,53 @@ public boolean isReady() {
181189
}
182190

183191
@VisibleForTesting
192+
@ManagedAttribute(name = "CurrentSessions")
184193
public int getCurrentSessionCount() {
185194
// It seems wildly unlikely we'll overflow an int
186195
return Math.toIntExact(currentSessions.size());
187196
}
188197

198+
@ManagedAttribute(name = "MaxSessions")
199+
public int getMaxSessionCount() {
200+
return maxSessionCount;
201+
}
202+
203+
@ManagedAttribute(name = "Status")
204+
public Availability getAvailability() {
205+
return isDraining() ? DRAINING : UP;
206+
}
207+
208+
@ManagedAttribute(name = "TotalSlots")
209+
public int getTotalSlots() {
210+
return factories.size();
211+
}
212+
213+
@ManagedAttribute(name = "UsedSlots")
214+
public long getUsedSlots() {
215+
return factories.stream().filter(sessionSlot -> !sessionSlot.isAvailable()).count();
216+
}
217+
218+
@ManagedAttribute(name = "Load")
219+
public float getLoad() {
220+
long inUse = factories.stream().filter(sessionSlot -> !sessionSlot.isAvailable()).count();
221+
return inUse / (float) maxSessionCount * 100f;
222+
}
223+
224+
@ManagedAttribute(name = "RemoteNodeUri")
225+
public URI getExternalUri() {
226+
return this.getUri();
227+
}
228+
229+
@ManagedAttribute(name = "GridUri")
230+
public URI getGridUri() {
231+
return this.gridUri;
232+
}
233+
234+
@ManagedAttribute(name = "NodeId")
235+
public String getNodeId() {
236+
return getId().toString();
237+
}
238+
189239
@Override
190240
public boolean isSupporting(Capabilities capabilities) {
191241
return factories.parallelStream().anyMatch(factory -> factory.test(capabilities));

java/server/src/org/openqa/selenium/grid/server/BUILD.bazel

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ java_library(
2020
"//java/server/src/org/openqa/selenium/grid/component",
2121
"//java/server/src/org/openqa/selenium/grid/config",
2222
"//java/server/src/org/openqa/selenium/grid/web",
23+
"//java/server/src/org/openqa/selenium/remote/server/jmx",
2324
artifact("com.beust:jcommander"),
2425
artifact("com.google.guava:guava"),
2526
artifact("javax.servlet:javax.servlet-api"),

java/server/src/org/openqa/selenium/grid/server/BaseServerOptions.java

+9
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,18 @@
2323
import org.openqa.selenium.net.HostIdentifier;
2424
import org.openqa.selenium.net.NetworkUtils;
2525
import org.openqa.selenium.net.PortProber;
26+
import org.openqa.selenium.remote.server.jmx.JMXHelper;
27+
import org.openqa.selenium.remote.server.jmx.ManagedAttribute;
28+
import org.openqa.selenium.remote.server.jmx.ManagedService;
2629

2730
import java.io.File;
2831
import java.net.URI;
2932
import java.net.URISyntaxException;
3033
import java.util.Optional;
3134
import java.util.logging.Logger;
3235

36+
@ManagedService(objectName = "org.seleniumhq.grid:type=Config,name=BaseServerConfig",
37+
description = "Server config")
3338
public class BaseServerOptions {
3439

3540
private static final String SERVER_SECTION = "server";
@@ -40,12 +45,14 @@ public class BaseServerOptions {
4045

4146
public BaseServerOptions(Config config) {
4247
this.config = config;
48+
new JMXHelper().register(this);
4349
}
4450

4551
public Optional<String> getHostname() {
4652
return config.get(SERVER_SECTION, "hostname");
4753
}
4854

55+
@ManagedAttribute(name = "Port")
4956
public int getPort() {
5057
if (port == -1) {
5158
int newPort = config.getInt(SERVER_SECTION, "port")
@@ -61,6 +68,7 @@ public int getPort() {
6168
return port;
6269
}
6370

71+
@ManagedAttribute(name = "MaxServerThreads")
6472
public int getMaxServerThreads() {
6573
int count = config.getInt(SERVER_SECTION, "max-threads")
6674
.orElse(200);
@@ -72,6 +80,7 @@ public int getMaxServerThreads() {
7280
return count;
7381
}
7482

83+
@ManagedAttribute(name = "Uri")
7584
public URI getExternalUri() {
7685
// Assume the host given is addressable if it's been set
7786
String host = getHostname()

java/server/src/org/openqa/selenium/grid/sessionqueue/BUILD.bazel

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ java_library(
2020
"//java/server/src/org/openqa/selenium/grid/data",
2121
"//java/server/src/org/openqa/selenium/grid/log",
2222
"//java/server/src/org/openqa/selenium/status",
23+
"//java/server/src/org/openqa/selenium/remote/server/jmx",
2324
artifact("com.google.guava:guava"),
2425
],
2526
)

java/server/src/org/openqa/selenium/grid/sessionqueue/config/BUILD.bazel

+2
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,13 @@ java_library(
66
srcs = glob(["*.java"]),
77
visibility = [
88
"//java/server/src/org/openqa/selenium/grid:__subpackages__",
9+
"//java/server/test/org/openqa/selenium/grid:__subpackages__",
910
],
1011
deps = [
1112
"//java:auto-service",
1213
"//java/server/src/org/openqa/selenium/grid/config",
1314
"//java/server/src/org/openqa/selenium/grid/sessionqueue",
15+
"//java/server/src/org/openqa/selenium/remote/server/jmx",
1416
artifact("com.beust:jcommander"),
1517
artifact("io.opentelemetry:opentelemetry-api"),
1618
],

java/server/src/org/openqa/selenium/grid/sessionqueue/config/NewSessionQueueOptions.java

+18-2
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,14 @@
1919

2020
import org.openqa.selenium.grid.config.Config;
2121
import org.openqa.selenium.grid.sessionqueue.NewSessionQueue;
22+
import org.openqa.selenium.remote.server.jmx.JMXHelper;
23+
import org.openqa.selenium.remote.server.jmx.ManagedAttribute;
24+
import org.openqa.selenium.remote.server.jmx.ManagedService;
2225

2326
import java.time.Duration;
2427

28+
@ManagedService(objectName = "org.seleniumhq.grid:type=Config,name=NewSessionQueueConfig",
29+
description = "New session queue config")
2530
public class NewSessionQueueOptions {
2631

2732
private static final String SESSIONS_QUEUE_SECTION = "sessionqueue";
@@ -35,10 +40,11 @@ public class NewSessionQueueOptions {
3540

3641
public NewSessionQueueOptions(Config config) {
3742
this.config = config;
43+
new JMXHelper().register(this);
3844
}
3945

4046
public Duration getSessionRequestTimeout() {
41-
int timeout = config.getInt(SESSIONS_QUEUE_SECTION, "session-request-timeout")
47+
long timeout = config.getInt(SESSIONS_QUEUE_SECTION, "session-request-timeout")
4248
.orElse(DEFAULT_REQUEST_TIMEOUT);
4349

4450
if (timeout <= 0) {
@@ -48,7 +54,7 @@ public Duration getSessionRequestTimeout() {
4854
}
4955

5056
public Duration getSessionRequestRetryInterval() {
51-
int interval = config.getInt(SESSIONS_QUEUE_SECTION, "session-retry-interval")
57+
long interval = config.getInt(SESSIONS_QUEUE_SECTION, "session-retry-interval")
5258
.orElse(DEFAULT_RETRY_INTERVAL);
5359

5460
if (interval <= 0) {
@@ -57,6 +63,16 @@ public Duration getSessionRequestRetryInterval() {
5763
return Duration.ofSeconds(interval);
5864
}
5965

66+
@ManagedAttribute(name = "RequestTimeoutSeconds")
67+
public long getRequestTimeoutSeconds() {
68+
return getSessionRequestTimeout().getSeconds();
69+
}
70+
71+
@ManagedAttribute(name = "RetryIntervalSeconds")
72+
public long getRetryIntervalSeconds() {
73+
return getSessionRequestRetryInterval().getSeconds();
74+
}
75+
6076
public NewSessionQueue getSessionQueue() {
6177
return config
6278
.getClass(SESSIONS_QUEUE_SECTION, "implementation", NewSessionQueue.class,

java/server/src/org/openqa/selenium/grid/sessionqueue/local/BUILD.bazel

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ java_library(
1818
"//java/server/src/org/openqa/selenium/grid/server",
1919
"//java/server/src/org/openqa/selenium/grid/sessionqueue",
2020
"//java/server/src/org/openqa/selenium/grid/sessionqueue/config",
21+
"//java/server/src/org/openqa/selenium/remote/server/jmx",
2122
artifact("com.google.guava:guava"),
2223
],
2324
)

java/server/src/org/openqa/selenium/grid/sessionqueue/local/LocalNewSessionQueue.java

+19
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@
2929
import org.openqa.selenium.grid.sessionqueue.config.NewSessionQueueOptions;
3030
import org.openqa.selenium.internal.Require;
3131
import org.openqa.selenium.remote.http.HttpRequest;
32+
33+
import org.openqa.selenium.remote.server.jmx.JMXHelper;
34+
import org.openqa.selenium.remote.server.jmx.ManagedAttribute;
35+
import org.openqa.selenium.remote.server.jmx.ManagedService;
36+
3237
import org.openqa.selenium.remote.tracing.AttributeKey;
3338
import org.openqa.selenium.remote.tracing.EventAttribute;
3439
import org.openqa.selenium.remote.tracing.EventAttributeValue;
@@ -50,6 +55,8 @@
5055
import java.util.logging.Level;
5156
import java.util.logging.Logger;
5257

58+
@ManagedService(objectName = "org.seleniumhq.grid:type=SessionQueue,name=LocalSessionQueue",
59+
description = "New session queue")
5360
public class LocalNewSessionQueue extends NewSessionQueue {
5461

5562
private static final Logger LOG = Logger.getLogger(LocalNewSessionQueue.class.getName());
@@ -65,6 +72,7 @@ public LocalNewSessionQueue(Tracer tracer, EventBus bus, Duration retryInterval,
6572
super(tracer, retryInterval, requestTimeout);
6673
this.bus = Require.nonNull("Event bus", bus);
6774
Runtime.getRuntime().addShutdownHook(shutdownHook);
75+
new JMXHelper().register(this);
6876
}
6977

7078
public static NewSessionQueue create(Config config) {
@@ -80,6 +88,17 @@ public boolean isReady() {
8088
return bus.isReady();
8189
}
8290

91+
@ManagedAttribute(name = "NewSessionQueueSize")
92+
public int getQueueSize() {
93+
Lock readLock = lock.readLock();
94+
readLock.lock();
95+
try {
96+
return sessionRequests.size();
97+
} finally {
98+
readLock.unlock();
99+
}
100+
}
101+
83102
@Override
84103
public boolean offerLast(HttpRequest request, RequestId requestId) {
85104
Require.nonNull("New Session request", request);

java/server/src/org/openqa/selenium/remote/server/jmx/BUILD.bazel

+2
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,7 @@ java_library(
55
srcs = glob(["*.java"]),
66
visibility = [
77
"//java/server/src/org/openqa/selenium/grid/session:__pkg__",
8+
"//java/server/src/org/openqa/selenium/grid:__subpackages__",
9+
"//java/server/test/org/openqa/selenium/grid:__subpackages__",
810
],
911
)

java/server/test/org/openqa/selenium/grid/router/BUILD.bazel

+2
Original file line numberDiff line numberDiff line change
@@ -70,12 +70,14 @@ java_test_suite(
7070
"//java/server/src/org/openqa/selenium/grid/sessionmap/httpd",
7171
"//java/server/src/org/openqa/selenium/grid/sessionmap/local",
7272
"//java/server/src/org/openqa/selenium/grid/sessionmap/remote",
73+
"//java/server/src/org/openqa/selenium/grid/sessionqueue/config",
7374
"//java/server/src/org/openqa/selenium/grid/sessionqueue",
7475
"//java/server/src/org/openqa/selenium/grid/sessionqueue/httpd",
7576
"//java/server/src/org/openqa/selenium/grid/sessionqueue/local",
7677
"//java/server/src/org/openqa/selenium/grid/sessionqueue/remote",
7778
"//java/server/src/org/openqa/selenium/grid/web",
7879
"//java/server/src/org/openqa/selenium/netty/server",
80+
"//java/server/src/org/openqa/selenium/remote/server/jmx",
7981
"//java/server/test/org/openqa/selenium/grid/testing",
8082
artifact("com.google.guava:guava"),
8183
artifact("io.opentelemetry:opentelemetry-api"),

0 commit comments

Comments
 (0)