From 00441b08a155567646c56a54653532f9682b2bcf Mon Sep 17 00:00:00 2001 From: Jay DeLuca Date: Thu, 19 Feb 2026 10:48:46 -0500 Subject: [PATCH 1/3] Handle empy datapoints Signed-off-by: Jay DeLuca --- .../otelmodel/MetricDataFactory.java | 24 +++++++++++++++++++ .../exporter/opentelemetry/ExportTest.java | 22 ++++++++++++++++- 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/MetricDataFactory.java b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/MetricDataFactory.java index 4c75d2622..78ecb0ebe 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/MetricDataFactory.java +++ b/prometheus-metrics-exporter-opentelemetry/src/main/java/io/prometheus/metrics/exporter/opentelemetry/otelmodel/MetricDataFactory.java @@ -27,7 +27,11 @@ public MetricDataFactory( this.currentTimeMillis = currentTimeMillis; } + @Nullable public MetricData create(CounterSnapshot snapshot) { + if (snapshot.getDataPoints().isEmpty()) { + return null; + } return new PrometheusMetricData<>( snapshot.getMetadata(), new PrometheusCounter(snapshot, currentTimeMillis), @@ -35,7 +39,11 @@ public MetricData create(CounterSnapshot snapshot) { resource); } + @Nullable public MetricData create(GaugeSnapshot snapshot) { + if (snapshot.getDataPoints().isEmpty()) { + return null; + } return new PrometheusMetricData<>( snapshot.getMetadata(), new PrometheusGauge(snapshot, currentTimeMillis), @@ -64,7 +72,11 @@ public MetricData create(HistogramSnapshot snapshot) { return null; } + @Nullable public MetricData create(SummarySnapshot snapshot) { + if (snapshot.getDataPoints().isEmpty()) { + return null; + } return new PrometheusMetricData<>( snapshot.getMetadata(), new PrometheusSummary(snapshot, currentTimeMillis), @@ -72,7 +84,11 @@ public MetricData create(SummarySnapshot snapshot) { resource); } + @Nullable public MetricData create(InfoSnapshot snapshot) { + if (snapshot.getDataPoints().isEmpty()) { + return null; + } return new PrometheusMetricData<>( snapshot.getMetadata(), new PrometheusInfo(snapshot, currentTimeMillis), @@ -80,7 +96,11 @@ public MetricData create(InfoSnapshot snapshot) { resource); } + @Nullable public MetricData create(StateSetSnapshot snapshot) { + if (snapshot.getDataPoints().isEmpty()) { + return null; + } return new PrometheusMetricData<>( snapshot.getMetadata(), new PrometheusStateSet(snapshot, currentTimeMillis), @@ -88,7 +108,11 @@ public MetricData create(StateSetSnapshot snapshot) { resource); } + @Nullable public MetricData create(UnknownSnapshot snapshot) { + if (snapshot.getDataPoints().isEmpty()) { + return null; + } return new PrometheusMetricData<>( snapshot.getMetadata(), new PrometheusUnknown(snapshot, currentTimeMillis), diff --git a/prometheus-metrics-exporter-opentelemetry/src/test/java/io/prometheus/metrics/exporter/opentelemetry/ExportTest.java b/prometheus-metrics-exporter-opentelemetry/src/test/java/io/prometheus/metrics/exporter/opentelemetry/ExportTest.java index 5ec213563..e00a00c7f 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/test/java/io/prometheus/metrics/exporter/opentelemetry/ExportTest.java +++ b/prometheus-metrics-exporter-opentelemetry/src/test/java/io/prometheus/metrics/exporter/opentelemetry/ExportTest.java @@ -33,7 +33,8 @@ class ExportTest { private static final Attributes ATTRIBUTES = Attributes.of(AttributeKey.stringKey("label"), "val", AttributeKey.stringKey("key"), "value"); - @RegisterExtension OpenTelemetryExtension testing = OpenTelemetryExtension.create(); + @RegisterExtension + static OpenTelemetryExtension testing = OpenTelemetryExtension.create(); private final PrometheusRegistry registry = new PrometheusRegistry(); @@ -304,6 +305,25 @@ void unknown() { .hasAttributes(Attributes.of(AttributeKey.stringKey("label"), "val")))); } + @Test + void metricsWithoutDataPointsAreNotExported() { + // Register metrics with labels but don't create any data points + // This simulates the jvm_memory_pool_allocated_bytes scenario where a metric + // is registered with label names, but no data points are created until GC happens + Counter.builder().name("counter_no_data").labelNames("pool").register(registry); + Gauge.builder().name("gauge_no_data").labelNames("pool").register(registry); + Summary.builder().name("summary_no_data").labelNames("pool").register(registry); + StateSet.builder() + .name("stateset_no_data") + .states("state") + .labelNames("pool") + .register(registry); + Info.builder().name("info_no_data").labelNames("pool").register(registry); + + List metrics = testing.getMetrics(); + assertThat(metrics).isEmpty(); + } + private MetricAssert metricAssert() { List metrics = testing.getMetrics(); assertThat(metrics).hasSize(1); From 2a5cd1fb71b359d7a6dfcb70578967f52b05467b Mon Sep 17 00:00:00 2001 From: Jay DeLuca Date: Thu, 19 Feb 2026 11:00:50 -0500 Subject: [PATCH 2/3] format Signed-off-by: Jay DeLuca --- .../prometheus/metrics/exporter/opentelemetry/ExportTest.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/prometheus-metrics-exporter-opentelemetry/src/test/java/io/prometheus/metrics/exporter/opentelemetry/ExportTest.java b/prometheus-metrics-exporter-opentelemetry/src/test/java/io/prometheus/metrics/exporter/opentelemetry/ExportTest.java index e00a00c7f..a60e556ce 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/test/java/io/prometheus/metrics/exporter/opentelemetry/ExportTest.java +++ b/prometheus-metrics-exporter-opentelemetry/src/test/java/io/prometheus/metrics/exporter/opentelemetry/ExportTest.java @@ -33,8 +33,7 @@ class ExportTest { private static final Attributes ATTRIBUTES = Attributes.of(AttributeKey.stringKey("label"), "val", AttributeKey.stringKey("key"), "value"); - @RegisterExtension - static OpenTelemetryExtension testing = OpenTelemetryExtension.create(); + @RegisterExtension static OpenTelemetryExtension testing = OpenTelemetryExtension.create(); private final PrometheusRegistry registry = new PrometheusRegistry(); From 32c7e7687db07bbe48f39d8a0de67c363b177627 Mon Sep 17 00:00:00 2001 From: Jay DeLuca Date: Thu, 19 Feb 2026 11:38:33 -0500 Subject: [PATCH 3/3] add histogram Signed-off-by: Jay DeLuca --- .../io/prometheus/metrics/exporter/opentelemetry/ExportTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/prometheus-metrics-exporter-opentelemetry/src/test/java/io/prometheus/metrics/exporter/opentelemetry/ExportTest.java b/prometheus-metrics-exporter-opentelemetry/src/test/java/io/prometheus/metrics/exporter/opentelemetry/ExportTest.java index a60e556ce..e134b2373 100644 --- a/prometheus-metrics-exporter-opentelemetry/src/test/java/io/prometheus/metrics/exporter/opentelemetry/ExportTest.java +++ b/prometheus-metrics-exporter-opentelemetry/src/test/java/io/prometheus/metrics/exporter/opentelemetry/ExportTest.java @@ -312,6 +312,7 @@ void metricsWithoutDataPointsAreNotExported() { Counter.builder().name("counter_no_data").labelNames("pool").register(registry); Gauge.builder().name("gauge_no_data").labelNames("pool").register(registry); Summary.builder().name("summary_no_data").labelNames("pool").register(registry); + Histogram.builder().name("histogram_no_data").labelNames("pool").register(registry); StateSet.builder() .name("stateset_no_data") .states("state")