diff --git a/prometheus_client/openmetrics/exposition.py b/prometheus_client/openmetrics/exposition.py index 5e69e463..57e18fe6 100644 --- a/prometheus_client/openmetrics/exposition.py +++ b/prometheus_client/openmetrics/exposition.py @@ -181,9 +181,9 @@ def escape_metric_name(s: str, escaping: str = UNDERSCORES) -> str: return '"{}"'.format(_escape(s, escaping, _is_legacy_metric_rune)) return _escape(s, escaping, _is_legacy_metric_rune) elif escaping == UNDERSCORES: - if _is_valid_legacy_metric_name(s): + if _is_valid_legacy_metric_name(s) and ':' not in s: return s - return _escape(s, escaping, _is_legacy_metric_rune) + return _escape(s, escaping, _is_legacy_labelname_rune) elif escaping == DOTS: return _escape(s, escaping, _is_legacy_metric_rune) elif escaping == VALUES: diff --git a/tests/openmetrics/test_exposition.py b/tests/openmetrics/test_exposition.py index a3ed0d6e..f67a7899 100644 --- a/tests/openmetrics/test_exposition.py +++ b/tests/openmetrics/test_exposition.py @@ -55,6 +55,15 @@ def test_counter_utf8_escaped_underscores(self): utf8_cc_total 1.0 utf8_cc_created 123.456 # EOF +""" == generate_latest(self.registry, UNDERSCORES) + + def test_gauge_colon_in_name_escaped_underscores(self): + g = Gauge('sglang:token_usage', 'Total token usage.', registry=self.registry) + g.set(42.0) + assert b"""# HELP sglang_token_usage Total token usage. +# TYPE sglang_token_usage gauge +sglang_token_usage 42.0 +# EOF """ == generate_latest(self.registry, UNDERSCORES) def test_counter_total(self) -> None: @@ -482,7 +491,7 @@ def test_native_histogram_version_comparison(self) -> None: { "name": "legacy valid metric name", "input": "no:escaping_required", - "expectedUnderscores": "no:escaping_required", + "expectedUnderscores": "no_escaping_required", "expectedDots": "no:escaping__required", "expectedValue": "no:escaping_required", }, @@ -503,7 +512,7 @@ def test_native_histogram_version_comparison(self) -> None: { "name": "metric name with dots and colon", "input": "http.status:sum", - "expectedUnderscores": "http_status:sum", + "expectedUnderscores": "http_status_sum", "expectedDots": "http_dot_status:sum", "expectedValue": "U__http_2e_status:sum", }, diff --git a/tests/test_exposition.py b/tests/test_exposition.py index a3c97820..2fe31891 100644 --- a/tests/test_exposition.py +++ b/tests/test_exposition.py @@ -644,7 +644,7 @@ def test_prom_no_version(self): { "name": "legacy valid metric name", "input": "no:escaping_required", - "expectedUnderscores": "no:escaping_required", + "expectedUnderscores": "no_escaping_required", "expectedDots": "no:escaping__required", "expectedValue": "no:escaping_required", }, @@ -665,7 +665,7 @@ def test_prom_no_version(self): { "name": "metric name with dots and colon", "input": "http.status:sum", - "expectedUnderscores": "http_status:sum", + "expectedUnderscores": "http_status_sum", "expectedDots": "http_dot_status:sum", "expectedValue": "U__http_2e_status:sum", },