From 2b8cac6e015aa22f61de8bf4ee7391b1ac0cf1e8 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Fri, 13 Feb 2026 14:28:23 +0100 Subject: [PATCH] Update Prometheus client to 1.4.3 Simplified replacement for #7588 - always uses legacy (non-UTF-8) Prometheus name escaping, without adding a flag. In Prometheus client 1.4.x, sanitizeMetricName and sanitizeLabelName no longer convert non-standard characters to underscores (to support UTF-8). To maintain backward compatibility, prometheusName() is called first to convert to legacy format. --- dependencyManagement/build.gradle.kts | 2 +- .../prometheus/Otel2PrometheusConverter.java | 19 +++++++++++++++---- .../prometheus/PrometheusHttpServerTest.java | 2 +- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index debe9f7f40f..3a78d666da1 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -15,7 +15,7 @@ val jmhVersion = "1.37" val mockitoVersion = "4.11.0" val slf4jVersion = "2.0.17" val opencensusVersion = "0.31.1" -val prometheusServerVersion = "1.3.10" +val prometheusServerVersion = "1.4.3" val armeriaVersion = "1.36.0" val junitVersion = "5.14.2" val okhttpVersion = "5.3.2" diff --git a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/Otel2PrometheusConverter.java b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/Otel2PrometheusConverter.java index f05abbce947..5f443dba0ab 100644 --- a/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/Otel2PrometheusConverter.java +++ b/exporters/prometheus/src/main/java/io/opentelemetry/exporter/prometheus/Otel2PrometheusConverter.java @@ -5,6 +5,7 @@ package io.opentelemetry.exporter.prometheus; +import static io.prometheus.metrics.model.snapshots.PrometheusNaming.prometheusName; import static io.prometheus.metrics.model.snapshots.PrometheusNaming.sanitizeLabelName; import static io.prometheus.metrics.model.snapshots.PrometheusNaming.sanitizeMetricName; import static java.util.Objects.requireNonNull; @@ -474,7 +475,7 @@ private Labels convertAttributes( attributes.forEach( (key, value) -> labelNameToValue.put( - sanitizeLabelName(key.getKey()), toLabelValue(key.getType(), value))); + convertLabelName(key.getKey()), toLabelValue(key.getType(), value))); for (int i = 0; i < additionalAttributes.length; i += 2) { labelNameToValue.putIfAbsent( @@ -504,7 +505,7 @@ private Labels convertAttributes( Object attributeValue = resourceAttributes.get(attributeKey); if (attributeValue != null) { labelNameToValue.putIfAbsent( - sanitizeLabelName(attributeKey.getKey()), attributeValue.toString()); + convertLabelName(attributeKey.getKey()), attributeValue.toString()); } } } @@ -544,14 +545,24 @@ private List> filterAllowedResourceAttributeKeys(@Nullable Resou return allowedAttributeKeys; } + /** + * Convert an attribute key to a legacy Prometheus label name. {@code prometheusName} converts + * non-standard characters (dots, dashes, etc.) to underscores, and {@code sanitizeLabelName} + * strips invalid leading prefixes. + */ + private static String convertLabelName(String key) { + return sanitizeLabelName(prometheusName(key)); + } + private static MetricMetadata convertMetadata(MetricData metricData) { - String name = sanitizeMetricName(metricData.getName()); + String name = sanitizeMetricName(prometheusName(metricData.getName())); String help = metricData.getDescription(); Unit unit = PrometheusUnitsHelper.convertUnit(metricData.getUnit()); if (unit != null && !name.endsWith(unit.toString())) { name = name + "_" + unit; } - // Repeated __ are not allowed according to spec, although this is allowed in prometheus + // Repeated __ are discouraged according to spec, although this is allowed in prometheus, see + // https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/compatibility/prometheus_and_openmetrics.md#metric-metadata-1 while (name.contains("__")) { name = name.replace("__", "_"); } diff --git a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerTest.java b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerTest.java index 16c39efc31b..c4cda1d6fad 100644 --- a/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerTest.java +++ b/exporters/prometheus/src/test/java/io/opentelemetry/exporter/prometheus/PrometheusHttpServerTest.java @@ -46,7 +46,7 @@ import io.opentelemetry.sdk.resources.Resource; import io.prometheus.metrics.exporter.httpserver.HTTPServer; import io.prometheus.metrics.exporter.httpserver.MetricsHandler; -import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_31_1.Metrics; +import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_33_0.Metrics; import io.prometheus.metrics.model.registry.PrometheusRegistry; import java.io.ByteArrayInputStream; import java.io.IOException;