From 13315ebcad0fa29f47ada0d03310ba153fdcd9dd Mon Sep 17 00:00:00 2001 From: Matthias Berndt Date: Tue, 7 May 2024 17:39:30 +0200 Subject: [PATCH 1/4] Start HTTP server on the provided executor The metrics HTTP server should run on a daemon JVM thread so as to not keep the JVM running even though all relevant threads have already exited. Unfortunately, the OpenJDK builtin HTTP server likes to spawn its own HTTP Dispatcher thread on startup. https://github.com/openjdk/jdk/blob/02c95a6d7eb77ed17ae64d0f585197e87a67cc4a/src/jdk.httpserver/share/classes/sun/net/httpserver/ServerImpl.java#L190 This new thread inherits the daemon flag from the thread that started it, therefore we need to call the start method from the executor service, because those threads are daemon threads. Signed-off-by: Matthias Berndt --- .../metrics/exporter/httpserver/HTTPServer.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HTTPServer.java b/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HTTPServer.java index 81f8871e4..b97d71b5b 100644 --- a/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HTTPServer.java +++ b/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HTTPServer.java @@ -6,7 +6,6 @@ import com.sun.net.httpserver.HttpServer; import com.sun.net.httpserver.HttpsConfigurator; import com.sun.net.httpserver.HttpsServer; -import io.prometheus.metrics.config.ExporterHttpServerProperties; import io.prometheus.metrics.config.PrometheusProperties; import io.prometheus.metrics.model.registry.PrometheusRegistry; @@ -14,6 +13,7 @@ import java.io.IOException; import java.net.InetAddress; import java.net.InetSocketAddress; +import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.RejectedExecutionHandler; import java.util.concurrent.SynchronousQueue; @@ -55,7 +55,13 @@ private HTTPServer(PrometheusProperties config, ExecutorService executorService, registerHandler("/", defaultHandler == null ? new DefaultHandler() : defaultHandler, authenticator); registerHandler("/metrics", new MetricsHandler(config, registry), authenticator); registerHandler("/-/healthy", new HealthyHandler(), authenticator); - this.server.start(); + try { + executorService.submit(() -> this.server.start()).get(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } catch (ExecutionException e) { + throw new RuntimeException(e.getCause()); + } } private void registerHandler(String path, HttpHandler handler, Authenticator authenticator) { From a224960e7d9935456dd9860c6e5541825ce6e7b2 Mon Sep 17 00:00:00 2001 From: Matthias Berndt Date: Tue, 7 May 2024 18:05:23 +0200 Subject: [PATCH 2/4] does this help to make the tests pass? Signed-off-by: Matthias Berndt --- .../metrics/it/exporter/httpserver/HTTPServerSample.java | 1 + 1 file changed, 1 insertion(+) diff --git a/integration-tests/it-exporter/it-exporter-httpserver-sample/src/main/java/io/prometheus/metrics/it/exporter/httpserver/HTTPServerSample.java b/integration-tests/it-exporter/it-exporter-httpserver-sample/src/main/java/io/prometheus/metrics/it/exporter/httpserver/HTTPServerSample.java index 9187ecfcb..ccd0b7724 100644 --- a/integration-tests/it-exporter/it-exporter-httpserver-sample/src/main/java/io/prometheus/metrics/it/exporter/httpserver/HTTPServerSample.java +++ b/integration-tests/it-exporter/it-exporter-httpserver-sample/src/main/java/io/prometheus/metrics/it/exporter/httpserver/HTTPServerSample.java @@ -65,6 +65,7 @@ public static void main(String[] args) throws IOException, InterruptedException .buildAndStart(); System.out.println("HTTPServer listening on port http://localhost:" + server.getPort() + "/metrics"); + Thread.sleep(10_000); } private static int parsePortOrExit(String port) { From b3dd57c8104dc368dd2e166056c55ae761f966c5 Mon Sep 17 00:00:00 2001 From: Matthias Berndt Date: Wed, 8 May 2024 22:04:48 +0200 Subject: [PATCH 3/4] change error handling Signed-off-by: Matthias Berndt --- .../io/prometheus/metrics/exporter/httpserver/HTTPServer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HTTPServer.java b/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HTTPServer.java index b97d71b5b..1b23dfaf0 100644 --- a/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HTTPServer.java +++ b/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HTTPServer.java @@ -60,7 +60,7 @@ private HTTPServer(PrometheusProperties config, ExecutorService executorService, } catch (InterruptedException e) { throw new RuntimeException(e); } catch (ExecutionException e) { - throw new RuntimeException(e.getCause()); + throw new RuntimeException(e); } } From bc479bcea63f42f021b3b406cc06a41819278863 Mon Sep 17 00:00:00 2001 From: Matthias Berndt Date: Wed, 8 May 2024 23:18:27 +0200 Subject: [PATCH 4/4] add comment Signed-off-by: Matthias Berndt --- .../io/prometheus/metrics/exporter/httpserver/HTTPServer.java | 1 + 1 file changed, 1 insertion(+) diff --git a/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HTTPServer.java b/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HTTPServer.java index 1b23dfaf0..eb5b5f39d 100644 --- a/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HTTPServer.java +++ b/prometheus-metrics-exporter-httpserver/src/main/java/io/prometheus/metrics/exporter/httpserver/HTTPServer.java @@ -57,6 +57,7 @@ private HTTPServer(PrometheusProperties config, ExecutorService executorService, registerHandler("/-/healthy", new HealthyHandler(), authenticator); try { executorService.submit(() -> this.server.start()).get(); + // calling .get() on the Future here to avoid silently discarding errors } catch (InterruptedException e) { throw new RuntimeException(e); } catch (ExecutionException e) {