diff --git a/CHANGELOG.md b/CHANGELOG.md index 6106b889b17..7121b281cc4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +- Prometheus Exporter string representation for target_info labels + ([#3659](https://github.com/open-telemetry/opentelemetry-python/pull/3659)) - Logs: ObservedTimestamp field is missing in console exporter output ([#3564](https://github.com/open-telemetry/opentelemetry-python/pull/3564)) - Fix explicit bucket histogram aggregation diff --git a/exporter/opentelemetry-exporter-prometheus/src/opentelemetry/exporter/prometheus/__init__.py b/exporter/opentelemetry-exporter-prometheus/src/opentelemetry/exporter/prometheus/__init__.py index 4c903297788..b1a8d668c46 100644 --- a/exporter/opentelemetry-exporter-prometheus/src/opentelemetry/exporter/prometheus/__init__.py +++ b/exporter/opentelemetry-exporter-prometheus/src/opentelemetry/exporter/prometheus/__init__.py @@ -380,7 +380,8 @@ def _create_info_metric( """Create an Info Metric Family with list of attributes""" # sanitize the attribute names according to Prometheus rule attributes = { - self._sanitize(key): value for key, value in attributes.items() + self._sanitize(key): self._check_value(value) + for key, value in attributes.items() } info = InfoMetricFamily(name, description, labels=attributes) info.add_metric(labels=list(attributes.keys()), value=attributes) diff --git a/exporter/opentelemetry-exporter-prometheus/tests/test_prometheus_exporter.py b/exporter/opentelemetry-exporter-prometheus/tests/test_prometheus_exporter.py index db920a5c734..6d9126c815f 100644 --- a/exporter/opentelemetry-exporter-prometheus/tests/test_prometheus_exporter.py +++ b/exporter/opentelemetry-exporter-prometheus/tests/test_prometheus_exporter.py @@ -351,30 +351,33 @@ def test_target_info_enabled_by_default(self): metric_reader = PrometheusMetricReader() provider = MeterProvider( metric_readers=[metric_reader], - resource=Resource({"os": "Unix", "histo": 1}), + resource=Resource({"os": "Unix", "version": "1.2.3"}), ) meter = provider.get_meter("getting-started", "0.1.2") counter = meter.create_counter("counter") counter.add(1) result = list(metric_reader._collector.collect()) - for prometheus_metric in result[:0]: - self.assertEqual(type(prometheus_metric), InfoMetricFamily) - self.assertEqual(prometheus_metric.name, "target") - self.assertEqual( - prometheus_metric.documentation, "Target metadata" - ) - self.assertTrue(len(prometheus_metric.samples) == 1) - self.assertEqual(prometheus_metric.samples[0].value, 1) - self.assertTrue(len(prometheus_metric.samples[0].labels) == 2) - self.assertEqual(prometheus_metric.samples[0].labels["os"], "Unix") - self.assertEqual(prometheus_metric.samples[0].labels["histo"], "1") + self.assertEqual(len(result), 2) + + prometheus_metric = result[0] + + self.assertEqual(type(prometheus_metric), InfoMetricFamily) + self.assertEqual(prometheus_metric.name, "target") + self.assertEqual(prometheus_metric.documentation, "Target metadata") + self.assertTrue(len(prometheus_metric.samples) == 1) + self.assertEqual(prometheus_metric.samples[0].value, 1) + self.assertTrue(len(prometheus_metric.samples[0].labels) == 2) + self.assertEqual(prometheus_metric.samples[0].labels["os"], "Unix") + self.assertEqual( + prometheus_metric.samples[0].labels["version"], "1.2.3" + ) def test_target_info_disabled(self): metric_reader = PrometheusMetricReader(disable_target_info=True) provider = MeterProvider( metric_readers=[metric_reader], - resource=Resource({"os": "Unix", "histo": 1}), + resource=Resource({"os": "Unix", "version": "1.2.3"}), ) meter = provider.get_meter("getting-started", "0.1.2") counter = meter.create_counter("counter") @@ -388,7 +391,7 @@ def test_target_info_disabled(self): prometheus_metric.documentation, "Target metadata" ) self.assertNotIn("os", prometheus_metric.samples[0].labels) - self.assertNotIn("histo", prometheus_metric.samples[0].labels) + self.assertNotIn("version", prometheus_metric.samples[0].labels) def test_target_info_sanitize(self): metric_reader = PrometheusMetricReader() @@ -398,6 +401,8 @@ def test_target_info_sanitize(self): { "system.os": "Unix", "system.name": "Prometheus Target Sanitize", + "histo": 1, + "ratio": 0.1, } ), ) @@ -411,7 +416,7 @@ def test_target_info_sanitize(self): self.assertEqual(prometheus_metric.documentation, "Target metadata") self.assertTrue(len(prometheus_metric.samples) == 1) self.assertEqual(prometheus_metric.samples[0].value, 1) - self.assertTrue(len(prometheus_metric.samples[0].labels) == 2) + self.assertTrue(len(prometheus_metric.samples[0].labels) == 4) self.assertTrue("system_os" in prometheus_metric.samples[0].labels) self.assertEqual( prometheus_metric.samples[0].labels["system_os"], "Unix" @@ -421,3 +426,13 @@ def test_target_info_sanitize(self): prometheus_metric.samples[0].labels["system_name"], "Prometheus Target Sanitize", ) + self.assertTrue("histo" in prometheus_metric.samples[0].labels) + self.assertEqual( + prometheus_metric.samples[0].labels["histo"], + "1", + ) + self.assertTrue("ratio" in prometheus_metric.samples[0].labels) + self.assertEqual( + prometheus_metric.samples[0].labels["ratio"], + "0.1", + )