Skip to content

Commit 8ee8039

Browse files
authored
Merge branch 'main' into issue_2635
2 parents ff32006 + 1a1421f commit 8ee8039

File tree

2 files changed

+58
-9
lines changed

2 files changed

+58
-9
lines changed

exporter/opentelemetry-exporter-prometheus/src/opentelemetry/exporter/prometheus/__init__.py

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -62,18 +62,19 @@
6262
---
6363
"""
6464

65-
import collections
66-
import logging
67-
import re
65+
from collections import deque
6866
from itertools import chain
69-
from typing import Iterable, Optional, Sequence, Tuple
67+
from json import dumps
68+
from logging import getLogger
69+
from re import IGNORECASE, UNICODE, compile
70+
from typing import Iterable, Optional, Sequence, Tuple, Union
7071

7172
from prometheus_client import core
7273

7374
from opentelemetry.sdk._metrics.export import MetricReader
7475
from opentelemetry.sdk._metrics.point import Gauge, Histogram, Metric, Sum
7576

76-
_logger = logging.getLogger(__name__)
77+
_logger = getLogger(__name__)
7778

7879

7980
def _convert_buckets(metric: Metric) -> Sequence[Tuple[str, int]]:
@@ -123,9 +124,9 @@ class _CustomCollector:
123124
def __init__(self, prefix: str = ""):
124125
self._prefix = prefix
125126
self._callback = None
126-
self._metrics_to_export = collections.deque()
127-
self._non_letters_digits_underscore_re = re.compile(
128-
r"[^\w]", re.UNICODE | re.IGNORECASE
127+
self._metrics_to_export = deque()
128+
self._non_letters_digits_underscore_re = compile(
129+
r"[^\w]", UNICODE | IGNORECASE
129130
)
130131

131132
def add_metrics_data(self, export_records: Sequence[Metric]) -> None:
@@ -157,7 +158,7 @@ def _translate_to_prometheus(
157158
label_keys = []
158159
for key, value in metric.attributes.items():
159160
label_keys.append(self._sanitize(key))
160-
label_values.append(str(value))
161+
label_values.append(self._check_value(value))
161162

162163
metric_name = ""
163164
if self._prefix != "":
@@ -206,3 +207,10 @@ def _sanitize(self, key: str) -> str:
206207
Replace all characters other than [A-Za-z0-9_] with '_'.
207208
"""
208209
return self._non_letters_digits_underscore_re.sub("_", key)
210+
211+
# pylint: disable=no-self-use
212+
def _check_value(self, value: Union[int, float, str, Sequence]) -> str:
213+
"""Check the label value and return is appropriate representation"""
214+
if not isinstance(value, str):
215+
return dumps(value, default=str)
216+
return str(value)

exporter/opentelemetry-exporter-prometheus/tests/test_prometheus_exporter.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,3 +167,44 @@ def test_sanitize(self):
167167
self.assertEqual(collector._sanitize(",./?;:[]{}"), "__________")
168168
self.assertEqual(collector._sanitize("TestString"), "TestString")
169169
self.assertEqual(collector._sanitize("aAbBcC_12_oi"), "aAbBcC_12_oi")
170+
171+
def test_list_labels(self):
172+
labels = {"environment@": ["1", "2", "3"], "os": "Unix"}
173+
record = _generate_gauge(
174+
"test@gauge",
175+
123,
176+
attributes=labels,
177+
description="testdesc",
178+
unit="testunit",
179+
)
180+
collector = _CustomCollector("testprefix")
181+
collector.add_metrics_data([record])
182+
183+
for prometheus_metric in collector.collect():
184+
self.assertEqual(type(prometheus_metric), GaugeMetricFamily)
185+
self.assertEqual(
186+
prometheus_metric.name, "testprefix_test_gauge_testunit"
187+
)
188+
self.assertEqual(prometheus_metric.documentation, "testdesc")
189+
self.assertTrue(len(prometheus_metric.samples) == 1)
190+
self.assertEqual(prometheus_metric.samples[0].value, 123)
191+
self.assertTrue(len(prometheus_metric.samples[0].labels) == 2)
192+
self.assertEqual(
193+
prometheus_metric.samples[0].labels["environment_"],
194+
'["1", "2", "3"]',
195+
)
196+
self.assertEqual(prometheus_metric.samples[0].labels["os"], "Unix")
197+
198+
def test_check_value(self):
199+
200+
collector = _CustomCollector("")
201+
202+
self.assertEqual(collector._check_value(1), "1")
203+
self.assertEqual(collector._check_value(1.0), "1.0")
204+
self.assertEqual(collector._check_value("a"), "a")
205+
self.assertEqual(collector._check_value([1, 2]), "[1, 2]")
206+
self.assertEqual(collector._check_value((1, 2)), "[1, 2]")
207+
self.assertEqual(collector._check_value(["a", 2]), '["a", 2]')
208+
self.assertEqual(collector._check_value(True), "true")
209+
self.assertEqual(collector._check_value(False), "false")
210+
self.assertEqual(collector._check_value(None), "null")

0 commit comments

Comments
 (0)