Skip to content

Commit cd46fc1

Browse files
committed
Add "homepage" with links to monitoring endpoints
References #235
1 parent e09099c commit cd46fc1

File tree

3 files changed

+69
-11
lines changed

3 files changed

+69
-11
lines changed

src/main/java/com/rabbitmq/stream/perf/DebugEndpointMonitoring.java

+2
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ public void configure(MonitoringContext context) {
4343
PlainTextThreadDumpFormatter formatter = new PlainTextThreadDumpFormatter();
4444
context.addHttpEndpoint(
4545
"threaddump",
46+
"Java thread dump",
4647
exchange -> {
4748
ThreadInfo[] threadInfos =
4849
ManagementFactory.getThreadMXBean().dumpAllThreads(true, true);
@@ -56,6 +57,7 @@ public void configure(MonitoringContext context) {
5657

5758
context.addHttpEndpoint(
5859
"stream-environment",
60+
"Stream client environment internals",
5961
exchange -> {
6062
exchange.getResponseHeaders().set("Content-Type", "application/json");
6163
byte[] content = context.environment().toString().getBytes(StandardCharsets.UTF_8);

src/main/java/com/rabbitmq/stream/perf/MonitoringContext.java

+66-11
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,14 @@
1717
import com.sun.net.httpserver.HttpHandler;
1818
import com.sun.net.httpserver.HttpServer;
1919
import io.micrometer.core.instrument.composite.CompositeMeterRegistry;
20+
import java.io.OutputStream;
21+
import java.net.InetAddress;
2022
import java.net.InetSocketAddress;
21-
import java.util.LinkedHashMap;
22-
import java.util.Map;
23-
import java.util.Map.Entry;
23+
import java.nio.charset.StandardCharsets;
24+
import java.util.ArrayList;
25+
import java.util.Collection;
26+
import java.util.Collections;
27+
import java.util.stream.Collectors;
2428
import org.slf4j.Logger;
2529
import org.slf4j.LoggerFactory;
2630

@@ -32,7 +36,7 @@ class MonitoringContext {
3236
private final CompositeMeterRegistry meterRegistry;
3337
private final Environment environment;
3438

35-
private final Map<String, HttpHandler> handlers = new LinkedHashMap<>();
39+
private final Collection<Endpoint> endpoints = Collections.synchronizedList(new ArrayList<>());
3640

3741
private volatile HttpServer server;
3842

@@ -43,21 +47,60 @@ class MonitoringContext {
4347
this.environment = environment;
4448
}
4549

46-
void addHttpEndpoint(String path, HttpHandler handler) {
47-
this.handlers.put(path, handler);
50+
void addHttpEndpoint(String path, String description, HttpHandler handler) {
51+
this.endpoints.add(new Endpoint(path, description, handler));
4852
}
4953

5054
void start() throws Exception {
51-
if (!handlers.isEmpty()) {
55+
if (!endpoints.isEmpty()) {
5256
server = HttpServer.create(new InetSocketAddress(this.monitoringPort), 0);
5357

54-
for (Entry<String, HttpHandler> entry : handlers.entrySet()) {
55-
String path = entry.getKey().startsWith("/") ? entry.getKey() : "/" + entry.getKey();
56-
HttpHandler handler = entry.getValue();
57-
server.createContext(path, handler);
58+
for (Endpoint handler : endpoints) {
59+
server.createContext(handler.path, handler.handler);
5860
}
5961

62+
String hostname = hostname();
63+
64+
StringBuilder builder =
65+
new StringBuilder(
66+
"{ \"name\" : \"StreamPerfTest Monitoring Endpoints\", \"endpoints\" : [");
67+
String endpointJson =
68+
endpoints.stream()
69+
.map(
70+
endpoint ->
71+
"{\"name\" : \""
72+
+ endpoint.description
73+
+ "\", \"href\" : \""
74+
+ url(hostname, endpoint.path)
75+
+ "\"}")
76+
.collect(Collectors.joining(","));
77+
builder.append(endpointJson);
78+
builder.append("]}");
79+
server.createContext(
80+
"/",
81+
exchange -> {
82+
exchange.getResponseHeaders().set("Content-Type", "application/json");
83+
byte[] content = builder.toString().getBytes(StandardCharsets.UTF_8);
84+
exchange.sendResponseHeaders(200, content.length);
85+
try (OutputStream out = exchange.getResponseBody()) {
86+
out.write(content);
87+
}
88+
});
89+
6090
server.start();
91+
System.out.println("Monitoring endpoints started on http://localhost:" + this.monitoringPort);
92+
}
93+
}
94+
95+
private String url(String hostname, String endpoint) {
96+
return String.format("http://%s:%d%s", hostname, this.monitoringPort, endpoint);
97+
}
98+
99+
private static String hostname() {
100+
try {
101+
return InetAddress.getLocalHost().getHostName();
102+
} catch (Exception e) {
103+
return "localhost";
61104
}
62105
}
63106

@@ -77,4 +120,16 @@ CompositeMeterRegistry meterRegistry() {
77120
Environment environment() {
78121
return this.environment;
79122
}
123+
124+
private static class Endpoint {
125+
126+
private final String path, description;
127+
private final HttpHandler handler;
128+
129+
private Endpoint(String path, String description, HttpHandler handler) {
130+
this.path = path.startsWith("/") ? path : "/" + path;
131+
this.description = description;
132+
this.handler = handler;
133+
}
134+
}
80135
}

src/main/java/com/rabbitmq/stream/perf/PrometheusEndpointMonitoring.java

+1
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ public void configure(MonitoringContext context) {
3636
context.meterRegistry().add(registry);
3737
context.addHttpEndpoint(
3838
"metrics",
39+
"Prometheus metrics",
3940
exchange -> {
4041
exchange.getResponseHeaders().set("Content-Type", "text/plain");
4142
byte[] content = registry.scrape().getBytes(StandardCharsets.UTF_8);

0 commit comments

Comments
 (0)