- * Prometheus counters are faster than counters of other libraries. For example, incrementing a single counter
- * without labels is more than 2 times faster (34752 ops / second) than doing the same with an OpenTelemetry
- * counter (16634 ops / sec).
+ *
+ * Prometheus counters are faster than counters of other libraries. For example, incrementing a
+ * single counter without labels is more than 2 times faster (34752 ops / second) than doing the
+ * same with an OpenTelemetry counter (16634 ops / sec).
*/
public class CounterBenchmark {
- @State(Scope.Benchmark)
- public static class PrometheusCounter {
-
- final Counter noLabels;
- final CounterDataPoint dataPoint;
-
- public PrometheusCounter() {
- noLabels = Counter.builder()
- .name("test")
- .help("help")
- .build();
-
- Counter labels = Counter.builder()
- .name("test")
- .help("help")
- .labelNames("path", "status")
- .build();
- this.dataPoint = labels.labelValues("/", "200");
- }
- }
+ @State(Scope.Benchmark)
+ public static class PrometheusCounter {
- @State(Scope.Benchmark)
- public static class SimpleclientCounter {
+ final Counter noLabels;
+ final CounterDataPoint dataPoint;
- final io.prometheus.client.Counter noLabels;
- final io.prometheus.client.Counter.Child dataPoint;
+ public PrometheusCounter() {
+ noLabels = Counter.builder().name("test").help("help").build();
- public SimpleclientCounter() {
- noLabels = io.prometheus.client.Counter.build()
- .name("name")
- .help("help")
- .create();
+ Counter labels =
+ Counter.builder().name("test").help("help").labelNames("path", "status").build();
+ this.dataPoint = labels.labelValues("/", "200");
+ }
+ }
- io.prometheus.client.Counter counter = io.prometheus.client.Counter.build()
- .name("name")
- .help("help")
- .labelNames("path", "status")
- .create();
+ @State(Scope.Benchmark)
+ public static class SimpleclientCounter {
- this.dataPoint = counter.labels("/", "200");
- }
- }
+ final io.prometheus.client.Counter noLabels;
+ final io.prometheus.client.Counter.Child dataPoint;
- @State(Scope.Benchmark)
- public static class CodahaleCounterNoLabels {
- final com.codahale.metrics.Counter counter = new com.codahale.metrics.MetricRegistry().counter("test");
- }
+ public SimpleclientCounter() {
+ noLabels = io.prometheus.client.Counter.build().name("name").help("help").create();
- @State(Scope.Benchmark)
- public static class OpenTelemetryCounter {
-
- final LongCounter longCounter;
- final DoubleCounter doubleCounter;
- final Attributes attributes;
-
- public OpenTelemetryCounter() {
-
- SdkMeterProvider sdkMeterProvider = SdkMeterProvider.builder()
- .registerMetricReader(InMemoryMetricReader.create())
- .setResource(Resource.getDefault())
- .build();
- OpenTelemetry openTelemetry = OpenTelemetrySdk.builder()
- .setMeterProvider(sdkMeterProvider)
- .build();
- Meter meter = openTelemetry
- .meterBuilder("instrumentation-library-name")
- .setInstrumentationVersion("1.0.0")
- .build();
- this.longCounter = meter
- .counterBuilder("test1")
- .setDescription("test")
- .build();
- this.doubleCounter = meter
- .counterBuilder("test2")
- .ofDoubles()
- .setDescription("test")
- .build();
- this.attributes = Attributes.of(
- AttributeKey.stringKey("path"), "/",
- AttributeKey.stringKey("status"), "200");
- }
- }
+ io.prometheus.client.Counter counter =
+ io.prometheus.client.Counter.build()
+ .name("name")
+ .help("help")
+ .labelNames("path", "status")
+ .create();
- @Benchmark
- @Threads(4)
- public CounterDataPoint prometheusAdd(RandomNumbers randomNumbers, PrometheusCounter counter) {
- for (int i=0; i
* Benchmark Mode Cnt Score Error Units
* i.p.metrics.benchmarks.HistogramBenchmark.openTelemetryClassic thrpt 25 1908.715 ± 114.050 ops/s
@@ -27,164 +27,159 @@
* i.p.metrics.benchmarks.HistogramBenchmark.prometheusNative thrpt 25 3372.789 ± 339.328 ops/s
* i.p.metrics.benchmarks.HistogramBenchmark.simpleclient thrpt 25 6488.252 ± 96.737 ops/s
*
+ *
* The simpleclient (i.e. client_java version 0.16.0 and older) histograms perform about the same as
* the classic histogram of the current 1.0.0 version.
- *
- * Compared to OpenTelemetry histograms the Prometheus Java client histograms perform more than 3 times better
- * (OpenTelemetry has 1908 ops / sec for classic histograms, while Prometheus has 6451 ops / sec).
+ *
+ *
Compared to OpenTelemetry histograms the Prometheus Java client histograms perform more than 3
+ * times better (OpenTelemetry has 1908 ops / sec for classic histograms, while Prometheus has 6451
+ * ops / sec).
*/
-
public class HistogramBenchmark {
- @State(Scope.Benchmark)
- public static class PrometheusClassicHistogram {
+ @State(Scope.Benchmark)
+ public static class PrometheusClassicHistogram {
- final Histogram noLabels;
+ final Histogram noLabels;
- public PrometheusClassicHistogram() {
- noLabels = Histogram.builder()
- .name("test")
- .help("help")
- .classicOnly()
- .build();
- }
+ public PrometheusClassicHistogram() {
+ noLabels = Histogram.builder().name("test").help("help").classicOnly().build();
}
-
- @State(Scope.Benchmark)
- public static class PrometheusNativeHistogram {
-
- final Histogram noLabels;
-
- public PrometheusNativeHistogram() {
- noLabels = Histogram.builder()
- .name("test")
- .help("help")
- .nativeOnly()
- .nativeInitialSchema(5)
- .nativeMaxNumberOfBuckets(0)
- .build();
- }
+ }
+
+ @State(Scope.Benchmark)
+ public static class PrometheusNativeHistogram {
+
+ final Histogram noLabels;
+
+ public PrometheusNativeHistogram() {
+ noLabels =
+ Histogram.builder()
+ .name("test")
+ .help("help")
+ .nativeOnly()
+ .nativeInitialSchema(5)
+ .nativeMaxNumberOfBuckets(0)
+ .build();
}
+ }
- @State(Scope.Benchmark)
- public static class SimpleclientHistogram {
+ @State(Scope.Benchmark)
+ public static class SimpleclientHistogram {
- final io.prometheus.client.Histogram noLabels;
+ final io.prometheus.client.Histogram noLabels;
- public SimpleclientHistogram() {
- noLabels = io.prometheus.client.Histogram.build()
- .name("name")
- .help("help")
- .create();
- }
+ public SimpleclientHistogram() {
+ noLabels = io.prometheus.client.Histogram.build().name("name").help("help").create();
}
-
- @State(Scope.Benchmark)
- public static class OpenTelemetryClassicHistogram {
-
- final io.opentelemetry.api.metrics.DoubleHistogram histogram;
-
- public OpenTelemetryClassicHistogram() {
-
- SdkMeterProvider sdkMeterProvider = SdkMeterProvider.builder()
- .registerMetricReader(InMemoryMetricReader.create())
- .setResource(Resource.getDefault())
- .registerView(InstrumentSelector.builder()
- .setName("test")
- .build(),
- View.builder()
- .setAggregation(Aggregation.explicitBucketHistogram(Arrays.asList(.005, .01, .025, .05, .1, .25, .5, 1.0, 2.5, 5.0, 10.0)))
- .build()
- )
- .build();
- OpenTelemetry openTelemetry = OpenTelemetrySdk.builder()
- .setMeterProvider(sdkMeterProvider)
- .build();
- Meter meter = openTelemetry
- .meterBuilder("instrumentation-library-name")
- .setInstrumentationVersion("1.0.0")
- .build();
- this.histogram = meter
- .histogramBuilder("test")
- .setDescription("test")
- .build();
- }
+ }
+
+ @State(Scope.Benchmark)
+ public static class OpenTelemetryClassicHistogram {
+
+ final io.opentelemetry.api.metrics.DoubleHistogram histogram;
+
+ public OpenTelemetryClassicHistogram() {
+
+ SdkMeterProvider sdkMeterProvider =
+ SdkMeterProvider.builder()
+ .registerMetricReader(InMemoryMetricReader.create())
+ .setResource(Resource.getDefault())
+ .registerView(
+ InstrumentSelector.builder().setName("test").build(),
+ View.builder()
+ .setAggregation(
+ Aggregation.explicitBucketHistogram(
+ Arrays.asList(
+ .005, .01, .025, .05, .1, .25, .5, 1.0, 2.5, 5.0, 10.0)))
+ .build())
+ .build();
+ OpenTelemetry openTelemetry =
+ OpenTelemetrySdk.builder().setMeterProvider(sdkMeterProvider).build();
+ Meter meter =
+ openTelemetry
+ .meterBuilder("instrumentation-library-name")
+ .setInstrumentationVersion("1.0.0")
+ .build();
+ this.histogram = meter.histogramBuilder("test").setDescription("test").build();
}
-
- @State(Scope.Benchmark)
- public static class OpenTelemetryExponentialHistogram {
-
- final io.opentelemetry.api.metrics.DoubleHistogram histogram;
-
- public OpenTelemetryExponentialHistogram() {
-
- SdkMeterProvider sdkMeterProvider = SdkMeterProvider.builder()
- .registerMetricReader(InMemoryMetricReader.create())
- .setResource(Resource.getDefault())
- .registerView(InstrumentSelector.builder()
- .setName("test")
- .build(),
- View.builder()
- .setAggregation(Aggregation.base2ExponentialBucketHistogram(10_000, 5))
- .build()
- )
- .build();
- OpenTelemetry openTelemetry = OpenTelemetrySdk.builder()
- .setMeterProvider(sdkMeterProvider)
- .build();
- Meter meter = openTelemetry
- .meterBuilder("instrumentation-library-name")
- .setInstrumentationVersion("1.0.0")
- .build();
- this.histogram = meter
- .histogramBuilder("test")
- .setDescription("test")
- .build();
- }
+ }
+
+ @State(Scope.Benchmark)
+ public static class OpenTelemetryExponentialHistogram {
+
+ final io.opentelemetry.api.metrics.DoubleHistogram histogram;
+
+ public OpenTelemetryExponentialHistogram() {
+
+ SdkMeterProvider sdkMeterProvider =
+ SdkMeterProvider.builder()
+ .registerMetricReader(InMemoryMetricReader.create())
+ .setResource(Resource.getDefault())
+ .registerView(
+ InstrumentSelector.builder().setName("test").build(),
+ View.builder()
+ .setAggregation(Aggregation.base2ExponentialBucketHistogram(10_000, 5))
+ .build())
+ .build();
+ OpenTelemetry openTelemetry =
+ OpenTelemetrySdk.builder().setMeterProvider(sdkMeterProvider).build();
+ Meter meter =
+ openTelemetry
+ .meterBuilder("instrumentation-library-name")
+ .setInstrumentationVersion("1.0.0")
+ .build();
+ this.histogram = meter.histogramBuilder("test").setDescription("test").build();
}
-
- @Benchmark
- @Threads(4)
- public Histogram prometheusClassic(RandomNumbers randomNumbers, PrometheusClassicHistogram histogram) {
- for (int i = 0; i < randomNumbers.randomNumbers.length; i++) {
- histogram.noLabels.observe(randomNumbers.randomNumbers[i]);
- }
- return histogram.noLabels;
+ }
+
+ @Benchmark
+ @Threads(4)
+ public Histogram prometheusClassic(
+ RandomNumbers randomNumbers, PrometheusClassicHistogram histogram) {
+ for (int i = 0; i < randomNumbers.randomNumbers.length; i++) {
+ histogram.noLabels.observe(randomNumbers.randomNumbers[i]);
}
-
- @Benchmark
- @Threads(4)
- public Histogram prometheusNative(RandomNumbers randomNumbers, PrometheusNativeHistogram histogram) {
- for (int i = 0; i < randomNumbers.randomNumbers.length; i++) {
- histogram.noLabels.observe(randomNumbers.randomNumbers[i]);
- }
- return histogram.noLabels;
+ return histogram.noLabels;
+ }
+
+ @Benchmark
+ @Threads(4)
+ public Histogram prometheusNative(
+ RandomNumbers randomNumbers, PrometheusNativeHistogram histogram) {
+ for (int i = 0; i < randomNumbers.randomNumbers.length; i++) {
+ histogram.noLabels.observe(randomNumbers.randomNumbers[i]);
}
-
- @Benchmark
- @Threads(4)
- public io.prometheus.client.Histogram simpleclient(RandomNumbers randomNumbers, SimpleclientHistogram histogram) {
- for (int i = 0; i < randomNumbers.randomNumbers.length; i++) {
- histogram.noLabels.observe(randomNumbers.randomNumbers[i]);
- }
- return histogram.noLabels;
+ return histogram.noLabels;
+ }
+
+ @Benchmark
+ @Threads(4)
+ public io.prometheus.client.Histogram simpleclient(
+ RandomNumbers randomNumbers, SimpleclientHistogram histogram) {
+ for (int i = 0; i < randomNumbers.randomNumbers.length; i++) {
+ histogram.noLabels.observe(randomNumbers.randomNumbers[i]);
}
-
- @Benchmark
- @Threads(4)
- public io.opentelemetry.api.metrics.DoubleHistogram openTelemetryClassic(RandomNumbers randomNumbers, OpenTelemetryClassicHistogram histogram) {
- for (int i = 0; i < randomNumbers.randomNumbers.length; i++) {
- histogram.histogram.record(randomNumbers.randomNumbers[i]);
- }
- return histogram.histogram;
+ return histogram.noLabels;
+ }
+
+ @Benchmark
+ @Threads(4)
+ public io.opentelemetry.api.metrics.DoubleHistogram openTelemetryClassic(
+ RandomNumbers randomNumbers, OpenTelemetryClassicHistogram histogram) {
+ for (int i = 0; i < randomNumbers.randomNumbers.length; i++) {
+ histogram.histogram.record(randomNumbers.randomNumbers[i]);
}
-
- @Benchmark
- @Threads(4)
- public io.opentelemetry.api.metrics.DoubleHistogram openTelemetryExponential(RandomNumbers randomNumbers, OpenTelemetryExponentialHistogram histogram) {
- for (int i = 0; i < randomNumbers.randomNumbers.length; i++) {
- histogram.histogram.record(randomNumbers.randomNumbers[i]);
- }
- return histogram.histogram;
+ return histogram.histogram;
+ }
+
+ @Benchmark
+ @Threads(4)
+ public io.opentelemetry.api.metrics.DoubleHistogram openTelemetryExponential(
+ RandomNumbers randomNumbers, OpenTelemetryExponentialHistogram histogram) {
+ for (int i = 0; i < randomNumbers.randomNumbers.length; i++) {
+ histogram.histogram.record(randomNumbers.randomNumbers[i]);
}
+ return histogram.histogram;
+ }
}
diff --git a/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/RandomNumbers.java b/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/RandomNumbers.java
index d7002d909..6778c4ea1 100644
--- a/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/RandomNumbers.java
+++ b/benchmarks/src/main/java/io/prometheus/metrics/benchmarks/RandomNumbers.java
@@ -1,19 +1,18 @@
package io.prometheus.metrics.benchmarks;
+import java.util.Random;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.State;
-import java.util.Random;
-
@State(Scope.Thread)
public class RandomNumbers {
- final double[] randomNumbers = new double[10*1024];
+ final double[] randomNumbers = new double[10 * 1024];
- public RandomNumbers() {
- Random rand = new Random(0);
- for (int i = 0; i < randomNumbers.length; i++) {
- randomNumbers[i] = Math.abs(rand.nextGaussian());
- }
+ public RandomNumbers() {
+ Random rand = new Random(0);
+ for (int i = 0; i < randomNumbers.length; i++) {
+ randomNumbers[i] = Math.abs(rand.nextGaussian());
}
+ }
}
diff --git a/examples/example-exemplars-tail-sampling/example-greeting-service/src/main/java/io/prometheus/metrics/examples/otel_exemplars/greeting/GreetingServlet.java b/examples/example-exemplars-tail-sampling/example-greeting-service/src/main/java/io/prometheus/metrics/examples/otel_exemplars/greeting/GreetingServlet.java
index 7a0870bf3..af1652f76 100644
--- a/examples/example-exemplars-tail-sampling/example-greeting-service/src/main/java/io/prometheus/metrics/examples/otel_exemplars/greeting/GreetingServlet.java
+++ b/examples/example-exemplars-tail-sampling/example-greeting-service/src/main/java/io/prometheus/metrics/examples/otel_exemplars/greeting/GreetingServlet.java
@@ -1,47 +1,45 @@
package io.prometheus.metrics.examples.otel_exemplars.greeting;
+import static io.prometheus.metrics.model.snapshots.Unit.nanosToSeconds;
+
import io.prometheus.metrics.core.metrics.Histogram;
import io.prometheus.metrics.model.snapshots.Unit;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
-
import java.io.IOException;
import java.util.Random;
-import static io.prometheus.metrics.model.snapshots.Unit.nanosToSeconds;
-
-/**
- * Hello World REST servlet, with an example counter and an example histogram.
- */
+/** Hello World REST servlet, with an example counter and an example histogram. */
public class GreetingServlet extends HttpServlet {
- private final Random random = new Random(0);
+ private final Random random = new Random(0);
- private final Histogram histogram;
+ private final Histogram histogram;
- public GreetingServlet() {
- histogram = Histogram.builder()
+ public GreetingServlet() {
+ histogram =
+ Histogram.builder()
.name("request_duration_seconds")
.help("request duration in seconds")
.unit(Unit.SECONDS)
.labelNames("http_status")
.register();
- histogram.initLabelValues("200");
- }
-
- @Override
- protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
- long start = System.nanoTime();
- try {
- Thread.sleep((long) (Math.abs((random.nextGaussian() + 1.0) * 100.0)));
- resp.setStatus(200);
- resp.setContentType("text/plain");
- resp.getWriter().println("Hello, World!");
- } catch (InterruptedException e) {
- throw new RuntimeException(e);
- } finally {
- histogram.labelValues("200").observe(nanosToSeconds(System.nanoTime() - start));
- }
+ histogram.initLabelValues("200");
+ }
+
+ @Override
+ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
+ long start = System.nanoTime();
+ try {
+ Thread.sleep((long) (Math.abs((random.nextGaussian() + 1.0) * 100.0)));
+ resp.setStatus(200);
+ resp.setContentType("text/plain");
+ resp.getWriter().println("Hello, World!");
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ } finally {
+ histogram.labelValues("200").observe(nanosToSeconds(System.nanoTime() - start));
}
+ }
}
diff --git a/examples/example-exemplars-tail-sampling/example-greeting-service/src/main/java/io/prometheus/metrics/examples/otel_exemplars/greeting/Main.java b/examples/example-exemplars-tail-sampling/example-greeting-service/src/main/java/io/prometheus/metrics/examples/otel_exemplars/greeting/Main.java
index 731e05cf9..c0cf09830 100644
--- a/examples/example-exemplars-tail-sampling/example-greeting-service/src/main/java/io/prometheus/metrics/examples/otel_exemplars/greeting/Main.java
+++ b/examples/example-exemplars-tail-sampling/example-greeting-service/src/main/java/io/prometheus/metrics/examples/otel_exemplars/greeting/Main.java
@@ -2,34 +2,31 @@
import io.prometheus.metrics.exporter.servlet.jakarta.PrometheusMetricsServlet;
import io.prometheus.metrics.instrumentation.jvm.JvmMetrics;
+import java.io.File;
import org.apache.catalina.Context;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.startup.Tomcat;
-import java.io.File;
-
-/**
- * Simple example using embedded Tomcat and the {@link PrometheusMetricsServlet}.
- */
+/** Simple example using embedded Tomcat and the {@link PrometheusMetricsServlet}. */
public class Main {
- public static void main(String[] args) throws LifecycleException {
+ public static void main(String[] args) throws LifecycleException {
- JvmMetrics.builder().register();
+ JvmMetrics.builder().register();
- Tomcat tomcat = new Tomcat();
- tomcat.setPort(8081);
+ Tomcat tomcat = new Tomcat();
+ tomcat.setPort(8081);
- Context ctx = tomcat.addContext("", new File(".").getAbsolutePath());
+ Context ctx = tomcat.addContext("", new File(".").getAbsolutePath());
- Tomcat.addServlet(ctx, "hello", new GreetingServlet());
- ctx.addServletMappingDecoded("/*", "hello");
+ Tomcat.addServlet(ctx, "hello", new GreetingServlet());
+ ctx.addServletMappingDecoded("/*", "hello");
- Tomcat.addServlet(ctx, "metrics", new PrometheusMetricsServlet());
- ctx.addServletMappingDecoded("/metrics", "metrics");
+ Tomcat.addServlet(ctx, "metrics", new PrometheusMetricsServlet());
+ ctx.addServletMappingDecoded("/metrics", "metrics");
- tomcat.getConnector();
- tomcat.start();
- tomcat.getServer().await();
- }
+ tomcat.getConnector();
+ tomcat.start();
+ tomcat.getServer().await();
+ }
}
diff --git a/examples/example-exemplars-tail-sampling/example-hello-world-app/src/main/java/io/prometheus/metrics/examples/otel_exemplars/app/HelloWorldServlet.java b/examples/example-exemplars-tail-sampling/example-hello-world-app/src/main/java/io/prometheus/metrics/examples/otel_exemplars/app/HelloWorldServlet.java
index 11c048d68..fbe293d50 100644
--- a/examples/example-exemplars-tail-sampling/example-hello-world-app/src/main/java/io/prometheus/metrics/examples/otel_exemplars/app/HelloWorldServlet.java
+++ b/examples/example-exemplars-tail-sampling/example-hello-world-app/src/main/java/io/prometheus/metrics/examples/otel_exemplars/app/HelloWorldServlet.java
@@ -1,12 +1,14 @@
package io.prometheus.metrics.examples.otel_exemplars.app;
+import static io.prometheus.metrics.model.snapshots.Unit.nanosToSeconds;
+import static java.net.http.HttpResponse.BodyHandlers.ofString;
+
import io.prometheus.metrics.core.metrics.Histogram;
import io.prometheus.metrics.model.snapshots.Unit;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
-
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
@@ -15,51 +17,46 @@
import java.net.http.HttpResponse;
import java.util.Random;
-import static io.prometheus.metrics.model.snapshots.Unit.nanosToSeconds;
-import static java.net.http.HttpResponse.BodyHandlers.ofString;
-
-/**
- * Hello World REST servlet, with an example counter and an example histogram.
- */
+/** Hello World REST servlet, with an example counter and an example histogram. */
public class HelloWorldServlet extends HttpServlet {
- private final Random random = new Random(0);
-
- private final Histogram histogram;
-
- public HelloWorldServlet() {
- histogram = Histogram.builder()
- .name("request_duration_seconds")
- .help("request duration in seconds")
- .unit(Unit.SECONDS)
- .labelNames("http_status")
- .register();
- histogram.initLabelValues("200");
- }
-
- @Override
- protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException {
- long start = System.nanoTime();
- try {
- Thread.sleep((long) (Math.abs((random.nextGaussian() + 1.0) * 100.0)));
- String greeting = executeGreetingServiceRequest();
- resp.setStatus(200);
- resp.setContentType("text/plain");
- resp.getWriter().print(greeting);
- } catch (Exception e) {
- throw new ServletException(e);
- } finally {
- histogram.labelValues("200").observe(nanosToSeconds(System.nanoTime() - start));
- }
- }
-
- private String executeGreetingServiceRequest() throws URISyntaxException, IOException, InterruptedException {
- HttpRequest request = HttpRequest.newBuilder()
- .GET()
- .uri(new URI("http://localhost:8081/"))
- .build();
- HttpClient httpClient = HttpClient.newHttpClient();
- HttpResponse response = httpClient.send(request, ofString());
- return response.body();
+ private final Random random = new Random(0);
+
+ private final Histogram histogram;
+
+ public HelloWorldServlet() {
+ histogram =
+ Histogram.builder()
+ .name("request_duration_seconds")
+ .help("request duration in seconds")
+ .unit(Unit.SECONDS)
+ .labelNames("http_status")
+ .register();
+ histogram.initLabelValues("200");
+ }
+
+ @Override
+ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException {
+ long start = System.nanoTime();
+ try {
+ Thread.sleep((long) (Math.abs((random.nextGaussian() + 1.0) * 100.0)));
+ String greeting = executeGreetingServiceRequest();
+ resp.setStatus(200);
+ resp.setContentType("text/plain");
+ resp.getWriter().print(greeting);
+ } catch (Exception e) {
+ throw new ServletException(e);
+ } finally {
+ histogram.labelValues("200").observe(nanosToSeconds(System.nanoTime() - start));
}
+ }
+
+ private String executeGreetingServiceRequest()
+ throws URISyntaxException, IOException, InterruptedException {
+ HttpRequest request =
+ HttpRequest.newBuilder().GET().uri(new URI("http://localhost:8081/")).build();
+ HttpClient httpClient = HttpClient.newHttpClient();
+ HttpResponse response = httpClient.send(request, ofString());
+ return response.body();
+ }
}
diff --git a/examples/example-exemplars-tail-sampling/example-hello-world-app/src/main/java/io/prometheus/metrics/examples/otel_exemplars/app/Main.java b/examples/example-exemplars-tail-sampling/example-hello-world-app/src/main/java/io/prometheus/metrics/examples/otel_exemplars/app/Main.java
index 5fb5114bb..dc58256cb 100644
--- a/examples/example-exemplars-tail-sampling/example-hello-world-app/src/main/java/io/prometheus/metrics/examples/otel_exemplars/app/Main.java
+++ b/examples/example-exemplars-tail-sampling/example-hello-world-app/src/main/java/io/prometheus/metrics/examples/otel_exemplars/app/Main.java
@@ -2,34 +2,31 @@
import io.prometheus.metrics.exporter.servlet.jakarta.PrometheusMetricsServlet;
import io.prometheus.metrics.instrumentation.jvm.JvmMetrics;
+import java.io.File;
import org.apache.catalina.Context;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.startup.Tomcat;
-import java.io.File;
-
-/**
- * Simple example using embedded Tomcat and the {@link PrometheusMetricsServlet}.
- */
+/** Simple example using embedded Tomcat and the {@link PrometheusMetricsServlet}. */
public class Main {
- public static void main(String[] args) throws LifecycleException {
+ public static void main(String[] args) throws LifecycleException {
- JvmMetrics.builder().register();
+ JvmMetrics.builder().register();
- Tomcat tomcat = new Tomcat();
- tomcat.setPort(8080);
+ Tomcat tomcat = new Tomcat();
+ tomcat.setPort(8080);
- Context ctx = tomcat.addContext("", new File(".").getAbsolutePath());
+ Context ctx = tomcat.addContext("", new File(".").getAbsolutePath());
- Tomcat.addServlet(ctx, "hello", new HelloWorldServlet());
- ctx.addServletMappingDecoded("/*", "hello");
+ Tomcat.addServlet(ctx, "hello", new HelloWorldServlet());
+ ctx.addServletMappingDecoded("/*", "hello");
- Tomcat.addServlet(ctx, "metrics", new PrometheusMetricsServlet());
- ctx.addServletMappingDecoded("/metrics", "metrics");
+ Tomcat.addServlet(ctx, "metrics", new PrometheusMetricsServlet());
+ ctx.addServletMappingDecoded("/metrics", "metrics");
- tomcat.getConnector();
- tomcat.start();
- tomcat.getServer().await();
- }
+ tomcat.getConnector();
+ tomcat.start();
+ tomcat.getServer().await();
+ }
}
diff --git a/examples/example-exporter-httpserver/src/main/java/io/prometheus/metrics/examples/httpserver/Main.java b/examples/example-exporter-httpserver/src/main/java/io/prometheus/metrics/examples/httpserver/Main.java
index f01874ef8..3b0976778 100644
--- a/examples/example-exporter-httpserver/src/main/java/io/prometheus/metrics/examples/httpserver/Main.java
+++ b/examples/example-exporter-httpserver/src/main/java/io/prometheus/metrics/examples/httpserver/Main.java
@@ -4,39 +4,36 @@
import io.prometheus.metrics.exporter.httpserver.HTTPServer;
import io.prometheus.metrics.instrumentation.jvm.JvmMetrics;
import io.prometheus.metrics.model.snapshots.Unit;
-
import java.io.IOException;
-/**
- * Simple example of an application exposing metrics via Prometheus' built-in HTTPServer.
- */
+/** Simple example of an application exposing metrics via Prometheus' built-in HTTPServer. */
public class Main {
- public static void main(String[] args) throws IOException, InterruptedException {
+ public static void main(String[] args) throws IOException, InterruptedException {
- JvmMetrics.builder().register();
+ JvmMetrics.builder().register();
- // Note: uptime_seconds_total is not a great example:
- // The built-in JvmMetrics have an out-of-the-box metric named process_start_time_seconds
- // with the start timestamp in seconds, so if you want to know the uptime you can simply
- // run the Prometheus query
- // time() - process_start_time_seconds
- // rather than creating a custom uptime metric.
- Counter counter = Counter.builder()
- .name("uptime_seconds_total")
- .help("total number of seconds since this application was started")
- .unit(Unit.SECONDS)
- .register();
+ // Note: uptime_seconds_total is not a great example:
+ // The built-in JvmMetrics have an out-of-the-box metric named process_start_time_seconds
+ // with the start timestamp in seconds, so if you want to know the uptime you can simply
+ // run the Prometheus query
+ // time() - process_start_time_seconds
+ // rather than creating a custom uptime metric.
+ Counter counter =
+ Counter.builder()
+ .name("uptime_seconds_total")
+ .help("total number of seconds since this application was started")
+ .unit(Unit.SECONDS)
+ .register();
- HTTPServer server = HTTPServer.builder()
- .port(9400)
- .buildAndStart();
+ HTTPServer server = HTTPServer.builder().port(9400).buildAndStart();
- System.out.println("HTTPServer listening on port http://localhost:" + server.getPort() + "/metrics");
+ System.out.println(
+ "HTTPServer listening on port http://localhost:" + server.getPort() + "/metrics");
- while (true) {
- Thread.sleep(1000);
- counter.inc();
- }
+ while (true) {
+ Thread.sleep(1000);
+ counter.inc();
}
+ }
}
diff --git a/examples/example-exporter-multi-target/src/main/java/io/prometheus/metrics/examples/multitarget/Main.java b/examples/example-exporter-multi-target/src/main/java/io/prometheus/metrics/examples/multitarget/Main.java
index da36346b9..0fac9a0d3 100644
--- a/examples/example-exporter-multi-target/src/main/java/io/prometheus/metrics/examples/multitarget/Main.java
+++ b/examples/example-exporter-multi-target/src/main/java/io/prometheus/metrics/examples/multitarget/Main.java
@@ -1,23 +1,19 @@
package io.prometheus.metrics.examples.multitarget;
-import java.io.IOException;
-
import io.prometheus.metrics.exporter.httpserver.HTTPServer;
import io.prometheus.metrics.model.registry.PrometheusRegistry;
+import java.io.IOException;
-/**
- * Simple example of an application exposing metrics via Prometheus' built-in HTTPServer.
- */
+/** Simple example of an application exposing metrics via Prometheus' built-in HTTPServer. */
public class Main {
- public static void main(String[] args) throws IOException, InterruptedException {
+ public static void main(String[] args) throws IOException, InterruptedException {
- SampleMultiCollector xmc = new SampleMultiCollector();
- PrometheusRegistry.defaultRegistry.register(xmc);
- HTTPServer server = HTTPServer.builder()
- .port(9401)
- .buildAndStart();
+ SampleMultiCollector xmc = new SampleMultiCollector();
+ PrometheusRegistry.defaultRegistry.register(xmc);
+ HTTPServer server = HTTPServer.builder().port(9401).buildAndStart();
- System.out.println("HTTPServer listening on port http://localhost:" + server.getPort() + "/metrics");
- }
+ System.out.println(
+ "HTTPServer listening on port http://localhost:" + server.getPort() + "/metrics");
+ }
}
diff --git a/examples/example-exporter-multi-target/src/main/java/io/prometheus/metrics/examples/multitarget/SampleMultiCollector.java b/examples/example-exporter-multi-target/src/main/java/io/prometheus/metrics/examples/multitarget/SampleMultiCollector.java
index 819bb3028..7a05f0a8b 100644
--- a/examples/example-exporter-multi-target/src/main/java/io/prometheus/metrics/examples/multitarget/SampleMultiCollector.java
+++ b/examples/example-exporter-multi-target/src/main/java/io/prometheus/metrics/examples/multitarget/SampleMultiCollector.java
@@ -1,9 +1,5 @@
package io.prometheus.metrics.examples.multitarget;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-
import io.prometheus.metrics.model.registry.MultiCollector;
import io.prometheus.metrics.model.registry.PrometheusScrapeRequest;
import io.prometheus.metrics.model.snapshots.CounterSnapshot;
@@ -13,76 +9,79 @@
import io.prometheus.metrics.model.snapshots.MetricSnapshot;
import io.prometheus.metrics.model.snapshots.MetricSnapshots;
import io.prometheus.metrics.model.snapshots.PrometheusNaming;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
public class SampleMultiCollector implements MultiCollector {
- public SampleMultiCollector() {
- super();
- }
-
- @Override
- public MetricSnapshots collect() {
- return new MetricSnapshots();
- }
+ public SampleMultiCollector() {
+ super();
+ }
- @Override
- public MetricSnapshots collect(PrometheusScrapeRequest scrapeRequest) {
- return collectMetricSnapshots(scrapeRequest);
- }
+ @Override
+ public MetricSnapshots collect() {
+ return new MetricSnapshots();
+ }
- protected MetricSnapshots collectMetricSnapshots(PrometheusScrapeRequest scrapeRequest) {
+ @Override
+ public MetricSnapshots collect(PrometheusScrapeRequest scrapeRequest) {
+ return collectMetricSnapshots(scrapeRequest);
+ }
- GaugeSnapshot.Builder gaugeBuilder = GaugeSnapshot.builder();
- gaugeBuilder.name("x_load").help("process load");
+ protected MetricSnapshots collectMetricSnapshots(PrometheusScrapeRequest scrapeRequest) {
- CounterSnapshot.Builder counterBuilder = CounterSnapshot.builder();
- counterBuilder.name(PrometheusNaming.sanitizeMetricName("x_calls_total")).help("invocations");
+ GaugeSnapshot.Builder gaugeBuilder = GaugeSnapshot.builder();
+ gaugeBuilder.name("x_load").help("process load");
- String[] targetNames = scrapeRequest.getParameterValues("target");
- String targetName;
- String[] procs = scrapeRequest.getParameterValues("proc");
- if (targetNames == null || targetNames.length == 0) {
- targetName = "defaultTarget";
- procs = null; //ignore procs param
- } else {
- targetName = targetNames[0];
- }
- Builder counterDataPointBuilder = CounterSnapshot.CounterDataPointSnapshot.builder();
- io.prometheus.metrics.model.snapshots.GaugeSnapshot.GaugeDataPointSnapshot.Builder gaugeDataPointBuilder = GaugeSnapshot.GaugeDataPointSnapshot.builder();
- Labels lbls = Labels.of("target", targetName);
+ CounterSnapshot.Builder counterBuilder = CounterSnapshot.builder();
+ counterBuilder.name(PrometheusNaming.sanitizeMetricName("x_calls_total")).help("invocations");
- if (procs == null || procs.length == 0) {
- counterDataPointBuilder.labels(lbls.merge(Labels.of("proc", "defaultProc")));
- gaugeDataPointBuilder.labels(lbls.merge(Labels.of("proc", "defaultProc")));
- counterDataPointBuilder.value(70);
- gaugeDataPointBuilder.value(Math.random());
+ String[] targetNames = scrapeRequest.getParameterValues("target");
+ String targetName;
+ String[] procs = scrapeRequest.getParameterValues("proc");
+ if (targetNames == null || targetNames.length == 0) {
+ targetName = "defaultTarget";
+ procs = null; // ignore procs param
+ } else {
+ targetName = targetNames[0];
+ }
+ Builder counterDataPointBuilder = CounterSnapshot.CounterDataPointSnapshot.builder();
+ io.prometheus.metrics.model.snapshots.GaugeSnapshot.GaugeDataPointSnapshot.Builder
+ gaugeDataPointBuilder = GaugeSnapshot.GaugeDataPointSnapshot.builder();
+ Labels lbls = Labels.of("target", targetName);
- counterBuilder.dataPoint(counterDataPointBuilder.build());
- gaugeBuilder.dataPoint(gaugeDataPointBuilder.build());
+ if (procs == null || procs.length == 0) {
+ counterDataPointBuilder.labels(lbls.merge(Labels.of("proc", "defaultProc")));
+ gaugeDataPointBuilder.labels(lbls.merge(Labels.of("proc", "defaultProc")));
+ counterDataPointBuilder.value(70);
+ gaugeDataPointBuilder.value(Math.random());
- } else {
- for (int i = 0; i < procs.length; i++) {
- counterDataPointBuilder.labels(lbls.merge(Labels.of("proc", procs[i])));
- gaugeDataPointBuilder.labels(lbls.merge(Labels.of("proc", procs[i])));
- counterDataPointBuilder.value(Math.random());
- gaugeDataPointBuilder.value(Math.random());
+ counterBuilder.dataPoint(counterDataPointBuilder.build());
+ gaugeBuilder.dataPoint(gaugeDataPointBuilder.build());
- counterBuilder.dataPoint(counterDataPointBuilder.build());
- gaugeBuilder.dataPoint(gaugeDataPointBuilder.build());
- }
- }
- Collection snaps = new ArrayList();
- snaps.add(counterBuilder.build());
- snaps.add(gaugeBuilder.build());
- MetricSnapshots msnaps = new MetricSnapshots(snaps);
- return msnaps;
- }
+ } else {
+ for (int i = 0; i < procs.length; i++) {
+ counterDataPointBuilder.labels(lbls.merge(Labels.of("proc", procs[i])));
+ gaugeDataPointBuilder.labels(lbls.merge(Labels.of("proc", procs[i])));
+ counterDataPointBuilder.value(Math.random());
+ gaugeDataPointBuilder.value(Math.random());
- public List getPrometheusNames() {
- List names = new ArrayList();
- names.add("x_calls_total");
- names.add("x_load");
- return names;
- }
+ counterBuilder.dataPoint(counterDataPointBuilder.build());
+ gaugeBuilder.dataPoint(gaugeDataPointBuilder.build());
+ }
+ }
+ Collection snaps = new ArrayList();
+ snaps.add(counterBuilder.build());
+ snaps.add(gaugeBuilder.build());
+ MetricSnapshots msnaps = new MetricSnapshots(snaps);
+ return msnaps;
+ }
+ public List getPrometheusNames() {
+ List names = new ArrayList();
+ names.add("x_calls_total");
+ names.add("x_load");
+ return names;
+ }
}
diff --git a/examples/example-exporter-opentelemetry/src/main/java/io/prometheus/metrics/examples/opentelemetry/Main.java b/examples/example-exporter-opentelemetry/src/main/java/io/prometheus/metrics/examples/opentelemetry/Main.java
index 966b16d92..defe85074 100644
--- a/examples/example-exporter-opentelemetry/src/main/java/io/prometheus/metrics/examples/opentelemetry/Main.java
+++ b/examples/example-exporter-opentelemetry/src/main/java/io/prometheus/metrics/examples/opentelemetry/Main.java
@@ -5,37 +5,36 @@
import io.prometheus.metrics.instrumentation.jvm.JvmMetrics;
import io.prometheus.metrics.model.snapshots.Unit;
-/**
- * Simple example of an application exposing metrics pushing metrics via OTLP.
- */
+/** Simple example of an application exposing metrics pushing metrics via OTLP. */
public class Main {
- public static void main(String[] args) throws Exception {
+ public static void main(String[] args) throws Exception {
- // Note: Some JVM metrics are also defined as OpenTelemetry's semantic conventions.
- // We have plans to implement a configuration option for JvmMetrics to use OpenTelemetry
- // naming conventions rather than the Prometheus names.
- JvmMetrics.builder().register();
+ // Note: Some JVM metrics are also defined as OpenTelemetry's semantic conventions.
+ // We have plans to implement a configuration option for JvmMetrics to use OpenTelemetry
+ // naming conventions rather than the Prometheus names.
+ JvmMetrics.builder().register();
- // Note: uptime_seconds_total is not a great example:
- // The built-in JvmMetrics have an out-of-the-box metric named process_start_time_seconds
- // with the start timestamp in seconds, so if you want to know the uptime you can simply
- // run the Prometheus query
- // time() - process_start_time_seconds
- // rather than creating a custom uptime metric.
- Counter counter = Counter.builder()
- .name("uptime_seconds_total")
- .help("total number of seconds since this application was started")
- .unit(Unit.SECONDS)
- .register();
+ // Note: uptime_seconds_total is not a great example:
+ // The built-in JvmMetrics have an out-of-the-box metric named process_start_time_seconds
+ // with the start timestamp in seconds, so if you want to know the uptime you can simply
+ // run the Prometheus query
+ // time() - process_start_time_seconds
+ // rather than creating a custom uptime metric.
+ Counter counter =
+ Counter.builder()
+ .name("uptime_seconds_total")
+ .help("total number of seconds since this application was started")
+ .unit(Unit.SECONDS)
+ .register();
- OpenTelemetryExporter.builder()
- .intervalSeconds(5) // ridiculously short interval for demo purposes
- .buildAndStart();
+ OpenTelemetryExporter.builder()
+ .intervalSeconds(5) // ridiculously short interval for demo purposes
+ .buildAndStart();
- while (true) {
- Thread.sleep(1000);
- counter.inc();
- }
+ while (true) {
+ Thread.sleep(1000);
+ counter.inc();
}
+ }
}
diff --git a/examples/example-exporter-opentelemetry/src/main/java/io/prometheus/metrics/examples/opentelemetry/ManualCompleteMetricsTest.java b/examples/example-exporter-opentelemetry/src/main/java/io/prometheus/metrics/examples/opentelemetry/ManualCompleteMetricsTest.java
index 72e8dd107..b8b8ef98b 100644
--- a/examples/example-exporter-opentelemetry/src/main/java/io/prometheus/metrics/examples/opentelemetry/ManualCompleteMetricsTest.java
+++ b/examples/example-exporter-opentelemetry/src/main/java/io/prometheus/metrics/examples/opentelemetry/ManualCompleteMetricsTest.java
@@ -19,127 +19,128 @@
public class ManualCompleteMetricsTest {
- // This contains a complete set of all metric types, and target_info and otel_scope_info.
- // I used this to expose in Prometheus format and OTLP format at the same time and compare the results.
- // I'm keeping this as a backup for now, but this should be converted to an integration test.
- //
- // To run it, add prometheus-metrics-exporter-httpserver as a dependency and configure Prometheus
- // to scrape from port 9400 in addition to receiving metrics via remote write.
-
- /*
- public static void main(String[] args) throws Exception {
-
- Counter counter = Counter.newBuilder()
- .withName("uptime_seconds_total")
- .withHelp("total number of seconds since this application was started")
- .withUnit(Unit.SECONDS)
- .register();
-
- Gauge gauge = Gauge.newBuilder()
- .withName("temperature_celsius")
- .withHelp("temperature in celsius")
- .withUnit(Unit.CELSIUS)
- .withLabelNames("location")
- .register();
-
- gauge.labelValues("inside").set(23.4);
- gauge.labelValues("outside").set(9.3);
-
- // By default, the histogram will be exported as an exponential histogram in OpenTelemetry.
- Histogram histogram = Histogram.newBuilder()
- .withName("request_latency_seconds")
- .withHelp("Request duration in seconds")
- .withUnit(Unit.SECONDS)
- .withLabelNames("http_status")
- .register();
-
- Random random = new Random(0);
- for (int i = 0; i < 1000; i++) {
- histogram.labelValues("200").observe(random.nextGaussian());
- }
-
- // Explicitly use a classic-only histogram to have an example of a classic histogram in OpenTelemetry
- Histogram classicHistogram = Histogram.newBuilder()
- .withName("request_size_bytes")
- .withHelp("Request size in Bytes")
- .withUnit(Unit.BYTES)
- .withLabelNames("path")
- .classicOnly()
- .withClassicBuckets(128, 256, 512, 1024, 2048)
- .register();
-
- for (int i = 0; i < 15; i++) {
- classicHistogram.labelValues("200").observe(random.nextInt(3000));
- }
-
- Summary summary = Summary.newBuilder()
- .withName("response_latency_seconds")
- .withHelp("Response latency seconds")
- .withUnit(Unit.BYTES)
- .withQuantile(0.95)
- .withQuantile(0.99)
- .register();
-
- for (int i = 0; i < 1000; i++) {
- summary.observe(random.nextGaussian());
- }
-
- Info targetInfo = Info.newBuilder()
- .withName("target_info")
- .withHelp("OTel resource")
- .withLabelNames("service.version")
- .register();
- targetInfo.setLabelValues("1.0.0");
-
- Info scopeInfo = Info.newBuilder()
- .withName("otel_scope_info")
- .withLabelNames("otel.scope.name", "otel.scope.version", "library_mascot")
- .register();
-
- scopeInfo.setLabelValues("my.instrumentation.lib", "100.3", "bear");
-
- Info info = Info.newBuilder()
- .withName("java_runtime_info")
- .withHelp("Java runtime info")
- .withLabelNames("version", "vendor", "runtime")
- .register();
-
- String version = System.getProperty("java.runtime.version", "unknown");
- String vendor = System.getProperty("java.vm.vendor", "unknown");
- String runtime = System.getProperty("java.runtime.name", "unknown");
-
- info.setLabelValues(version, vendor, runtime);
-
- StateSet stateSet = StateSet.newBuilder()
- .withName("feature_flags")
- .withLabelNames("env")
- .withStates("feature1", "feature2")
- .register();
-
- stateSet.labelValues("dev").setFalse("feature1");
- stateSet.labelValues("dev").setTrue("feature2");
-
- PrometheusRegistry.defaultRegistry.register(() -> UnknownSnapshot.newBuilder()
- .withName("my_unknown_metric")
- .addDataPoint(UnknownSnapshot.UnknownDataPointSnapshot.newBuilder()
- .withLabels(Labels.of("a", "1", "b", "2"))
- .withValue(3.0)
- .build())
- .build());
-
- HTTPServer server = HTTPServer.newBuilder()
- .withPort(9400)
- .buildAndStart();
- System.out.println("HTTPServer listening on port http://localhost:" + server.getPort() + "/metrics");
-
- OpenTelemetryExporter.newBuilder()
- .withIntervalSeconds(5)
- .buildAndStart();
-
- while (true) {
- Thread.sleep(1000);
- counter.inc();
- }
- }
- */
+ // This contains a complete set of all metric types, and target_info and otel_scope_info.
+ // I used this to expose in Prometheus format and OTLP format at the same time and compare the
+ // results.
+ // I'm keeping this as a backup for now, but this should be converted to an integration test.
+ //
+ // To run it, add prometheus-metrics-exporter-httpserver as a dependency and configure Prometheus
+ // to scrape from port 9400 in addition to receiving metrics via remote write.
+
+ /*
+ public static void main(String[] args) throws Exception {
+
+ Counter counter = Counter.newBuilder()
+ .withName("uptime_seconds_total")
+ .withHelp("total number of seconds since this application was started")
+ .withUnit(Unit.SECONDS)
+ .register();
+
+ Gauge gauge = Gauge.newBuilder()
+ .withName("temperature_celsius")
+ .withHelp("temperature in celsius")
+ .withUnit(Unit.CELSIUS)
+ .withLabelNames("location")
+ .register();
+
+ gauge.labelValues("inside").set(23.4);
+ gauge.labelValues("outside").set(9.3);
+
+ // By default, the histogram will be exported as an exponential histogram in OpenTelemetry.
+ Histogram histogram = Histogram.newBuilder()
+ .withName("request_latency_seconds")
+ .withHelp("Request duration in seconds")
+ .withUnit(Unit.SECONDS)
+ .withLabelNames("http_status")
+ .register();
+
+ Random random = new Random(0);
+ for (int i = 0; i < 1000; i++) {
+ histogram.labelValues("200").observe(random.nextGaussian());
+ }
+
+ // Explicitly use a classic-only histogram to have an example of a classic histogram in OpenTelemetry
+ Histogram classicHistogram = Histogram.newBuilder()
+ .withName("request_size_bytes")
+ .withHelp("Request size in Bytes")
+ .withUnit(Unit.BYTES)
+ .withLabelNames("path")
+ .classicOnly()
+ .withClassicBuckets(128, 256, 512, 1024, 2048)
+ .register();
+
+ for (int i = 0; i < 15; i++) {
+ classicHistogram.labelValues("200").observe(random.nextInt(3000));
+ }
+
+ Summary summary = Summary.newBuilder()
+ .withName("response_latency_seconds")
+ .withHelp("Response latency seconds")
+ .withUnit(Unit.BYTES)
+ .withQuantile(0.95)
+ .withQuantile(0.99)
+ .register();
+
+ for (int i = 0; i < 1000; i++) {
+ summary.observe(random.nextGaussian());
+ }
+
+ Info targetInfo = Info.newBuilder()
+ .withName("target_info")
+ .withHelp("OTel resource")
+ .withLabelNames("service.version")
+ .register();
+ targetInfo.setLabelValues("1.0.0");
+
+ Info scopeInfo = Info.newBuilder()
+ .withName("otel_scope_info")
+ .withLabelNames("otel.scope.name", "otel.scope.version", "library_mascot")
+ .register();
+
+ scopeInfo.setLabelValues("my.instrumentation.lib", "100.3", "bear");
+
+ Info info = Info.newBuilder()
+ .withName("java_runtime_info")
+ .withHelp("Java runtime info")
+ .withLabelNames("version", "vendor", "runtime")
+ .register();
+
+ String version = System.getProperty("java.runtime.version", "unknown");
+ String vendor = System.getProperty("java.vm.vendor", "unknown");
+ String runtime = System.getProperty("java.runtime.name", "unknown");
+
+ info.setLabelValues(version, vendor, runtime);
+
+ StateSet stateSet = StateSet.newBuilder()
+ .withName("feature_flags")
+ .withLabelNames("env")
+ .withStates("feature1", "feature2")
+ .register();
+
+ stateSet.labelValues("dev").setFalse("feature1");
+ stateSet.labelValues("dev").setTrue("feature2");
+
+ PrometheusRegistry.defaultRegistry.register(() -> UnknownSnapshot.newBuilder()
+ .withName("my_unknown_metric")
+ .addDataPoint(UnknownSnapshot.UnknownDataPointSnapshot.newBuilder()
+ .withLabels(Labels.of("a", "1", "b", "2"))
+ .withValue(3.0)
+ .build())
+ .build());
+
+ HTTPServer server = HTTPServer.newBuilder()
+ .withPort(9400)
+ .buildAndStart();
+ System.out.println("HTTPServer listening on port http://localhost:" + server.getPort() + "/metrics");
+
+ OpenTelemetryExporter.newBuilder()
+ .withIntervalSeconds(5)
+ .buildAndStart();
+
+ while (true) {
+ Thread.sleep(1000);
+ counter.inc();
+ }
+ }
+ */
}
diff --git a/examples/example-exporter-servlet-tomcat/src/main/java/io/prometheus/metrics/examples/tomcat_servlet/HelloWorldServlet.java b/examples/example-exporter-servlet-tomcat/src/main/java/io/prometheus/metrics/examples/tomcat_servlet/HelloWorldServlet.java
index d3d8f37e5..eb2fa4f19 100644
--- a/examples/example-exporter-servlet-tomcat/src/main/java/io/prometheus/metrics/examples/tomcat_servlet/HelloWorldServlet.java
+++ b/examples/example-exporter-servlet-tomcat/src/main/java/io/prometheus/metrics/examples/tomcat_servlet/HelloWorldServlet.java
@@ -1,57 +1,56 @@
package io.prometheus.metrics.examples.tomcat_servlet;
+import static io.prometheus.metrics.model.snapshots.Unit.nanosToSeconds;
+
import io.prometheus.metrics.core.metrics.Counter;
import io.prometheus.metrics.core.metrics.Histogram;
import io.prometheus.metrics.model.snapshots.Unit;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
-
import java.io.IOException;
import java.util.Random;
-import static io.prometheus.metrics.model.snapshots.Unit.nanosToSeconds;
-
-/**
- * Hello World REST servlet, with an example counter and an example histogram.
- */
+/** Hello World REST servlet, with an example counter and an example histogram. */
public class HelloWorldServlet extends HttpServlet {
- private final Random random = new Random(0);
-
- // Note: The requests_total counter is not a great example, because the
- // request_duration_seconds histogram below also has a count with the number of requests.
- private final Counter counter = Counter.builder()
- .name("requests_total")
- .help("total number of requests")
- .labelNames("http_status")
- .register();
-
- private final Histogram histogram = Histogram.builder()
- .name("request_duration_seconds")
- .help("request duration in seconds")
- .unit(Unit.SECONDS)
- .labelNames("http_status")
- .register();
-
- public HelloWorldServlet() {
- counter.initLabelValues("200");
- histogram.initLabelValues("200");
- }
-
- @Override
- protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
- long start = System.nanoTime();
- try {
- Thread.sleep((long) (Math.abs((random.nextGaussian() + 1.0) * 100.0)));
- resp.setStatus(200);
- resp.setContentType("text/plain");
- resp.getWriter().println("Hello, World!");
- } catch (InterruptedException e) {
- throw new RuntimeException(e);
- } finally {
- counter.labelValues("200").inc();
- histogram.labelValues("200").observe(nanosToSeconds(System.nanoTime() - start));
- }
+ private final Random random = new Random(0);
+
+ // Note: The requests_total counter is not a great example, because the
+ // request_duration_seconds histogram below also has a count with the number of requests.
+ private final Counter counter =
+ Counter.builder()
+ .name("requests_total")
+ .help("total number of requests")
+ .labelNames("http_status")
+ .register();
+
+ private final Histogram histogram =
+ Histogram.builder()
+ .name("request_duration_seconds")
+ .help("request duration in seconds")
+ .unit(Unit.SECONDS)
+ .labelNames("http_status")
+ .register();
+
+ public HelloWorldServlet() {
+ counter.initLabelValues("200");
+ histogram.initLabelValues("200");
+ }
+
+ @Override
+ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
+ long start = System.nanoTime();
+ try {
+ Thread.sleep((long) (Math.abs((random.nextGaussian() + 1.0) * 100.0)));
+ resp.setStatus(200);
+ resp.setContentType("text/plain");
+ resp.getWriter().println("Hello, World!");
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ } finally {
+ counter.labelValues("200").inc();
+ histogram.labelValues("200").observe(nanosToSeconds(System.nanoTime() - start));
}
+ }
}
diff --git a/examples/example-exporter-servlet-tomcat/src/main/java/io/prometheus/metrics/examples/tomcat_servlet/Main.java b/examples/example-exporter-servlet-tomcat/src/main/java/io/prometheus/metrics/examples/tomcat_servlet/Main.java
index 4ce6353db..81bc2ac19 100644
--- a/examples/example-exporter-servlet-tomcat/src/main/java/io/prometheus/metrics/examples/tomcat_servlet/Main.java
+++ b/examples/example-exporter-servlet-tomcat/src/main/java/io/prometheus/metrics/examples/tomcat_servlet/Main.java
@@ -2,38 +2,35 @@
import io.prometheus.metrics.exporter.servlet.jakarta.PrometheusMetricsServlet;
import io.prometheus.metrics.instrumentation.jvm.JvmMetrics;
-import org.apache.catalina.Context;
-import org.apache.catalina.LifecycleException;
-import org.apache.catalina.startup.Tomcat;
-
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
+import org.apache.catalina.Context;
+import org.apache.catalina.LifecycleException;
+import org.apache.catalina.startup.Tomcat;
-/**
- * Simple example using embedded Tomcat and the {@link PrometheusMetricsServlet}.
- */
+/** Simple example using embedded Tomcat and the {@link PrometheusMetricsServlet}. */
public class Main {
- public static void main(String[] args) throws LifecycleException, IOException {
+ public static void main(String[] args) throws LifecycleException, IOException {
- JvmMetrics.builder().register();
+ JvmMetrics.builder().register();
- Tomcat tomcat = new Tomcat();
- Path tmpDir = Files.createTempDirectory("prometheus-tomcat-servlet-example-");
- tomcat.setBaseDir(tmpDir.toFile().getAbsolutePath());
+ Tomcat tomcat = new Tomcat();
+ Path tmpDir = Files.createTempDirectory("prometheus-tomcat-servlet-example-");
+ tomcat.setBaseDir(tmpDir.toFile().getAbsolutePath());
- Context ctx = tomcat.addContext("", new File(".").getAbsolutePath());
+ Context ctx = tomcat.addContext("", new File(".").getAbsolutePath());
- Tomcat.addServlet(ctx, "hello", new HelloWorldServlet());
- ctx.addServletMappingDecoded("/*", "hello");
+ Tomcat.addServlet(ctx, "hello", new HelloWorldServlet());
+ ctx.addServletMappingDecoded("/*", "hello");
- Tomcat.addServlet(ctx, "metrics", new PrometheusMetricsServlet());
- ctx.addServletMappingDecoded("/metrics", "metrics");
+ Tomcat.addServlet(ctx, "metrics", new PrometheusMetricsServlet());
+ ctx.addServletMappingDecoded("/metrics", "metrics");
- tomcat.getConnector();
- tomcat.start();
- tomcat.getServer().await();
- }
+ tomcat.getConnector();
+ tomcat.start();
+ tomcat.getServer().await();
+ }
}
diff --git a/examples/example-native-histogram/src/main/java/io/prometheus/metrics/examples/nativehistogram/Main.java b/examples/example-native-histogram/src/main/java/io/prometheus/metrics/examples/nativehistogram/Main.java
index 591216fb7..b23fd054d 100644
--- a/examples/example-native-histogram/src/main/java/io/prometheus/metrics/examples/nativehistogram/Main.java
+++ b/examples/example-native-histogram/src/main/java/io/prometheus/metrics/examples/nativehistogram/Main.java
@@ -4,36 +4,35 @@
import io.prometheus.metrics.exporter.httpserver.HTTPServer;
import io.prometheus.metrics.instrumentation.jvm.JvmMetrics;
import io.prometheus.metrics.model.snapshots.Unit;
-
import java.io.IOException;
import java.util.Random;
public class Main {
- public static void main(String[] args) throws IOException, InterruptedException {
+ public static void main(String[] args) throws IOException, InterruptedException {
- JvmMetrics.builder().register();
+ JvmMetrics.builder().register();
- Histogram histogram = Histogram.builder()
- .name("request_latency_seconds")
- .help("request latency in seconds")
- .unit(Unit.SECONDS)
- .labelNames("path", "status")
- .register();
+ Histogram histogram =
+ Histogram.builder()
+ .name("request_latency_seconds")
+ .help("request latency in seconds")
+ .unit(Unit.SECONDS)
+ .labelNames("path", "status")
+ .register();
- HTTPServer server = HTTPServer.builder()
- .port(9400)
- .buildAndStart();
+ HTTPServer server = HTTPServer.builder().port(9400).buildAndStart();
- System.out.println("HTTPServer listening on port http://localhost:" + server.getPort() + "/metrics");
+ System.out.println(
+ "HTTPServer listening on port http://localhost:" + server.getPort() + "/metrics");
- Random random = new Random(0);
+ Random random = new Random(0);
- while (true) {
- double duration = Math.abs(random.nextGaussian() / 10.0 + 0.2);
- String status = random.nextInt(100) < 20 ? "500" : "200";
- histogram.labelValues("/", status).observe(duration);
- Thread.sleep(1000);
- }
+ while (true) {
+ double duration = Math.abs(random.nextGaussian() / 10.0 + 0.2);
+ String status = random.nextInt(100) < 20 ? "500" : "200";
+ histogram.labelValues("/", status).observe(duration);
+ Thread.sleep(1000);
}
+ }
}
diff --git a/examples/example-prometheus-properties/src/main/java/io/prometheus/metrics/examples/prometheus_properties/Main.java b/examples/example-prometheus-properties/src/main/java/io/prometheus/metrics/examples/prometheus_properties/Main.java
index 97611fe7b..e1f5954bc 100644
--- a/examples/example-prometheus-properties/src/main/java/io/prometheus/metrics/examples/prometheus_properties/Main.java
+++ b/examples/example-prometheus-properties/src/main/java/io/prometheus/metrics/examples/prometheus_properties/Main.java
@@ -4,42 +4,42 @@
import io.prometheus.metrics.exporter.httpserver.HTTPServer;
import io.prometheus.metrics.instrumentation.jvm.JvmMetrics;
import io.prometheus.metrics.model.snapshots.Unit;
-
import java.io.IOException;
import java.util.Random;
public class Main {
- public static void main(String[] args) throws IOException, InterruptedException {
+ public static void main(String[] args) throws IOException, InterruptedException {
- JvmMetrics.builder().register();
+ JvmMetrics.builder().register();
- Histogram requestDuration = Histogram.builder()
- .name("request_duration_seconds")
- .help("request duration in seconds")
- .unit(Unit.SECONDS)
- .register();
+ Histogram requestDuration =
+ Histogram.builder()
+ .name("request_duration_seconds")
+ .help("request duration in seconds")
+ .unit(Unit.SECONDS)
+ .register();
- Histogram requestSize = Histogram.builder()
- .name("request_size_bytes")
- .help("request size in bytes")
- .unit(Unit.BYTES)
- .register();
+ Histogram requestSize =
+ Histogram.builder()
+ .name("request_size_bytes")
+ .help("request size in bytes")
+ .unit(Unit.BYTES)
+ .register();
- HTTPServer server = HTTPServer.builder()
- .port(9400)
- .buildAndStart();
+ HTTPServer server = HTTPServer.builder().port(9400).buildAndStart();
- System.out.println("HTTPServer listening on port http://localhost:" + server.getPort() + "/metrics");
+ System.out.println(
+ "HTTPServer listening on port http://localhost:" + server.getPort() + "/metrics");
- Random random = new Random(0);
+ Random random = new Random(0);
- while (true) {
- double duration = Math.abs(random.nextGaussian() / 10.0 + 0.2);
- double size = random.nextInt(1000) + 256;
- requestDuration.observe(duration);
- requestSize.observe(size);
- Thread.sleep(1000);
- }
+ while (true) {
+ double duration = Math.abs(random.nextGaussian() / 10.0 + 0.2);
+ double size = random.nextInt(1000) + 256;
+ requestDuration.observe(duration);
+ requestSize.observe(size);
+ Thread.sleep(1000);
}
+ }
}
diff --git a/examples/example-simpleclient-bridge/src/main/java/io/prometheus/metrics/examples/simpleclient/Main.java b/examples/example-simpleclient-bridge/src/main/java/io/prometheus/metrics/examples/simpleclient/Main.java
index cb0488d57..dd9dbcdcb 100644
--- a/examples/example-simpleclient-bridge/src/main/java/io/prometheus/metrics/examples/simpleclient/Main.java
+++ b/examples/example-simpleclient-bridge/src/main/java/io/prometheus/metrics/examples/simpleclient/Main.java
@@ -3,39 +3,34 @@
import io.prometheus.client.Counter;
import io.prometheus.metrics.exporter.httpserver.HTTPServer;
import io.prometheus.metrics.simpleclient.bridge.SimpleclientCollector;
-
import java.io.IOException;
-/**
- * Simple example of the simpleclient backwards compatibility module.
- */
+/** Simple example of the simpleclient backwards compatibility module. */
public class Main {
- public static void main(String[] args) throws IOException, InterruptedException {
+ public static void main(String[] args) throws IOException, InterruptedException {
- // The following call will register all metrics from the old CollectorRegistry.defaultRegistry
- // with the new PrometheusRegistry.defaultRegistry.
+ // The following call will register all metrics from the old CollectorRegistry.defaultRegistry
+ // with the new PrometheusRegistry.defaultRegistry.
- SimpleclientCollector.builder().register();
+ SimpleclientCollector.builder().register();
- // Register a counter with the old CollectorRegistry.
- // It doesn't matter whether the counter is registered before or after bridging with PrometheusRegistry.
+ // Register a counter with the old CollectorRegistry.
+ // It doesn't matter whether the counter is registered before or after bridging with
+ // PrometheusRegistry.
- Counter simpleclientCounter = Counter.build()
- .name("events_total")
- .help("total number of events")
- .register();
+ Counter simpleclientCounter =
+ Counter.build().name("events_total").help("total number of events").register();
- simpleclientCounter.inc();
+ simpleclientCounter.inc();
- // Expose metrics from the new PrometheusRegistry. This should contain the events_total metric.
+ // Expose metrics from the new PrometheusRegistry. This should contain the events_total metric.
- HTTPServer server = HTTPServer.builder()
- .port(9400)
- .buildAndStart();
+ HTTPServer server = HTTPServer.builder().port(9400).buildAndStart();
- System.out.println("HTTPServer listening on port http://localhost:" + server.getPort() + "/metrics");
+ System.out.println(
+ "HTTPServer listening on port http://localhost:" + server.getPort() + "/metrics");
- Thread.currentThread().join();
- }
+ Thread.currentThread().join();
+ }
}
diff --git a/integration-tests/it-common/src/test/java/io/prometheus/client/it/common/LogConsumer.java b/integration-tests/it-common/src/test/java/io/prometheus/client/it/common/LogConsumer.java
index d60e53979..0e6cfbcc6 100644
--- a/integration-tests/it-common/src/test/java/io/prometheus/client/it/common/LogConsumer.java
+++ b/integration-tests/it-common/src/test/java/io/prometheus/client/it/common/LogConsumer.java
@@ -1,36 +1,33 @@
package io.prometheus.client.it.common;
-import org.testcontainers.containers.output.OutputFrame;
-
import java.util.function.Consumer;
+import org.testcontainers.containers.output.OutputFrame;
-/**
- * Print Docker logs from TestContainers to stdout or stderr.
- */
+/** Print Docker logs from TestContainers to stdout or stderr. */
public class LogConsumer implements Consumer {
- private final String prefix;
+ private final String prefix;
- private LogConsumer(String prefix) {
- this.prefix = prefix;
- }
+ private LogConsumer(String prefix) {
+ this.prefix = prefix;
+ }
- public static LogConsumer withPrefix(String prefix) {
- return new LogConsumer(prefix);
- }
+ public static LogConsumer withPrefix(String prefix) {
+ return new LogConsumer(prefix);
+ }
- @Override
- public void accept(OutputFrame outputFrame) {
- switch (outputFrame.getType()) {
- case STDOUT:
- System.out.print(prefix + " - " + outputFrame.getUtf8String());
- break;
- case END:
- System.out.println(prefix + " - END");
- break;
- default: // STDERR or unexpected
- System.err.print(prefix + " - " + outputFrame.getUtf8String());
- break;
- }
+ @Override
+ public void accept(OutputFrame outputFrame) {
+ switch (outputFrame.getType()) {
+ case STDOUT:
+ System.out.print(prefix + " - " + outputFrame.getUtf8String());
+ break;
+ case END:
+ System.out.println(prefix + " - END");
+ break;
+ default: // STDERR or unexpected
+ System.err.print(prefix + " - " + outputFrame.getUtf8String());
+ break;
}
+ }
}
diff --git a/integration-tests/it-common/src/test/java/io/prometheus/client/it/common/Volume.java b/integration-tests/it-common/src/test/java/io/prometheus/client/it/common/Volume.java
index dc9a32992..783ccb7a5 100644
--- a/integration-tests/it-common/src/test/java/io/prometheus/client/it/common/Volume.java
+++ b/integration-tests/it-common/src/test/java/io/prometheus/client/it/common/Volume.java
@@ -1,6 +1,6 @@
package io.prometheus.client.it.common;
-import org.junit.Assert;
+import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
import java.io.File;
import java.io.IOException;
@@ -8,94 +8,96 @@
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.function.Predicate;
+import org.junit.Assert;
-import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
-
-/**
- * Temporary directory in ./target/ to be mounted as a volume in Docker containers.
- */
+/** Temporary directory in ./target/ to be mounted as a volume in Docker containers. */
public class Volume {
- private final Path tmpDir; // will be created in the ./target/ directory
+ private final Path tmpDir; // will be created in the ./target/ directory
- private Volume(Path tmpDir) {
- this.tmpDir = tmpDir;
- }
+ private Volume(Path tmpDir) {
+ this.tmpDir = tmpDir;
+ }
- public static Volume create(String prefix) throws IOException, URISyntaxException {
- Path targetDir = Paths.get(Volume.class.getResource("/").toURI()).getParent();
- Assert.assertEquals("failed to locate target/ directory", "target", targetDir.getFileName().toString());
- return new Volume(Files.createTempDirectory(targetDir, prefix + "-"));
- }
+ public static Volume create(String prefix) throws IOException, URISyntaxException {
+ Path targetDir = Paths.get(Volume.class.getResource("/").toURI()).getParent();
+ Assert.assertEquals(
+ "failed to locate target/ directory", "target", targetDir.getFileName().toString());
+ return new Volume(Files.createTempDirectory(targetDir, prefix + "-"));
+ }
- /**
- * Copy a file or directory to this volume.
- * @param src is relative to {@code ./target/}
- */
- public Volume copy(String src) throws IOException {
- Path srcPath = tmpDir.getParent().resolve(src);
- if (Files.isRegularFile(srcPath)) {
- Files.copy(srcPath, tmpDir.resolve(srcPath.getFileName()), REPLACE_EXISTING);
- } else if (Files.isDirectory(srcPath)) {
- Path dest = tmpDir.resolve(srcPath.getFileName());
- Files.createDirectories(dest);
- Files.walkFileTree(srcPath, new SimpleFileVisitor() {
+ /**
+ * Copy a file or directory to this volume.
+ *
+ * @param src is relative to {@code ./target/}
+ */
+ public Volume copy(String src) throws IOException {
+ Path srcPath = tmpDir.getParent().resolve(src);
+ if (Files.isRegularFile(srcPath)) {
+ Files.copy(srcPath, tmpDir.resolve(srcPath.getFileName()), REPLACE_EXISTING);
+ } else if (Files.isDirectory(srcPath)) {
+ Path dest = tmpDir.resolve(srcPath.getFileName());
+ Files.createDirectories(dest);
+ Files.walkFileTree(
+ srcPath,
+ new SimpleFileVisitor() {
- // create parent directories
- @Override
- public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
- Files.createDirectories(dest.resolve(srcPath.relativize(dir)));
- return FileVisitResult.CONTINUE;
- }
+ // create parent directories
+ @Override
+ public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
+ throws IOException {
+ Files.createDirectories(dest.resolve(srcPath.relativize(dir)));
+ return FileVisitResult.CONTINUE;
+ }
- // copy file
- @Override
- public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
- Files.copy(file, dest.resolve(srcPath.relativize(file)), REPLACE_EXISTING);
- return FileVisitResult.CONTINUE;
- }
- });
- } else {
- Assert.fail(src + ": No such file or directory");
- }
- return this;
+ // copy file
+ @Override
+ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
+ throws IOException {
+ Files.copy(file, dest.resolve(srcPath.relativize(file)), REPLACE_EXISTING);
+ return FileVisitResult.CONTINUE;
+ }
+ });
+ } else {
+ Assert.fail(src + ": No such file or directory");
}
+ return this;
+ }
- /**
- * Remove files in tmpDir if they match the predicate.
- */
- public void rm(Predicate predicate) throws IOException {
- Files.walkFileTree(tmpDir, new SimpleFileVisitor() {
- @Override
- public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
- if (predicate.test(file)) {
- Files.delete(file);
- }
- return FileVisitResult.CONTINUE;
+ /** Remove files in tmpDir if they match the predicate. */
+ public void rm(Predicate predicate) throws IOException {
+ Files.walkFileTree(
+ tmpDir,
+ new SimpleFileVisitor() {
+ @Override
+ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
+ throws IOException {
+ if (predicate.test(file)) {
+ Files.delete(file);
}
+ return FileVisitResult.CONTINUE;
+ }
});
- }
+ }
- public String getHostPath() {
- return tmpDir.toString();
- }
+ public String getHostPath() {
+ return tmpDir.toString();
+ }
- /**
- * Recursively remove tmpDir and its contents.
- */
- public void remove() throws IOException {
- if (!deleteRecursively(tmpDir.toFile())) {
- throw new IOException(tmpDir + ": Failed to remove temporary test directory.");
- }
+ /** Recursively remove tmpDir and its contents. */
+ public void remove() throws IOException {
+ if (!deleteRecursively(tmpDir.toFile())) {
+ throw new IOException(tmpDir + ": Failed to remove temporary test directory.");
}
+ }
- private boolean deleteRecursively(File file) {
- File[] allContents = file.listFiles();
- if (allContents != null) {
- for (File child : allContents) {
- deleteRecursively(child);
- }
- }
- return file.delete();
+ private boolean deleteRecursively(File file) {
+ File[] allContents = file.listFiles();
+ if (allContents != null) {
+ for (File child : allContents) {
+ deleteRecursively(child);
+ }
}
+ return file.delete();
+ }
}
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 b8cdc5141..4c665dd81 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
@@ -6,85 +6,87 @@
import io.prometheus.metrics.exporter.httpserver.HTTPServer;
import io.prometheus.metrics.model.registry.Collector;
import io.prometheus.metrics.model.registry.PrometheusRegistry;
-import io.prometheus.metrics.model.snapshots.MetricSnapshot;
import io.prometheus.metrics.model.snapshots.Unit;
-
import java.io.IOException;
public class HTTPServerSample {
- enum Mode {
- success,
- error
- }
-
- public static void main(String[] args) throws IOException, InterruptedException {
-
- if (args.length != 2) {
- System.err.println("Usage: java -jar exporter-httpserver-sample.jar ");
- System.err.println("Where mode is \"success\" or \"error\".");
- System.exit(1);
- }
-
- int port = parsePortOrExit(args[0]);
- Mode mode = parseModeOrExit(args[1]);
-
- Counter counter = Counter.builder()
- .name("uptime_seconds_total")
- .help("total number of seconds since this application was started")
- .unit(Unit.SECONDS)
- .register();
- counter.inc(17);
+ enum Mode {
+ success,
+ error
+ }
- Info info = Info.builder()
- .name("integration_test_info")
- .help("Info metric on this integration test")
- .labelNames("test_name")
- .register();
- info.addLabelValues("exporter-httpserver-sample");
+ public static void main(String[] args) throws IOException, InterruptedException {
- Gauge gauge = Gauge.builder()
- .name("temperature_celsius")
- .help("Temperature in Celsius")
- .unit(Unit.CELSIUS)
- .labelNames("location")
- .register();
- gauge.labelValues("inside").set(23.0);
- gauge.labelValues("outside").set(27.0);
+ if (args.length != 2) {
+ System.err.println("Usage: java -jar exporter-httpserver-sample.jar ");
+ System.err.println("Where mode is \"success\" or \"error\".");
+ System.exit(1);
+ }
- if (mode == Mode.error) {
- Collector failingCollector = () -> {
- throw new RuntimeException("Simulating an error.");
- };
+ int port = parsePortOrExit(args[0]);
+ Mode mode = parseModeOrExit(args[1]);
+
+ Counter counter =
+ Counter.builder()
+ .name("uptime_seconds_total")
+ .help("total number of seconds since this application was started")
+ .unit(Unit.SECONDS)
+ .register();
+ counter.inc(17);
+
+ Info info =
+ Info.builder()
+ .name("integration_test_info")
+ .help("Info metric on this integration test")
+ .labelNames("test_name")
+ .register();
+ info.addLabelValues("exporter-httpserver-sample");
+
+ Gauge gauge =
+ Gauge.builder()
+ .name("temperature_celsius")
+ .help("Temperature in Celsius")
+ .unit(Unit.CELSIUS)
+ .labelNames("location")
+ .register();
+ gauge.labelValues("inside").set(23.0);
+ gauge.labelValues("outside").set(27.0);
+
+ if (mode == Mode.error) {
+ Collector failingCollector =
+ () -> {
+ throw new RuntimeException("Simulating an error.");
+ };
+
+ PrometheusRegistry.defaultRegistry.register(failingCollector);
+ }
- PrometheusRegistry.defaultRegistry.register(failingCollector);
- }
+ HTTPServer server = HTTPServer.builder().port(port).buildAndStart();
- HTTPServer server = HTTPServer.builder()
- .port(port)
- .buildAndStart();
+ System.out.println(
+ "HTTPServer listening on port http://localhost:" + server.getPort() + "/metrics");
+ Thread.currentThread().join(); // wait forever
+ }
- System.out.println("HTTPServer listening on port http://localhost:" + server.getPort() + "/metrics");
- Thread.currentThread().join(); // wait forever
+ private static int parsePortOrExit(String port) {
+ try {
+ return Integer.parseInt(port);
+ } catch (NumberFormatException e) {
+ System.err.println("\"" + port + "\": Invalid port number.");
+ System.exit(1);
}
-
- private static int parsePortOrExit(String port) {
- try {
- return Integer.parseInt(port);
- } catch (NumberFormatException e) {
- System.err.println("\"" + port + "\": Invalid port number.");
- System.exit(1);
- }
- return 0; // this won't happen
- }
-
- private static Mode parseModeOrExit(String mode) {
- try {
- return Mode.valueOf(mode);
- } catch (IllegalArgumentException e) {
- System.err.println("\"" + mode + "\": Invalid mode. Legal values are \"success\" and \"error\".");
- System.exit(1);
- }
- return null; // this won't happen
+ return 0; // this won't happen
+ }
+
+ private static Mode parseModeOrExit(String mode) {
+ try {
+ return Mode.valueOf(mode);
+ } catch (IllegalArgumentException e) {
+ System.err.println(
+ "\"" + mode + "\": Invalid mode. Legal values are \"success\" and \"error\".");
+ System.exit(1);
}
+ return null; // this won't happen
+ }
}
diff --git a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/src/main/java/io/prometheus/metrics/it/exporter/servlet/jetty/ExporterServletJettySample.java b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/src/main/java/io/prometheus/metrics/it/exporter/servlet/jetty/ExporterServletJettySample.java
index 9e1a22487..1cc16ee4b 100644
--- a/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/src/main/java/io/prometheus/metrics/it/exporter/servlet/jetty/ExporterServletJettySample.java
+++ b/integration-tests/it-exporter/it-exporter-servlet-jetty-sample/src/main/java/io/prometheus/metrics/it/exporter/servlet/jetty/ExporterServletJettySample.java
@@ -6,99 +6,101 @@
import io.prometheus.metrics.exporter.servlet.jakarta.PrometheusMetricsServlet;
import io.prometheus.metrics.model.registry.Collector;
import io.prometheus.metrics.model.registry.PrometheusRegistry;
-import io.prometheus.metrics.model.snapshots.MetricSnapshot;
import io.prometheus.metrics.model.snapshots.Unit;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.servlet.ServletHandler;
-/**
- * Sample application using the {@link PrometheusMetricsServlet} in Jetty.
- */
+/** Sample application using the {@link PrometheusMetricsServlet} in Jetty. */
public class ExporterServletJettySample {
- enum Mode {
- success,
- error
- }
+ enum Mode {
+ success,
+ error
+ }
+
+ public static void main(String[] args) throws Exception {
- public static void main(String[] args) throws Exception {
-
- if (args.length != 2) {
- System.err.println("Usage: java -jar exporter-servlet-jetty-sample.jar ");
- System.err.println("Where mode is \"success\" or \"error\".");
- System.exit(1);
- }
-
- int port = parsePortOrExit(args[0]);
- Mode mode = parseModeOrExit(args[1]);
-
- Counter counter = Counter.builder()
- .name("uptime_seconds_total")
- .help("total number of seconds since this application was started")
- .unit(Unit.SECONDS)
- .register();
- counter.inc(17);
-
- Info info = Info.builder()
- .name("integration_test_info")
- .help("Info metric on this integration test")
- .labelNames("test_name")
- .register();
- info.addLabelValues("exporter-servlet-jetty-sample");
-
- Gauge gauge = Gauge.builder()
- .name("temperature_celsius")
- .help("Temperature in Celsius")
- .unit(Unit.CELSIUS)
- .labelNames("location")
- .register();
- gauge.labelValues("inside").set(23.0);
- gauge.labelValues("outside").set(27.0);
-
- if (mode == Mode.error) {
- Collector failingCollector = () -> {
- throw new RuntimeException("Simulating an error.");
- };
-
- PrometheusRegistry.defaultRegistry.register(failingCollector);
- }
-
- Server server = new Server();
-
- // set port
- ServerConnector connector = new ServerConnector(server);
- connector.setPort(port);
- server.setConnectors(new Connector[] {connector});
-
- // register servlet
- ServletHandler servletHandler = new ServletHandler();
- servletHandler.addServletWithMapping(PrometheusMetricsServlet.class, "/metrics");
- server.setHandler(servletHandler);
-
- System.out.println("Running on http://localhost:" + port + "/metrics");
-
- // run
- server.start();
+ if (args.length != 2) {
+ System.err.println("Usage: java -jar exporter-servlet-jetty-sample.jar ");
+ System.err.println("Where mode is \"success\" or \"error\".");
+ System.exit(1);
}
- private static int parsePortOrExit(String port) {
- try {
- return Integer.parseInt(port);
- } catch (NumberFormatException e) {
- System.err.println("\"" + port + "\": Invalid port number.");
- System.exit(1);
- }
- return 0; // this won't happen
+ int port = parsePortOrExit(args[0]);
+ Mode mode = parseModeOrExit(args[1]);
+
+ Counter counter =
+ Counter.builder()
+ .name("uptime_seconds_total")
+ .help("total number of seconds since this application was started")
+ .unit(Unit.SECONDS)
+ .register();
+ counter.inc(17);
+
+ Info info =
+ Info.builder()
+ .name("integration_test_info")
+ .help("Info metric on this integration test")
+ .labelNames("test_name")
+ .register();
+ info.addLabelValues("exporter-servlet-jetty-sample");
+
+ Gauge gauge =
+ Gauge.builder()
+ .name("temperature_celsius")
+ .help("Temperature in Celsius")
+ .unit(Unit.CELSIUS)
+ .labelNames("location")
+ .register();
+ gauge.labelValues("inside").set(23.0);
+ gauge.labelValues("outside").set(27.0);
+
+ if (mode == Mode.error) {
+ Collector failingCollector =
+ () -> {
+ throw new RuntimeException("Simulating an error.");
+ };
+
+ PrometheusRegistry.defaultRegistry.register(failingCollector);
}
- private static Mode parseModeOrExit(String mode) {
- try {
- return Mode.valueOf(mode);
- } catch (IllegalArgumentException e) {
- System.err.println("\"" + mode + "\": Invalid mode. Legal values are \"success\" and \"error\".");
- System.exit(1);
- }
- return null; // this won't happen
+ Server server = new Server();
+
+ // set port
+ ServerConnector connector = new ServerConnector(server);
+ connector.setPort(port);
+ server.setConnectors(new Connector[] {connector});
+
+ // register servlet
+ ServletHandler servletHandler = new ServletHandler();
+ servletHandler.addServletWithMapping(PrometheusMetricsServlet.class, "/metrics");
+ server.setHandler(servletHandler);
+
+ System.out.println("Running on http://localhost:" + port + "/metrics");
+
+ // run
+ server.start();
+ }
+
+ private static int parsePortOrExit(String port) {
+ try {
+ return Integer.parseInt(port);
+ } catch (NumberFormatException e) {
+ System.err.println("\"" + port + "\": Invalid port number.");
+ System.exit(1);
+ }
+ return 0; // this won't happen
+ }
+
+ private static Mode parseModeOrExit(String mode) {
+ try {
+ return Mode.valueOf(mode);
+ } catch (IllegalArgumentException e) {
+ System.err.println(
+ "\"" + mode + "\": Invalid mode. Legal values are \"success\" and \"error\".");
+ System.exit(1);
}
+ return null; // this won't happen
+ }
}
diff --git a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/src/main/java/io/prometheus/metrics/it/exporter/servlet/tomcat/ExporterServletTomcatSample.java b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/src/main/java/io/prometheus/metrics/it/exporter/servlet/tomcat/ExporterServletTomcatSample.java
index 8d13082b7..ead2ee88f 100644
--- a/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/src/main/java/io/prometheus/metrics/it/exporter/servlet/tomcat/ExporterServletTomcatSample.java
+++ b/integration-tests/it-exporter/it-exporter-servlet-tomcat-sample/src/main/java/io/prometheus/metrics/it/exporter/servlet/tomcat/ExporterServletTomcatSample.java
@@ -6,99 +6,100 @@
import io.prometheus.metrics.exporter.servlet.jakarta.PrometheusMetricsServlet;
import io.prometheus.metrics.model.registry.Collector;
import io.prometheus.metrics.model.registry.PrometheusRegistry;
-import io.prometheus.metrics.model.snapshots.MetricSnapshot;
import io.prometheus.metrics.model.snapshots.Unit;
-import org.apache.catalina.Context;
-import org.apache.catalina.LifecycleException;
-import org.apache.catalina.startup.Tomcat;
-
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
+import org.apache.catalina.Context;
+import org.apache.catalina.LifecycleException;
+import org.apache.catalina.startup.Tomcat;
-/**
- * Sample application using the {@link PrometheusMetricsServlet} in Tomcat.
- */
+/** Sample application using the {@link PrometheusMetricsServlet} in Tomcat. */
public class ExporterServletTomcatSample {
- enum Mode {
- success,
- error
- }
-
- public static void main(String[] args) throws LifecycleException, IOException {
+ enum Mode {
+ success,
+ error
+ }
- if (args.length != 2) {
- System.err.println("Usage: java -jar exporter-servlet-tomcat-sample.jar ");
- System.err.println("Where mode is \"success\" or \"error\".");
- System.exit(1);
- }
+ public static void main(String[] args) throws LifecycleException, IOException {
- int port = parsePortOrExit(args[0]);
- Mode mode = parseModeOrExit(args[1]);
-
- Counter counter = Counter.builder()
- .name("uptime_seconds_total")
- .help("total number of seconds since this application was started")
- .unit(Unit.SECONDS)
- .register();
- counter.inc(17);
-
- Info info = Info.builder()
- .name("integration_test_info")
- .help("Info metric on this integration test")
- .labelNames("test_name")
- .register();
- info.addLabelValues("exporter-servlet-tomcat-sample");
-
- Gauge gauge = Gauge.builder()
- .name("temperature_celsius")
- .help("Temperature in Celsius")
- .unit(Unit.CELSIUS)
- .labelNames("location")
- .register();
- gauge.labelValues("inside").set(23.0);
- gauge.labelValues("outside").set(27.0);
-
- if (mode == Mode.error) {
- Collector failingCollector = () -> {
- throw new RuntimeException("Simulating an error.");
- };
-
- PrometheusRegistry.defaultRegistry.register(failingCollector);
- }
-
- Tomcat tomcat = new Tomcat();
- tomcat.setPort(port);
-
- Path tmpDir = Files.createTempDirectory("exporter-servlet-tomcat-sample-");
- tomcat.setBaseDir(tmpDir.toFile().getAbsolutePath());
- Context ctx = tomcat.addContext("", new File(".").getAbsolutePath());
- Tomcat.addServlet(ctx, "metrics", new PrometheusMetricsServlet());
- ctx.addServletMappingDecoded("/metrics", "metrics");
-
- tomcat.getConnector();
- tomcat.start();
- tomcat.getServer().await();
+ if (args.length != 2) {
+ System.err.println("Usage: java -jar exporter-servlet-tomcat-sample.jar ");
+ System.err.println("Where mode is \"success\" or \"error\".");
+ System.exit(1);
}
- private static int parsePortOrExit(String port) {
- try {
- return Integer.parseInt(port);
- } catch (NumberFormatException e) {
- System.err.println("\"" + port + "\": Invalid port number.");
- System.exit(1);
- }
- return 0; // this won't happen
+ int port = parsePortOrExit(args[0]);
+ Mode mode = parseModeOrExit(args[1]);
+
+ Counter counter =
+ Counter.builder()
+ .name("uptime_seconds_total")
+ .help("total number of seconds since this application was started")
+ .unit(Unit.SECONDS)
+ .register();
+ counter.inc(17);
+
+ Info info =
+ Info.builder()
+ .name("integration_test_info")
+ .help("Info metric on this integration test")
+ .labelNames("test_name")
+ .register();
+ info.addLabelValues("exporter-servlet-tomcat-sample");
+
+ Gauge gauge =
+ Gauge.builder()
+ .name("temperature_celsius")
+ .help("Temperature in Celsius")
+ .unit(Unit.CELSIUS)
+ .labelNames("location")
+ .register();
+ gauge.labelValues("inside").set(23.0);
+ gauge.labelValues("outside").set(27.0);
+
+ if (mode == Mode.error) {
+ Collector failingCollector =
+ () -> {
+ throw new RuntimeException("Simulating an error.");
+ };
+
+ PrometheusRegistry.defaultRegistry.register(failingCollector);
}
- private static Mode parseModeOrExit(String mode) {
- try {
- return Mode.valueOf(mode);
- } catch (IllegalArgumentException e) {
- System.err.println("\"" + mode + "\": Invalid mode. Legal values are \"success\" and \"error\".");
- System.exit(1);
- }
- return null; // this won't happen
+ Tomcat tomcat = new Tomcat();
+ tomcat.setPort(port);
+
+ Path tmpDir = Files.createTempDirectory("exporter-servlet-tomcat-sample-");
+ tomcat.setBaseDir(tmpDir.toFile().getAbsolutePath());
+ Context ctx = tomcat.addContext("", new File(".").getAbsolutePath());
+ Tomcat.addServlet(ctx, "metrics", new PrometheusMetricsServlet());
+ ctx.addServletMappingDecoded("/metrics", "metrics");
+
+ tomcat.getConnector();
+ tomcat.start();
+ tomcat.getServer().await();
+ }
+
+ private static int parsePortOrExit(String port) {
+ try {
+ return Integer.parseInt(port);
+ } catch (NumberFormatException e) {
+ System.err.println("\"" + port + "\": Invalid port number.");
+ System.exit(1);
+ }
+ return 0; // this won't happen
+ }
+
+ private static Mode parseModeOrExit(String mode) {
+ try {
+ return Mode.valueOf(mode);
+ } catch (IllegalArgumentException e) {
+ System.err.println(
+ "\"" + mode + "\": Invalid mode. Legal values are \"success\" and \"error\".");
+ System.exit(1);
}
+ return null; // this won't happen
+ }
}
diff --git a/integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/ExporterIT.java b/integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/ExporterIT.java
index 657b890db..949f71840 100644
--- a/integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/ExporterIT.java
+++ b/integration-tests/it-exporter/it-exporter-test/src/test/java/io/prometheus/metrics/it/exporter/test/ExporterIT.java
@@ -1,17 +1,10 @@
package io.prometheus.metrics.it.exporter.test;
+import static java.nio.charset.StandardCharsets.UTF_8;
+
import io.prometheus.client.it.common.LogConsumer;
import io.prometheus.client.it.common.Volume;
import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_25_3.Metrics;
-import org.apache.commons.io.IOUtils;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.testcontainers.containers.BindMode;
-import org.testcontainers.containers.GenericContainer;
-
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
@@ -26,317 +19,397 @@
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.zip.GZIPInputStream;
-
-import static java.nio.charset.StandardCharsets.UTF_8;
+import org.apache.commons.io.IOUtils;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.testcontainers.containers.BindMode;
+import org.testcontainers.containers.GenericContainer;
@RunWith(Parameterized.class)
public class ExporterIT {
- private final GenericContainer> sampleAppContainer;
- private final Volume sampleAppVolume;
- private final String sampleApp;
+ private final GenericContainer> sampleAppContainer;
+ private final Volume sampleAppVolume;
+ private final String sampleApp;
- @Parameterized.Parameters(name = "{0}")
- public static String[] sampleApps() {
- return new String[]{
- "exporter-httpserver-sample",
- "exporter-servlet-tomcat-sample",
- "exporter-servlet-jetty-sample",
- };
- }
+ @Parameterized.Parameters(name = "{0}")
+ public static String[] sampleApps() {
+ return new String[] {
+ "exporter-httpserver-sample",
+ "exporter-servlet-tomcat-sample",
+ "exporter-servlet-jetty-sample",
+ };
+ }
- public ExporterIT(String sampleApp) throws IOException, URISyntaxException {
- this.sampleApp = sampleApp;
- this.sampleAppVolume = Volume.create("it-exporter")
- .copy("../../it-" + sampleApp + "/target/" + sampleApp + ".jar");
- this.sampleAppContainer = new GenericContainer<>("openjdk:17")
- .withFileSystemBind(sampleAppVolume.getHostPath(), "/app", BindMode.READ_ONLY)
- .withWorkingDirectory("/app")
- .withLogConsumer(LogConsumer.withPrefix(sampleApp))
- .withExposedPorts(9400);
- }
+ public ExporterIT(String sampleApp) throws IOException, URISyntaxException {
+ this.sampleApp = sampleApp;
+ this.sampleAppVolume =
+ Volume.create("it-exporter")
+ .copy("../../it-" + sampleApp + "/target/" + sampleApp + ".jar");
+ this.sampleAppContainer =
+ new GenericContainer<>("openjdk:17")
+ .withFileSystemBind(sampleAppVolume.getHostPath(), "/app", BindMode.READ_ONLY)
+ .withWorkingDirectory("/app")
+ .withLogConsumer(LogConsumer.withPrefix(sampleApp))
+ .withExposedPorts(9400);
+ }
- @After
- public void tearDown() throws IOException {
- sampleAppContainer.stop();
- sampleAppVolume.remove();
- }
+ @After
+ public void tearDown() throws IOException {
+ sampleAppContainer.stop();
+ sampleAppVolume.remove();
+ }
- @Test
- public void testOpenMetricsTextFormat() throws IOException {
- sampleAppContainer
- .withCommand("java", "-jar", "/app/" + sampleApp + ".jar", "9400", "success")
- .start();
- Response response = scrape("GET", "", "Accept", "application/openmetrics-text; version=1.0.0; charset=utf-8");
- Assert.assertEquals(200, response.status);
- assertContentType("application/openmetrics-text; version=1.0.0; charset=utf-8", response.getHeader("Content-Type"));
- Assert.assertNull(response.getHeader("Content-Encoding"));
- Assert.assertNull(response.getHeader("Transfer-Encoding"));
- Assert.assertEquals(Integer.toString(response.body.length), response.getHeader("Content-Length"));
- String bodyString = new String(response.body);
- Assert.assertTrue(bodyString.contains("integration_test_info{test_name=\"" + sampleApp + "\"} 1"));
- Assert.assertTrue(bodyString.contains("temperature_celsius{location=\"inside\"} 23.0"));
- Assert.assertTrue(bodyString.contains("temperature_celsius{location=\"outside\"} 27.0"));
- Assert.assertTrue(bodyString.contains("uptime_seconds_total 17.0"));
- // OpenMetrics text format has a UNIT.
- Assert.assertTrue(bodyString.contains("# UNIT uptime_seconds seconds"));
- }
+ @Test
+ public void testOpenMetricsTextFormat() throws IOException {
+ sampleAppContainer
+ .withCommand("java", "-jar", "/app/" + sampleApp + ".jar", "9400", "success")
+ .start();
+ Response response =
+ scrape("GET", "", "Accept", "application/openmetrics-text; version=1.0.0; charset=utf-8");
+ Assert.assertEquals(200, response.status);
+ assertContentType(
+ "application/openmetrics-text; version=1.0.0; charset=utf-8",
+ response.getHeader("Content-Type"));
+ Assert.assertNull(response.getHeader("Content-Encoding"));
+ Assert.assertNull(response.getHeader("Transfer-Encoding"));
+ Assert.assertEquals(
+ Integer.toString(response.body.length), response.getHeader("Content-Length"));
+ String bodyString = new String(response.body);
+ Assert.assertTrue(
+ bodyString.contains("integration_test_info{test_name=\"" + sampleApp + "\"} 1"));
+ Assert.assertTrue(bodyString.contains("temperature_celsius{location=\"inside\"} 23.0"));
+ Assert.assertTrue(bodyString.contains("temperature_celsius{location=\"outside\"} 27.0"));
+ Assert.assertTrue(bodyString.contains("uptime_seconds_total 17.0"));
+ // OpenMetrics text format has a UNIT.
+ Assert.assertTrue(bodyString.contains("# UNIT uptime_seconds seconds"));
+ }
- @Test
- public void testPrometheusTextFormat() throws IOException {
- sampleAppContainer
- .withCommand("java", "-jar", "/app/" + sampleApp + ".jar", "9400", "success")
- .start();
- Response response = scrape("GET", "");
- Assert.assertEquals(200, response.status);
- assertContentType("text/plain; version=0.0.4; charset=utf-8", response.getHeader("Content-Type"));
- Assert.assertNull(response.getHeader("Content-Encoding"));
- Assert.assertNull(response.getHeader("Transfer-Encoding"));
- Assert.assertEquals(Integer.toString(response.body.length), response.getHeader("Content-Length"));
- String bodyString = new String(response.body);
- Assert.assertTrue(bodyString.contains("integration_test_info{test_name=\"" + sampleApp + "\"} 1"));
- Assert.assertTrue(bodyString.contains("temperature_celsius{location=\"inside\"} 23.0"));
- Assert.assertTrue(bodyString.contains("temperature_celsius{location=\"outside\"} 27.0"));
- Assert.assertTrue(bodyString.contains("uptime_seconds_total 17.0"));
- // Prometheus text format does not have a UNIT.
- Assert.assertFalse(bodyString.contains("# UNIT uptime_seconds seconds"));
- }
+ @Test
+ public void testPrometheusTextFormat() throws IOException {
+ sampleAppContainer
+ .withCommand("java", "-jar", "/app/" + sampleApp + ".jar", "9400", "success")
+ .start();
+ Response response = scrape("GET", "");
+ Assert.assertEquals(200, response.status);
+ assertContentType(
+ "text/plain; version=0.0.4; charset=utf-8", response.getHeader("Content-Type"));
+ Assert.assertNull(response.getHeader("Content-Encoding"));
+ Assert.assertNull(response.getHeader("Transfer-Encoding"));
+ Assert.assertEquals(
+ Integer.toString(response.body.length), response.getHeader("Content-Length"));
+ String bodyString = new String(response.body);
+ Assert.assertTrue(
+ bodyString.contains("integration_test_info{test_name=\"" + sampleApp + "\"} 1"));
+ Assert.assertTrue(bodyString.contains("temperature_celsius{location=\"inside\"} 23.0"));
+ Assert.assertTrue(bodyString.contains("temperature_celsius{location=\"outside\"} 27.0"));
+ Assert.assertTrue(bodyString.contains("uptime_seconds_total 17.0"));
+ // Prometheus text format does not have a UNIT.
+ Assert.assertFalse(bodyString.contains("# UNIT uptime_seconds seconds"));
+ }
- @Test
- public void testPrometheusProtobufFormat() throws IOException {
- sampleAppContainer
- .withCommand("java", "-jar", "/app/" + sampleApp + ".jar", "9400", "success")
- .start();
- Response response = scrape("GET", "", "Accept", "application/vnd.google.protobuf; proto=io.prometheus.client.MetricFamily; encoding=delimited");
- Assert.assertEquals(200, response.status);
- assertContentType("application/vnd.google.protobuf; proto=io.prometheus.client.MetricFamily; encoding=delimited", response.getHeader("Content-Type"));
- Assert.assertNull(response.getHeader("Content-Encoding"));
- Assert.assertNull(response.getHeader("Transfer-Encoding"));
- Assert.assertEquals(Integer.toString(response.body.length), response.getHeader("Content-Length"));
- List metrics = new ArrayList<>();
- InputStream in = new ByteArrayInputStream(response.body);
- while (in.available() > 0) {
- metrics.add(Metrics.MetricFamily.parseDelimitedFrom(in));
- }
- Assert.assertEquals(3, metrics.size());
- // metrics are sorted by name
- Assert.assertEquals("integration_test_info", metrics.get(0).getName());
- Assert.assertEquals("temperature_celsius", metrics.get(1).getName());
- Assert.assertEquals("uptime_seconds_total", metrics.get(2).getName());
+ @Test
+ public void testPrometheusProtobufFormat() throws IOException {
+ sampleAppContainer
+ .withCommand("java", "-jar", "/app/" + sampleApp + ".jar", "9400", "success")
+ .start();
+ Response response =
+ scrape(
+ "GET",
+ "",
+ "Accept",
+ "application/vnd.google.protobuf; proto=io.prometheus.client.MetricFamily; encoding=delimited");
+ Assert.assertEquals(200, response.status);
+ assertContentType(
+ "application/vnd.google.protobuf; proto=io.prometheus.client.MetricFamily; encoding=delimited",
+ response.getHeader("Content-Type"));
+ Assert.assertNull(response.getHeader("Content-Encoding"));
+ Assert.assertNull(response.getHeader("Transfer-Encoding"));
+ Assert.assertEquals(
+ Integer.toString(response.body.length), response.getHeader("Content-Length"));
+ List metrics = new ArrayList<>();
+ InputStream in = new ByteArrayInputStream(response.body);
+ while (in.available() > 0) {
+ metrics.add(Metrics.MetricFamily.parseDelimitedFrom(in));
}
+ Assert.assertEquals(3, metrics.size());
+ // metrics are sorted by name
+ Assert.assertEquals("integration_test_info", metrics.get(0).getName());
+ Assert.assertEquals("temperature_celsius", metrics.get(1).getName());
+ Assert.assertEquals("uptime_seconds_total", metrics.get(2).getName());
+ }
- @Test
- public void testCompression() throws IOException {
- sampleAppContainer
- .withCommand("java", "-jar", "/app/" + sampleApp + ".jar", "9400", "success")
- .start();
- Response response = scrape("GET", "",
- "Accept", "application/openmetrics-text; version=1.0.0; charset=utf-8",
- "Accept-Encoding", "gzip");
- Assert.assertEquals(200, response.status);
- Assert.assertEquals("gzip", response.getHeader("Content-Encoding"));
- if (response.getHeader("Content-Length") != null) {
- // The servlet container might set a content length as the body is very small.
- Assert.assertEquals(Integer.toString(response.body.length), response.getHeader("Content-Length"));
- Assert.assertNull(response.getHeader("Transfer-Encoding"));
- } else {
- // If no content length is set, transfer-encoding chunked must be used.
- Assert.assertEquals("chunked", response.getHeader("Transfer-Encoding"));
- }
- assertContentType("application/openmetrics-text; version=1.0.0; charset=utf-8", response.getHeader("Content-Type"));
- String body = new String(IOUtils.toByteArray(new GZIPInputStream(new ByteArrayInputStream(response.body))), UTF_8);
- Assert.assertTrue(body.contains("uptime_seconds_total 17.0"));
+ @Test
+ public void testCompression() throws IOException {
+ sampleAppContainer
+ .withCommand("java", "-jar", "/app/" + sampleApp + ".jar", "9400", "success")
+ .start();
+ Response response =
+ scrape(
+ "GET",
+ "",
+ "Accept",
+ "application/openmetrics-text; version=1.0.0; charset=utf-8",
+ "Accept-Encoding",
+ "gzip");
+ Assert.assertEquals(200, response.status);
+ Assert.assertEquals("gzip", response.getHeader("Content-Encoding"));
+ if (response.getHeader("Content-Length") != null) {
+ // The servlet container might set a content length as the body is very small.
+ Assert.assertEquals(
+ Integer.toString(response.body.length), response.getHeader("Content-Length"));
+ Assert.assertNull(response.getHeader("Transfer-Encoding"));
+ } else {
+ // If no content length is set, transfer-encoding chunked must be used.
+ Assert.assertEquals("chunked", response.getHeader("Transfer-Encoding"));
}
+ assertContentType(
+ "application/openmetrics-text; version=1.0.0; charset=utf-8",
+ response.getHeader("Content-Type"));
+ String body =
+ new String(
+ IOUtils.toByteArray(new GZIPInputStream(new ByteArrayInputStream(response.body))),
+ UTF_8);
+ Assert.assertTrue(body.contains("uptime_seconds_total 17.0"));
+ }
- @Test
- public void testErrorHandling() throws IOException {
- sampleAppContainer
- .withCommand("java", "-jar", "/app/" + sampleApp + ".jar", "9400", "error")
- .start();
- Response response = scrape("GET", "");
- Assert.assertEquals(500, response.status);
- Assert.assertTrue(new String(response.body, UTF_8).contains("Simulating an error."));
- }
+ @Test
+ public void testErrorHandling() throws IOException {
+ sampleAppContainer
+ .withCommand("java", "-jar", "/app/" + sampleApp + ".jar", "9400", "error")
+ .start();
+ Response response = scrape("GET", "");
+ Assert.assertEquals(500, response.status);
+ Assert.assertTrue(new String(response.body, UTF_8).contains("Simulating an error."));
+ }
- @Test
- public void testHeadRequest() throws IOException {
- sampleAppContainer
- .withCommand("java", "-jar", "/app/" + sampleApp + ".jar", "9400", "success")
- .start();
- Response fullResponse = scrape("GET", "");
- int size = fullResponse.body.length;
- Assert.assertTrue(size > 0);
- Response headResponse = scrape("HEAD", "");
- Assert.assertEquals(200, headResponse.status);
- Assert.assertEquals(Integer.toString(size), headResponse.getHeader("Content-Length"));
- Assert.assertEquals(0, headResponse.body.length);
- }
+ @Test
+ public void testHeadRequest() throws IOException {
+ sampleAppContainer
+ .withCommand("java", "-jar", "/app/" + sampleApp + ".jar", "9400", "success")
+ .start();
+ Response fullResponse = scrape("GET", "");
+ int size = fullResponse.body.length;
+ Assert.assertTrue(size > 0);
+ Response headResponse = scrape("HEAD", "");
+ Assert.assertEquals(200, headResponse.status);
+ Assert.assertEquals(Integer.toString(size), headResponse.getHeader("Content-Length"));
+ Assert.assertEquals(0, headResponse.body.length);
+ }
- @Test
- public void testDebug() throws IOException {
- sampleAppContainer
- .withCommand("java", "-jar", "/app/" + sampleApp + ".jar", "9400", "success")
- .start();
- Response response = scrape("GET", "debug=openmetrics");
- Assert.assertEquals(200, response.status);
- assertContentType("text/plain; charset=utf-8", response.getHeader("Content-Type"));
- String bodyString = new String(response.body, UTF_8);
- Assert.assertTrue(bodyString.contains("uptime_seconds_total 17.0"));
- Assert.assertTrue(bodyString.contains("# UNIT uptime_seconds seconds"));
- }
+ @Test
+ public void testDebug() throws IOException {
+ sampleAppContainer
+ .withCommand("java", "-jar", "/app/" + sampleApp + ".jar", "9400", "success")
+ .start();
+ Response response = scrape("GET", "debug=openmetrics");
+ Assert.assertEquals(200, response.status);
+ assertContentType("text/plain; charset=utf-8", response.getHeader("Content-Type"));
+ String bodyString = new String(response.body, UTF_8);
+ Assert.assertTrue(bodyString.contains("uptime_seconds_total 17.0"));
+ Assert.assertTrue(bodyString.contains("# UNIT uptime_seconds seconds"));
+ }
- @Test
- public void testNameFilter() throws IOException {
- sampleAppContainer
- .withCommand("java", "-jar", "/app/" + sampleApp + ".jar", "9400", "success")
- .start();
- Response response = scrape("GET", nameParam("integration_test_info") + "&" + nameParam("uptime_seconds_total"),
- "Accept", "application/openmetrics-text; version=1.0.0; charset=utf-8");
- Assert.assertEquals(200, response.status);
- assertContentType("application/openmetrics-text; version=1.0.0; charset=utf-8", response.getHeader("Content-Type"));
- String bodyString = new String(response.body, UTF_8);
- Assert.assertTrue(bodyString.contains("integration_test_info{test_name=\"" + sampleApp + "\"} 1"));
- Assert.assertTrue(bodyString.contains("uptime_seconds_total 17.0"));
- Assert.assertFalse(bodyString.contains("temperature_celsius"));
- }
+ @Test
+ public void testNameFilter() throws IOException {
+ sampleAppContainer
+ .withCommand("java", "-jar", "/app/" + sampleApp + ".jar", "9400", "success")
+ .start();
+ Response response =
+ scrape(
+ "GET",
+ nameParam("integration_test_info") + "&" + nameParam("uptime_seconds_total"),
+ "Accept",
+ "application/openmetrics-text; version=1.0.0; charset=utf-8");
+ Assert.assertEquals(200, response.status);
+ assertContentType(
+ "application/openmetrics-text; version=1.0.0; charset=utf-8",
+ response.getHeader("Content-Type"));
+ String bodyString = new String(response.body, UTF_8);
+ Assert.assertTrue(
+ bodyString.contains("integration_test_info{test_name=\"" + sampleApp + "\"} 1"));
+ Assert.assertTrue(bodyString.contains("uptime_seconds_total 17.0"));
+ Assert.assertFalse(bodyString.contains("temperature_celsius"));
+ }
- @Test
- public void testEmptyResponseOpenMetrics() throws IOException {
- sampleAppContainer
- .withCommand("java", "-jar", "/app/" + sampleApp + ".jar", "9400", "success")
- .start();
- Response response = scrape("GET", nameParam("none_existing"),
- "Accept", "application/openmetrics-text; version=1.0.0; charset=utf-8");
- Assert.assertEquals(200, response.status);
- assertContentType("application/openmetrics-text; version=1.0.0; charset=utf-8", response.getHeader("Content-Type"));
- Assert.assertEquals(Integer.toString(response.body.length), response.getHeader("Content-Length"));
- Assert.assertEquals("# EOF\n", new String(response.body, UTF_8));
- }
+ @Test
+ public void testEmptyResponseOpenMetrics() throws IOException {
+ sampleAppContainer
+ .withCommand("java", "-jar", "/app/" + sampleApp + ".jar", "9400", "success")
+ .start();
+ Response response =
+ scrape(
+ "GET",
+ nameParam("none_existing"),
+ "Accept",
+ "application/openmetrics-text; version=1.0.0; charset=utf-8");
+ Assert.assertEquals(200, response.status);
+ assertContentType(
+ "application/openmetrics-text; version=1.0.0; charset=utf-8",
+ response.getHeader("Content-Type"));
+ Assert.assertEquals(
+ Integer.toString(response.body.length), response.getHeader("Content-Length"));
+ Assert.assertEquals("# EOF\n", new String(response.body, UTF_8));
+ }
- @Test
- public void testEmptyResponseText() throws IOException {
- sampleAppContainer
- .withCommand("java", "-jar", "/app/" + sampleApp + ".jar", "9400", "success")
- .start();
- Response response = scrape("GET", nameParam("none_existing"));
- Assert.assertEquals(200, response.status);
- assertContentType("text/plain; version=0.0.4; charset=utf-8", response.getHeader("Content-Type"));
- if (response.getHeader("Content-Length") != null) { // HTTPServer does not send a zero content length, which is ok
- Assert.assertEquals("0", response.getHeader("Content-Length"));
- }
- Assert.assertEquals(0, response.body.length);
+ @Test
+ public void testEmptyResponseText() throws IOException {
+ sampleAppContainer
+ .withCommand("java", "-jar", "/app/" + sampleApp + ".jar", "9400", "success")
+ .start();
+ Response response = scrape("GET", nameParam("none_existing"));
+ Assert.assertEquals(200, response.status);
+ assertContentType(
+ "text/plain; version=0.0.4; charset=utf-8", response.getHeader("Content-Type"));
+ if (response.getHeader("Content-Length")
+ != null) { // HTTPServer does not send a zero content length, which is ok
+ Assert.assertEquals("0", response.getHeader("Content-Length"));
}
+ Assert.assertEquals(0, response.body.length);
+ }
- @Test
- public void testEmptyResponseProtobuf() throws IOException {
- sampleAppContainer
- .withCommand("java", "-jar", "/app/" + sampleApp + ".jar", "9400", "success")
- .start();
- Response response = scrape("GET", nameParam("none_existing"),
- "Accept", "application/vnd.google.protobuf; proto=io.prometheus.client.MetricFamily; encoding=delimited");
- Assert.assertEquals(200, response.status);
- assertContentType("application/vnd.google.protobuf; proto=io.prometheus.client.MetricFamily; encoding=delimited", response.getHeader("Content-Type"));
- Assert.assertEquals(0, response.body.length);
- }
+ @Test
+ public void testEmptyResponseProtobuf() throws IOException {
+ sampleAppContainer
+ .withCommand("java", "-jar", "/app/" + sampleApp + ".jar", "9400", "success")
+ .start();
+ Response response =
+ scrape(
+ "GET",
+ nameParam("none_existing"),
+ "Accept",
+ "application/vnd.google.protobuf; proto=io.prometheus.client.MetricFamily; encoding=delimited");
+ Assert.assertEquals(200, response.status);
+ assertContentType(
+ "application/vnd.google.protobuf; proto=io.prometheus.client.MetricFamily; encoding=delimited",
+ response.getHeader("Content-Type"));
+ Assert.assertEquals(0, response.body.length);
+ }
- @Test
- public void testEmptyResponseGzipOpenMetrics() throws IOException {
- sampleAppContainer
- .withCommand("java", "-jar", "/app/" + sampleApp + ".jar", "9400", "success")
- .start();
- Response response = scrape("GET", nameParam("none_existing"),
- "Accept", "application/openmetrics-text; version=1.0.0; charset=utf-8",
- "Accept-Encoding", "gzip");
- Assert.assertEquals(200, response.status);
- Assert.assertEquals("gzip", response.getHeader("Content-Encoding"));
- String body = new String(IOUtils.toByteArray(new GZIPInputStream(new ByteArrayInputStream(response.body))), UTF_8);
- Assert.assertEquals("# EOF\n", body);
- }
+ @Test
+ public void testEmptyResponseGzipOpenMetrics() throws IOException {
+ sampleAppContainer
+ .withCommand("java", "-jar", "/app/" + sampleApp + ".jar", "9400", "success")
+ .start();
+ Response response =
+ scrape(
+ "GET",
+ nameParam("none_existing"),
+ "Accept",
+ "application/openmetrics-text; version=1.0.0; charset=utf-8",
+ "Accept-Encoding",
+ "gzip");
+ Assert.assertEquals(200, response.status);
+ Assert.assertEquals("gzip", response.getHeader("Content-Encoding"));
+ String body =
+ new String(
+ IOUtils.toByteArray(new GZIPInputStream(new ByteArrayInputStream(response.body))),
+ UTF_8);
+ Assert.assertEquals("# EOF\n", body);
+ }
- @Test
- public void testEmptyResponseGzipText() throws IOException {
- sampleAppContainer
- .withCommand("java", "-jar", "/app/" + sampleApp + ".jar", "9400", "success")
- .start();
- Response response = scrape("GET", nameParam("none_existing"),
- "Accept-Encoding", "gzip");
- Assert.assertEquals(200, response.status);
- Assert.assertEquals("gzip", response.getHeader("Content-Encoding"));
- String body = new String(IOUtils.toByteArray(new GZIPInputStream(new ByteArrayInputStream(response.body))), UTF_8);
- Assert.assertEquals(0, body.length());
- }
+ @Test
+ public void testEmptyResponseGzipText() throws IOException {
+ sampleAppContainer
+ .withCommand("java", "-jar", "/app/" + sampleApp + ".jar", "9400", "success")
+ .start();
+ Response response = scrape("GET", nameParam("none_existing"), "Accept-Encoding", "gzip");
+ Assert.assertEquals(200, response.status);
+ Assert.assertEquals("gzip", response.getHeader("Content-Encoding"));
+ String body =
+ new String(
+ IOUtils.toByteArray(new GZIPInputStream(new ByteArrayInputStream(response.body))),
+ UTF_8);
+ Assert.assertEquals(0, body.length());
+ }
- private String nameParam(String name) throws UnsupportedEncodingException {
- return URLEncoder.encode("name[]", UTF_8.name()) + "=" + URLEncoder.encode(name, UTF_8.name());
- }
+ private String nameParam(String name) throws UnsupportedEncodingException {
+ return URLEncoder.encode("name[]", UTF_8.name()) + "=" + URLEncoder.encode(name, UTF_8.name());
+ }
- @Test
- public void testDebugUnknown() throws IOException {
- sampleAppContainer
- .withCommand("java", "-jar", "/app/" + sampleApp + ".jar", "9400", "success")
- .start();
- Response response = scrape("GET", "debug=unknown");
- Assert.assertEquals(500, response.status);
- assertContentType("text/plain; charset=utf-8", response.getHeader("Content-Type"));
- }
+ @Test
+ public void testDebugUnknown() throws IOException {
+ sampleAppContainer
+ .withCommand("java", "-jar", "/app/" + sampleApp + ".jar", "9400", "success")
+ .start();
+ Response response = scrape("GET", "debug=unknown");
+ Assert.assertEquals(500, response.status);
+ assertContentType("text/plain; charset=utf-8", response.getHeader("Content-Type"));
+ }
- private void assertContentType(String expected, String actual) {
- if (!expected.replace(" ", "").equals(actual)) {
- Assert.assertEquals(expected, actual);
- }
+ private void assertContentType(String expected, String actual) {
+ if (!expected.replace(" ", "").equals(actual)) {
+ Assert.assertEquals(expected, actual);
}
+ }
- private Response scrape(String method, String queryString, String... requestHeaders) throws IOException {
- long timeoutMillis = TimeUnit.SECONDS.toMillis(5);
- URL url = new URL("http://localhost:" + sampleAppContainer.getMappedPort(9400) + "/metrics?" + queryString);
- HttpURLConnection con = (HttpURLConnection) url.openConnection();
- con.setRequestMethod(method);
- for (int i = 0; i < requestHeaders.length; i += 2) {
- con.setRequestProperty(requestHeaders[i], requestHeaders[i + 1]);
- }
- long start = System.currentTimeMillis();
- Exception exception = null;
- while (System.currentTimeMillis() - start < timeoutMillis) {
- try {
- if (con.getResponseCode() == 200) {
- return new Response(con.getResponseCode(), con.getHeaderFields(), IOUtils.toByteArray(con.getInputStream()));
- } else {
- return new Response(con.getResponseCode(), con.getHeaderFields(), IOUtils.toByteArray(con.getErrorStream()));
- }
- } catch (Exception e) {
- exception = e;
- try {
- Thread.sleep(100);
- } catch (InterruptedException ignored) {
- }
- }
+ private Response scrape(String method, String queryString, String... requestHeaders)
+ throws IOException {
+ long timeoutMillis = TimeUnit.SECONDS.toMillis(5);
+ URL url =
+ new URL(
+ "http://localhost:"
+ + sampleAppContainer.getMappedPort(9400)
+ + "/metrics?"
+ + queryString);
+ HttpURLConnection con = (HttpURLConnection) url.openConnection();
+ con.setRequestMethod(method);
+ for (int i = 0; i < requestHeaders.length; i += 2) {
+ con.setRequestProperty(requestHeaders[i], requestHeaders[i + 1]);
+ }
+ long start = System.currentTimeMillis();
+ Exception exception = null;
+ while (System.currentTimeMillis() - start < timeoutMillis) {
+ try {
+ if (con.getResponseCode() == 200) {
+ return new Response(
+ con.getResponseCode(),
+ con.getHeaderFields(),
+ IOUtils.toByteArray(con.getInputStream()));
+ } else {
+ return new Response(
+ con.getResponseCode(),
+ con.getHeaderFields(),
+ IOUtils.toByteArray(con.getErrorStream()));
}
- if (exception != null) {
- exception.printStackTrace();
+ } catch (Exception e) {
+ exception = e;
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException ignored) {
}
- Assert.fail("timeout while getting metrics from " + url);
- return null; // will not happen
+ }
+ }
+ if (exception != null) {
+ exception.printStackTrace();
}
+ Assert.fail("timeout while getting metrics from " + url);
+ return null; // will not happen
+ }
- private static class Response {
- private final int status;
- private final Map headers;
- private final byte[] body;
+ private static class Response {
+ private final int status;
+ private final Map headers;
+ private final byte[] body;
- private Response(int status, Map> headers, byte[] body) {
- this.status = status;
- this.headers = new HashMap<>(headers.size());
- this.body = body;
- for (Map.Entry> entry : headers.entrySet()) {
- if (entry.getKey() != null) { // HttpUrlConnection uses pseudo key "null" for the status line
- this.headers.put(entry.getKey().toLowerCase(), entry.getValue().get(0));
- }
- }
+ private Response(int status, Map> headers, byte[] body) {
+ this.status = status;
+ this.headers = new HashMap<>(headers.size());
+ this.body = body;
+ for (Map.Entry> entry : headers.entrySet()) {
+ if (entry.getKey()
+ != null) { // HttpUrlConnection uses pseudo key "null" for the status line
+ this.headers.put(entry.getKey().toLowerCase(), entry.getValue().get(0));
}
+ }
+ }
- private String getHeader(String name) {
- // HTTP headers are case-insensitive
- return headers.get(name.toLowerCase());
- }
+ private String getHeader(String name) {
+ // HTTP headers are case-insensitive
+ return headers.get(name.toLowerCase());
}
+ }
}
diff --git a/integration-tests/it-pushgateway/src/main/java/io/prometheus/metrics/it/pushgateway/PushGatewayTestApp.java b/integration-tests/it-pushgateway/src/main/java/io/prometheus/metrics/it/pushgateway/PushGatewayTestApp.java
index 69ef63081..6376b03fb 100644
--- a/integration-tests/it-pushgateway/src/main/java/io/prometheus/metrics/it/pushgateway/PushGatewayTestApp.java
+++ b/integration-tests/it-pushgateway/src/main/java/io/prometheus/metrics/it/pushgateway/PushGatewayTestApp.java
@@ -1,131 +1,126 @@
package io.prometheus.metrics.it.pushgateway;
+import static io.prometheus.metrics.exporter.pushgateway.Scheme.HTTPS;
+
import io.prometheus.metrics.core.metrics.Gauge;
import io.prometheus.metrics.core.metrics.Histogram;
import io.prometheus.metrics.exporter.pushgateway.Format;
import io.prometheus.metrics.exporter.pushgateway.HttpConnectionFactory;
import io.prometheus.metrics.exporter.pushgateway.PushGateway;
import io.prometheus.metrics.model.snapshots.Unit;
-
-import javax.net.ssl.HttpsURLConnection;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.TrustManager;
-import javax.net.ssl.X509TrustManager;
import java.io.IOException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
-import static io.prometheus.metrics.exporter.pushgateway.Scheme.HTTPS;
-
-/**
- * Example application using the {@link PushGateway}.
- */
+/** Example application using the {@link PushGateway}. */
public class PushGatewayTestApp {
- public static void main(String[] args) throws IOException {
- if (args.length != 1) {
- System.err.println("Usage: java -jar pushgateway-test-app.jar ");
- System.exit(-1);
- }
- switch (args[0]) {
- case "simple":
- runSimpleTest();
- break;
- case "textFormat":
- runTextFormatTest();
- break;
- case "basicauth":
- runBasicAuthTest();
- break;
- case "ssl":
- runSslTest();
- break;
- default:
- System.err.println(args[0] + ": Not implemented.");
- System.exit(-1);
- }
+ public static void main(String[] args) throws IOException {
+ if (args.length != 1) {
+ System.err.println("Usage: java -jar pushgateway-test-app.jar ");
+ System.exit(-1);
}
-
- private static void runSimpleTest() throws IOException {
- makeMetrics();
- PushGateway pg = PushGateway.builder().build();
- System.out.println("Pushing metrics...");
- pg.push();
- System.out.println("Push successful.");
+ switch (args[0]) {
+ case "simple":
+ runSimpleTest();
+ break;
+ case "textFormat":
+ runTextFormatTest();
+ break;
+ case "basicauth":
+ runBasicAuthTest();
+ break;
+ case "ssl":
+ runSslTest();
+ break;
+ default:
+ System.err.println(args[0] + ": Not implemented.");
+ System.exit(-1);
}
+ }
- private static void runTextFormatTest() throws IOException {
- makeMetrics();
- PushGateway pg = PushGateway.builder().format(Format.PROMETHEUS_TEXT).build();
- System.out.println("Pushing metrics...");
- pg.push();
- System.out.println("Push successful.");
- }
+ private static void runSimpleTest() throws IOException {
+ makeMetrics();
+ PushGateway pg = PushGateway.builder().build();
+ System.out.println("Pushing metrics...");
+ pg.push();
+ System.out.println("Push successful.");
+ }
- private static void runBasicAuthTest() throws IOException {
- makeMetrics();
- PushGateway pg = PushGateway.builder()
- .basicAuth("my_user", "secret_password")
- .build();
- System.out.println("Pushing metrics...");
- pg.push();
- System.out.println("Push successful.");
- }
+ private static void runTextFormatTest() throws IOException {
+ makeMetrics();
+ PushGateway pg = PushGateway.builder().format(Format.PROMETHEUS_TEXT).build();
+ System.out.println("Pushing metrics...");
+ pg.push();
+ System.out.println("Push successful.");
+ }
- private static void runSslTest() throws IOException {
- makeMetrics();
- PushGateway pg = PushGateway.builder()
- .scheme(HTTPS)
- .connectionFactory(insecureConnectionFactory)
- .build();
- System.out.println("Pushing metrics...");
- pg.push();
- System.out.println("Push successful.");
- }
+ private static void runBasicAuthTest() throws IOException {
+ makeMetrics();
+ PushGateway pg = PushGateway.builder().basicAuth("my_user", "secret_password").build();
+ System.out.println("Pushing metrics...");
+ pg.push();
+ System.out.println("Push successful.");
+ }
+
+ private static void runSslTest() throws IOException {
+ makeMetrics();
+ PushGateway pg =
+ PushGateway.builder().scheme(HTTPS).connectionFactory(insecureConnectionFactory).build();
+ System.out.println("Pushing metrics...");
+ pg.push();
+ System.out.println("Push successful.");
+ }
- static TrustManager insecureTrustManager = new X509TrustManager() {
+ static TrustManager insecureTrustManager =
+ new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
- return null;
+ return null;
}
@Override
- public void checkClientTrusted(X509Certificate[] chain, String authType) {
- }
+ public void checkClientTrusted(X509Certificate[] chain, String authType) {}
@Override
- public void checkServerTrusted(X509Certificate[] chain, String authType) {
- }
- };
+ public void checkServerTrusted(X509Certificate[] chain, String authType) {}
+ };
- static HttpConnectionFactory insecureConnectionFactory = url -> {
+ static HttpConnectionFactory insecureConnectionFactory =
+ url -> {
try {
- SSLContext sslContext = SSLContext.getInstance("TLS");
- sslContext.init(null, new TrustManager[]{insecureTrustManager}, null);
- SSLContext.setDefault(sslContext);
+ SSLContext sslContext = SSLContext.getInstance("TLS");
+ sslContext.init(null, new TrustManager[] {insecureTrustManager}, null);
+ SSLContext.setDefault(sslContext);
- HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
- connection.setHostnameVerifier((hostname, session) -> true);
- return connection;
+ HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
+ connection.setHostnameVerifier((hostname, session) -> true);
+ return connection;
} catch (NoSuchAlgorithmException | KeyManagementException e) {
- throw new RuntimeException(e);
+ throw new RuntimeException(e);
}
- };
+ };
- private static void makeMetrics() {
- Histogram sizes = Histogram.builder()
- .name("file_sizes_bytes")
- .classicUpperBounds(256, 512, 1024, 2048)
- .unit(Unit.BYTES)
- .register();
- sizes.observe(513);
- sizes.observe(814);
- sizes.observe(1553);
- Gauge duration = Gauge.builder()
- .name("my_batch_job_duration_seconds")
- .help("Duration of my batch job in seconds.")
- .unit(Unit.SECONDS)
- .register();
- duration.set(0.5);
- }
+ private static void makeMetrics() {
+ Histogram sizes =
+ Histogram.builder()
+ .name("file_sizes_bytes")
+ .classicUpperBounds(256, 512, 1024, 2048)
+ .unit(Unit.BYTES)
+ .register();
+ sizes.observe(513);
+ sizes.observe(814);
+ sizes.observe(1553);
+ Gauge duration =
+ Gauge.builder()
+ .name("my_batch_job_duration_seconds")
+ .help("Duration of my batch job in seconds.")
+ .unit(Unit.SECONDS)
+ .register();
+ duration.set(0.5);
+ }
}
diff --git a/integration-tests/it-pushgateway/src/test/java/io/prometheus/metrics/it/pushgateway/PushGatewayIT.java b/integration-tests/it-pushgateway/src/test/java/io/prometheus/metrics/it/pushgateway/PushGatewayIT.java
index 6b89a8c58..7e1198a55 100644
--- a/integration-tests/it-pushgateway/src/test/java/io/prometheus/metrics/it/pushgateway/PushGatewayIT.java
+++ b/integration-tests/it-pushgateway/src/test/java/io/prometheus/metrics/it/pushgateway/PushGatewayIT.java
@@ -6,6 +6,9 @@
import com.squareup.okhttp.*;
import io.prometheus.client.it.common.LogConsumer;
import io.prometheus.client.it.common.Volume;
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.util.concurrent.TimeUnit;
import net.minidev.json.JSONArray;
import org.junit.After;
import org.junit.Assert;
@@ -17,212 +20,247 @@
import org.testcontainers.containers.wait.strategy.Wait;
import org.testcontainers.utility.MountableFile;
-import java.io.IOException;
-import java.net.URISyntaxException;
-import java.util.concurrent.TimeUnit;
-
public class PushGatewayIT {
- private GenericContainer> sampleAppContainer;
- private GenericContainer> pushGatewayContainer;
- private GenericContainer> prometheusContainer;
- private Volume sampleAppVolume;
-
- @Before
- public void setUp() throws IOException, URISyntaxException {
- Network network = Network.newNetwork();
- sampleAppVolume = Volume.create("it-pushgateway")
- .copy("pushgateway-test-app.jar");
- pushGatewayContainer = new GenericContainer<>("prom/pushgateway:v1.8.0")
- .withExposedPorts(9091)
- .withNetwork(network)
- .withNetworkAliases("pushgateway")
- .withLogConsumer(LogConsumer.withPrefix("pushgateway"))
- .waitingFor(Wait.forListeningPort());
- sampleAppContainer = new GenericContainer<>("openjdk:17")
- .withFileSystemBind(sampleAppVolume.getHostPath(), "/app", BindMode.READ_ONLY)
- .withNetwork(network)
- .withWorkingDirectory("/app")
- .dependsOn(pushGatewayContainer)
- .withLogConsumer(LogConsumer.withPrefix("test-app"));
- prometheusContainer = new GenericContainer<>("prom/prometheus:v2.51.2")
- .withNetwork(network)
- .dependsOn(pushGatewayContainer)
- .withExposedPorts(9090)
- .withLogConsumer(LogConsumer.withPrefix("prometheus"));
- }
+ private GenericContainer> sampleAppContainer;
+ private GenericContainer> pushGatewayContainer;
+ private GenericContainer> prometheusContainer;
+ private Volume sampleAppVolume;
- @After
- public void tearDown() throws IOException {
- prometheusContainer.stop();
- pushGatewayContainer.stop();
- sampleAppContainer.stop();
- sampleAppVolume.remove();
- }
+ @Before
+ public void setUp() throws IOException, URISyntaxException {
+ Network network = Network.newNetwork();
+ sampleAppVolume = Volume.create("it-pushgateway").copy("pushgateway-test-app.jar");
+ pushGatewayContainer =
+ new GenericContainer<>("prom/pushgateway:v1.8.0")
+ .withExposedPorts(9091)
+ .withNetwork(network)
+ .withNetworkAliases("pushgateway")
+ .withLogConsumer(LogConsumer.withPrefix("pushgateway"))
+ .waitingFor(Wait.forListeningPort());
+ sampleAppContainer =
+ new GenericContainer<>("openjdk:17")
+ .withFileSystemBind(sampleAppVolume.getHostPath(), "/app", BindMode.READ_ONLY)
+ .withNetwork(network)
+ .withWorkingDirectory("/app")
+ .dependsOn(pushGatewayContainer)
+ .withLogConsumer(LogConsumer.withPrefix("test-app"));
+ prometheusContainer =
+ new GenericContainer<>("prom/prometheus:v2.51.2")
+ .withNetwork(network)
+ .dependsOn(pushGatewayContainer)
+ .withExposedPorts(9090)
+ .withLogConsumer(LogConsumer.withPrefix("prometheus"));
+ }
- final OkHttpClient client = new OkHttpClient();
-
- @Test
- public void testSimple() throws IOException, InterruptedException {
- pushGatewayContainer
- .start();
- sampleAppContainer
- .withCommand("java",
- "-Dio.prometheus.exporter.pushgateway.address=pushgateway:9091",
- "-jar",
- "/app/pushgateway-test-app.jar",
- "simple"
- ).start();
- prometheusContainer
- .withCopyFileToContainer(MountableFile.forClasspathResource("/prometheus.yaml"), "/etc/prometheus/prometheus.yml")
- .start();
- awaitTermination(sampleAppContainer, 10, TimeUnit.SECONDS);
- assertMetrics();
- }
+ @After
+ public void tearDown() throws IOException {
+ prometheusContainer.stop();
+ pushGatewayContainer.stop();
+ sampleAppContainer.stop();
+ sampleAppVolume.remove();
+ }
- @Test
- public void testTextFormat() throws IOException, InterruptedException {
- pushGatewayContainer
- .start();
- sampleAppContainer
- .withCommand("java",
- "-Dio.prometheus.exporter.pushgateway.address=pushgateway:9091",
- "-jar",
- "/app/pushgateway-test-app.jar",
- "textFormat"
- ).start();
- prometheusContainer
- .withCopyFileToContainer(MountableFile.forClasspathResource("/prometheus.yaml"), "/etc/prometheus/prometheus.yml")
- .start();
- awaitTermination(sampleAppContainer, 10, TimeUnit.SECONDS);
- assertMetrics();
- }
+ final OkHttpClient client = new OkHttpClient();
- @Test
- public void testBasicAuth() throws IOException, InterruptedException {
- pushGatewayContainer
- .withCopyFileToContainer(MountableFile.forClasspathResource("/pushgateway-basicauth.yaml"), "/pushgateway/pushgateway-basicauth.yaml")
- .withCommand("--web.config.file", "pushgateway-basicauth.yaml")
- .start();
- sampleAppContainer
- .withCommand("java",
- "-Dio.prometheus.exporter.pushgateway.address=pushgateway:9091",
- "-jar",
- "/app/pushgateway-test-app.jar",
- "basicauth"
- ).start();
- prometheusContainer
- .withCopyFileToContainer(MountableFile.forClasspathResource("/prometheus-basicauth.yaml"), "/etc/prometheus/prometheus.yml")
- .start();
- awaitTermination(sampleAppContainer, 10, TimeUnit.SECONDS);
- assertMetrics();
- }
+ @Test
+ public void testSimple() throws IOException, InterruptedException {
+ pushGatewayContainer.start();
+ sampleAppContainer
+ .withCommand(
+ "java",
+ "-Dio.prometheus.exporter.pushgateway.address=pushgateway:9091",
+ "-jar",
+ "/app/pushgateway-test-app.jar",
+ "simple")
+ .start();
+ prometheusContainer
+ .withCopyFileToContainer(
+ MountableFile.forClasspathResource("/prometheus.yaml"),
+ "/etc/prometheus/prometheus.yml")
+ .start();
+ awaitTermination(sampleAppContainer, 10, TimeUnit.SECONDS);
+ assertMetrics();
+ }
- @Test
- public void testSsl() throws InterruptedException, IOException {
- pushGatewayContainer
- .withCopyFileToContainer(MountableFile.forClasspathResource("/pushgateway-ssl.yaml"), "/pushgateway/pushgateway-ssl.yaml")
- .withCommand("--web.config.file", "pushgateway-ssl.yaml")
- .start();
- sampleAppContainer
- .withCommand("java",
- "-Dio.prometheus.exporter.pushgateway.address=pushgateway:9091",
- "-jar",
- "/app/pushgateway-test-app.jar",
- "ssl"
- ).start();
- prometheusContainer
- .withCopyFileToContainer(MountableFile.forClasspathResource("/prometheus-ssl.yaml"), "/etc/prometheus/prometheus.yml")
- .start();
- awaitTermination(sampleAppContainer, 10, TimeUnit.SECONDS);
- assertMetrics();
- }
+ @Test
+ public void testTextFormat() throws IOException, InterruptedException {
+ pushGatewayContainer.start();
+ sampleAppContainer
+ .withCommand(
+ "java",
+ "-Dio.prometheus.exporter.pushgateway.address=pushgateway:9091",
+ "-jar",
+ "/app/pushgateway-test-app.jar",
+ "textFormat")
+ .start();
+ prometheusContainer
+ .withCopyFileToContainer(
+ MountableFile.forClasspathResource("/prometheus.yaml"),
+ "/etc/prometheus/prometheus.yml")
+ .start();
+ awaitTermination(sampleAppContainer, 10, TimeUnit.SECONDS);
+ assertMetrics();
+ }
- @Test
- public void testProtobuf() throws IOException, InterruptedException {
- pushGatewayContainer
- .start();
- sampleAppContainer
- .withCommand("java",
- "-Dio.prometheus.exporter.pushgateway.address=pushgateway:9091",
- "-jar",
- "/app/pushgateway-test-app.jar",
- "simple"
- ).start();
- prometheusContainer
- .withCommand("--enable-feature=native-histograms", "--config.file", "/etc/prometheus/prometheus.yml")
- .withCopyFileToContainer(MountableFile.forClasspathResource("/prometheus.yaml"), "/etc/prometheus/prometheus.yml")
- .start();
- awaitTermination(sampleAppContainer, 10, TimeUnit.SECONDS);
- assertNativeHistogram();
- }
+ @Test
+ public void testBasicAuth() throws IOException, InterruptedException {
+ pushGatewayContainer
+ .withCopyFileToContainer(
+ MountableFile.forClasspathResource("/pushgateway-basicauth.yaml"),
+ "/pushgateway/pushgateway-basicauth.yaml")
+ .withCommand("--web.config.file", "pushgateway-basicauth.yaml")
+ .start();
+ sampleAppContainer
+ .withCommand(
+ "java",
+ "-Dio.prometheus.exporter.pushgateway.address=pushgateway:9091",
+ "-jar",
+ "/app/pushgateway-test-app.jar",
+ "basicauth")
+ .start();
+ prometheusContainer
+ .withCopyFileToContainer(
+ MountableFile.forClasspathResource("/prometheus-basicauth.yaml"),
+ "/etc/prometheus/prometheus.yml")
+ .start();
+ awaitTermination(sampleAppContainer, 10, TimeUnit.SECONDS);
+ assertMetrics();
+ }
- private void assertMetrics() throws IOException, InterruptedException {
- double value = getValue("my_batch_job_duration_seconds", "job", "pushgateway-test-app");
- Assert.assertEquals(0.5, value, 0.0);
- value = getValue("file_sizes_bytes_bucket", "job", "pushgateway-test-app", "le", "512");
- Assert.assertEquals(0.0, value, 0.0);
- value = getValue("file_sizes_bytes_bucket", "job", "pushgateway-test-app", "le", "1024");
- Assert.assertEquals(2.0, value, 0.0);
- value = getValue("file_sizes_bytes_bucket", "job", "pushgateway-test-app", "le", "+Inf");
- Assert.assertEquals(3.0, value, 0.0);
- }
+ @Test
+ public void testSsl() throws InterruptedException, IOException {
+ pushGatewayContainer
+ .withCopyFileToContainer(
+ MountableFile.forClasspathResource("/pushgateway-ssl.yaml"),
+ "/pushgateway/pushgateway-ssl.yaml")
+ .withCommand("--web.config.file", "pushgateway-ssl.yaml")
+ .start();
+ sampleAppContainer
+ .withCommand(
+ "java",
+ "-Dio.prometheus.exporter.pushgateway.address=pushgateway:9091",
+ "-jar",
+ "/app/pushgateway-test-app.jar",
+ "ssl")
+ .start();
+ prometheusContainer
+ .withCopyFileToContainer(
+ MountableFile.forClasspathResource("/prometheus-ssl.yaml"),
+ "/etc/prometheus/prometheus.yml")
+ .start();
+ awaitTermination(sampleAppContainer, 10, TimeUnit.SECONDS);
+ assertMetrics();
+ }
- private double getValue(String name, String... labels) throws IOException, InterruptedException {
- String scrapeResponseJson = scrape(name);
- Criteria criteria = Criteria.where("metric.__name__").eq(name);
- for (int i = 0; i < labels.length; i += 2) {
- criteria = criteria.and("metric." + labels[i]).eq(labels[i + 1]);
- }
- JSONArray result = JsonPath.parse(scrapeResponseJson).read("$.data.result" + Filter.filter(criteria) + ".value[1]");
- Assert.assertEquals(1, result.size());
- return Double.valueOf(result.get(0).toString());
- }
+ @Test
+ public void testProtobuf() throws IOException, InterruptedException {
+ pushGatewayContainer.start();
+ sampleAppContainer
+ .withCommand(
+ "java",
+ "-Dio.prometheus.exporter.pushgateway.address=pushgateway:9091",
+ "-jar",
+ "/app/pushgateway-test-app.jar",
+ "simple")
+ .start();
+ prometheusContainer
+ .withCommand(
+ "--enable-feature=native-histograms", "--config.file", "/etc/prometheus/prometheus.yml")
+ .withCopyFileToContainer(
+ MountableFile.forClasspathResource("/prometheus.yaml"),
+ "/etc/prometheus/prometheus.yml")
+ .start();
+ awaitTermination(sampleAppContainer, 10, TimeUnit.SECONDS);
+ assertNativeHistogram();
+ }
- private void assertNativeHistogram() throws IOException, InterruptedException {
- double count = getNativeHistogramCount("file_sizes_bytes", "pushgateway-test-app");
- Assert.assertEquals(3, count, 0.0);
- }
+ private void assertMetrics() throws IOException, InterruptedException {
+ double value = getValue("my_batch_job_duration_seconds", "job", "pushgateway-test-app");
+ Assert.assertEquals(0.5, value, 0.0);
+ value = getValue("file_sizes_bytes_bucket", "job", "pushgateway-test-app", "le", "512");
+ Assert.assertEquals(0.0, value, 0.0);
+ value = getValue("file_sizes_bytes_bucket", "job", "pushgateway-test-app", "le", "1024");
+ Assert.assertEquals(2.0, value, 0.0);
+ value = getValue("file_sizes_bytes_bucket", "job", "pushgateway-test-app", "le", "+Inf");
+ Assert.assertEquals(3.0, value, 0.0);
+ }
- private double getNativeHistogramCount(String name, String job) throws IOException, InterruptedException {
- String scrapeResponseJson = scrape("histogram_count(" + name + ")");
- Criteria criteria = Criteria.where("metric.job").eq(job);
- JSONArray result = JsonPath.parse(scrapeResponseJson).read("$.data.result" + Filter.filter(criteria) + ".value[1]");
- return Double.valueOf(result.get(0).toString());
+ private double getValue(String name, String... labels) throws IOException, InterruptedException {
+ String scrapeResponseJson = scrape(name);
+ Criteria criteria = Criteria.where("metric.__name__").eq(name);
+ for (int i = 0; i < labels.length; i += 2) {
+ criteria = criteria.and("metric." + labels[i]).eq(labels[i + 1]);
}
+ JSONArray result =
+ JsonPath.parse(scrapeResponseJson)
+ .read("$.data.result" + Filter.filter(criteria) + ".value[1]");
+ Assert.assertEquals(1, result.size());
+ return Double.valueOf(result.get(0).toString());
+ }
+
+ private void assertNativeHistogram() throws IOException, InterruptedException {
+ double count = getNativeHistogramCount("file_sizes_bytes", "pushgateway-test-app");
+ Assert.assertEquals(3, count, 0.0);
+ }
+
+ private double getNativeHistogramCount(String name, String job)
+ throws IOException, InterruptedException {
+ String scrapeResponseJson = scrape("histogram_count(" + name + ")");
+ Criteria criteria = Criteria.where("metric.job").eq(job);
+ JSONArray result =
+ JsonPath.parse(scrapeResponseJson)
+ .read("$.data.result" + Filter.filter(criteria) + ".value[1]");
+ return Double.valueOf(result.get(0).toString());
+ }
- private String scrape(String query) throws IOException, InterruptedException {
- System.out.println("Querying http://" + prometheusContainer.getHost() + ":" + prometheusContainer.getMappedPort(9090));
- HttpUrl baseUrl = HttpUrl.parse("http://" + prometheusContainer.getHost() + ":" + prometheusContainer.getMappedPort(9090) + "/api/v1/query");
- HttpUrl url = baseUrl.newBuilder()
- .addQueryParameter("query", query)
- .build();
- long timeRemaining = TimeUnit.SECONDS.toMillis(15);
- while (timeRemaining > 0) {
- Request request = new Request.Builder().url(url).build();
- Call call = client.newCall(request);
- Response response = call.execute();
- String body = response.body().string();
- if (!body.contains("\"result\":[]")) {
- // Result when data is not available yet:
- // {"status":"success","data":{"resultType":"vector","result":[]}}
- return body;
- }
- Thread.sleep(250);
- timeRemaining -= 250;
- }
- Assert.fail("timeout while scraping " + url);
- return null;
+ private String scrape(String query) throws IOException, InterruptedException {
+ System.out.println(
+ "Querying http://"
+ + prometheusContainer.getHost()
+ + ":"
+ + prometheusContainer.getMappedPort(9090));
+ HttpUrl baseUrl =
+ HttpUrl.parse(
+ "http://"
+ + prometheusContainer.getHost()
+ + ":"
+ + prometheusContainer.getMappedPort(9090)
+ + "/api/v1/query");
+ HttpUrl url = baseUrl.newBuilder().addQueryParameter("query", query).build();
+ long timeRemaining = TimeUnit.SECONDS.toMillis(15);
+ while (timeRemaining > 0) {
+ Request request = new Request.Builder().url(url).build();
+ Call call = client.newCall(request);
+ Response response = call.execute();
+ String body = response.body().string();
+ if (!body.contains("\"result\":[]")) {
+ // Result when data is not available yet:
+ // {"status":"success","data":{"resultType":"vector","result":[]}}
+ return body;
+ }
+ Thread.sleep(250);
+ timeRemaining -= 250;
}
+ Assert.fail("timeout while scraping " + url);
+ return null;
+ }
- private void awaitTermination(GenericContainer> container, long timeout, TimeUnit unit) throws InterruptedException {
- long waitTimeMillis = 0;
- while (container.isRunning()) {
- if (waitTimeMillis > unit.toMillis(timeout)) {
- Assert.fail(container.getContainerName() + " did not terminate after " + timeout + " " + unit + ".");
- }
- Thread.sleep(20);
- waitTimeMillis += 20;
- }
+ private void awaitTermination(GenericContainer> container, long timeout, TimeUnit unit)
+ throws InterruptedException {
+ long waitTimeMillis = 0;
+ while (container.isRunning()) {
+ if (waitTimeMillis > unit.toMillis(timeout)) {
+ Assert.fail(
+ container.getContainerName()
+ + " did not terminate after "
+ + timeout
+ + " "
+ + unit
+ + ".");
+ }
+ Thread.sleep(20);
+ waitTimeMillis += 20;
}
+ }
}
diff --git a/pom.xml b/pom.xml
index 44eadc391..5ab8f42e2 100644
--- a/pom.xml
+++ b/pom.xml
@@ -169,7 +169,6 @@
com.diffplug.spotlessspotless-maven-plugin
- origin/main
diff --git a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExemplarsProperties.java b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExemplarsProperties.java
index ff955bc50..f660725bf 100644
--- a/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExemplarsProperties.java
+++ b/prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExemplarsProperties.java
@@ -2,113 +2,135 @@
import java.util.Map;
-/**
- * Properties starting with io.prometheus.exemplars
- */
+/** Properties starting with io.prometheus.exemplars */
public class ExemplarsProperties {
- private static final String MIN_RETENTION_PERIOD_SECONDS = "minRetentionPeriodSeconds";
- private static final String MAX_RETENTION_PERIOD_SECONDS = "maxRetentionPeriodSeconds";
- private static final String SAMPLE_INTERVAL_MILLISECONDS = "sampleIntervalMilliseconds";
-
- private final Integer minRetentionPeriodSeconds;
- private final Integer maxRetentionPeriodSeconds;
- private final Integer sampleIntervalMilliseconds;
-
- private ExemplarsProperties(
- Integer minRetentionPeriodSeconds,
- Integer maxRetentionPeriodSeconds,
- Integer sampleIntervalMilliseconds) {
- this.minRetentionPeriodSeconds = minRetentionPeriodSeconds;
- this.maxRetentionPeriodSeconds = maxRetentionPeriodSeconds;
- this.sampleIntervalMilliseconds = sampleIntervalMilliseconds;
+ private static final String MIN_RETENTION_PERIOD_SECONDS = "minRetentionPeriodSeconds";
+ private static final String MAX_RETENTION_PERIOD_SECONDS = "maxRetentionPeriodSeconds";
+ private static final String SAMPLE_INTERVAL_MILLISECONDS = "sampleIntervalMilliseconds";
+
+ private final Integer minRetentionPeriodSeconds;
+ private final Integer maxRetentionPeriodSeconds;
+ private final Integer sampleIntervalMilliseconds;
+
+ private ExemplarsProperties(
+ Integer minRetentionPeriodSeconds,
+ Integer maxRetentionPeriodSeconds,
+ Integer sampleIntervalMilliseconds) {
+ this.minRetentionPeriodSeconds = minRetentionPeriodSeconds;
+ this.maxRetentionPeriodSeconds = maxRetentionPeriodSeconds;
+ this.sampleIntervalMilliseconds = sampleIntervalMilliseconds;
+ }
+
+ /**
+ * Minimum time how long Exemplars are kept before they may be replaced by new Exemplars.
+ *
+ *
Default see {@code ExemplarSamplerConfig.DEFAULT_MIN_RETENTION_PERIOD_SECONDS}
+ */
+ public Integer getMinRetentionPeriodSeconds() {
+ return minRetentionPeriodSeconds;
+ }
+
+ /**
+ * Maximum time how long Exemplars are kept before they are evicted.
+ *
+ *
Default see {@code ExemplarSamplerConfig.DEFAULT_MAX_RETENTION_PERIOD_SECONDS}
+ */
+ public Integer getMaxRetentionPeriodSeconds() {
+ return maxRetentionPeriodSeconds;
+ }
+
+ /**
+ * Time between attempts to sample new Exemplars. This is a performance improvement for
+ * high-frequency applications, because with the sample interval we make sure that the exemplar
+ * sampler is not called for every single request.
+ *
+ *
Default see {@code ExemplarSamplerConfig.DEFAULT_SAMPLE_INTERVAL_MILLISECONDS}
+ */
+ public Integer getSampleIntervalMilliseconds() {
+ return sampleIntervalMilliseconds;
+ }
+
+ /**
+ * Note that this will remove entries from {@code properties}. This is because we want to know if
+ * there are unused properties remaining after all properties have been loaded.
+ */
+ static ExemplarsProperties load(String prefix, Map