diff --git a/prometheus_client/openmetrics/exposition.py b/prometheus_client/openmetrics/exposition.py index 5e69e463..5a7711b0 100644 --- a/prometheus_client/openmetrics/exposition.py +++ b/prometheus_client/openmetrics/exposition.py @@ -25,9 +25,9 @@ def _is_valid_exemplar_metric(metric, sample): if metric.type == 'counter' and sample.name.endswith('_total'): return True - if metric.type in ('gaugehistogram') and sample.name.endswith('_bucket'): + if metric.type == 'gaugehistogram' and sample.name.endswith('_bucket'): return True - if metric.type in ('histogram') and sample.name.endswith('_bucket') or sample.name == metric.name: + if metric.type == 'histogram' and (sample.name.endswith('_bucket') or sample.name == metric.name): return True return False diff --git a/tests/openmetrics/test_exposition.py b/tests/openmetrics/test_exposition.py index a3ed0d6e..a849f5fa 100644 --- a/tests/openmetrics/test_exposition.py +++ b/tests/openmetrics/test_exposition.py @@ -347,6 +347,21 @@ def collect(self): with self.assertRaises(ValueError): generate_latest(self.registry) + def test_gauge_exemplar(self) -> None: + class MyCollector: + def collect(self): + metric = Metric("gg", "A gauge", 'gauge') + # A sample whose name equals the metric name must not be + # treated as exemplar-eligible just because it matches; + # only histogram/gaugehistogram buckets, counter _total, and + # native histograms may carry exemplars. + metric.add_sample("gg", {}, 1, None, Exemplar({'a': 'b'}, 0.5)) + yield metric + + self.registry.register(MyCollector()) + with self.assertRaises(ValueError): + generate_latest(self.registry) + def test_gaugehistogram(self) -> None: self.custom_collector( GaugeHistogramMetricFamily('gh', 'help', buckets=[('1.0', 4), ('+Inf', (5))], gsum_value=7))