Skip to content

Commit 520a64b

Browse files
authored
Exporter/Prometheus: Sanitize metric name and key. (census-instrumentation#475)
1 parent 42962cf commit 520a64b

2 files changed

Lines changed: 20 additions & 2 deletions

File tree

opencensus/stats/exporters/prometheus_exporter.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
from opencensus.stats import aggregation_data as aggregation_data_module
2525
from opencensus.stats.exporters import base
2626

27+
import re
28+
2729

2830
class Options(object):
2931
""" Options contains options for configuring the exporter.
@@ -125,7 +127,7 @@ def register_view(self, view):
125127
if v_name not in self.registered_views:
126128
desc = {'name': v_name,
127129
'documentation': view.description,
128-
'labels': list(view.columns)}
130+
'labels': list(map(sanitize, view.columns))}
129131
self.registered_views[v_name] = desc
130132
self.registry.register(self)
131133

@@ -345,4 +347,14 @@ def get_view_name(namespace, view):
345347
name = ""
346348
if namespace != "":
347349
name = namespace + "_"
348-
return name + view.name
350+
return sanitize(name + view.name)
351+
352+
353+
_NON_LETTERS_NOR_DIGITS_RE = re.compile(r'[^\w]', re.UNICODE | re.IGNORECASE)
354+
355+
356+
def sanitize(key):
357+
""" sanitize the given metric name or label according to Prometheus rule.
358+
Replace all characters other than [A-Za-z0-9_] with '_'.
359+
"""
360+
return _NON_LETTERS_NOR_DIGITS_RE.sub('_', key)

tests/unit/stats/exporter/test_prometheus_stats.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,3 +283,9 @@ def test_get_view_name(self):
283283
def test_get_view_name_without_namespace(self):
284284
v_name = prometheus.get_view_name(namespace="", view=VIDEO_SIZE_VIEW)
285285
self.assertEqual("myorg_views_video_size_test2", v_name)
286+
287+
def test_sanitize(self):
288+
v_name = prometheus.sanitize("demo/latency")
289+
self.assertEqual("demo_latency", v_name)
290+
label_name = prometheus.sanitize("my.org/demo/key1")
291+
self.assertEqual("my_org_demo_key1", label_name)

0 commit comments

Comments
 (0)