Skip to content

Commit

Permalink
feat: normalize prometheus metric name
Browse files Browse the repository at this point in the history
Ensure the Prometheus metric name are respecting Prometheus convention.
  • Loading branch information
kpetremann committed Jun 25, 2023
1 parent 83424af commit ed110bb
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 1 deletion.
22 changes: 21 additions & 1 deletion mqtt_exporter/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import sys

import paho.mqtt.client as mqtt
from prometheus_client import Counter, Gauge, start_http_server
from prometheus_client import Counter, Gauge, metrics, start_http_server

from mqtt_exporter import settings

Expand Down Expand Up @@ -61,13 +61,33 @@ def subscribe(client, _, __, result_code, *args):
LOG.error("MQTT %s", mqtt.connack_string(result_code))


def _normalize_prometheus_metric_name(prom_metric_name):
"""Transform an invalid prometheus metric to a valid one.
https://prometheus.io/docs/concepts/data_model/#metric-names-and-labels
"""
if metrics.METRIC_NAME_RE.match(prom_metric_name):
return prom_metric_name

# clean invalid characted
prom_metric_name = re.sub(r"[^a-zA-Z0-9_:]", "", prom_metric_name)

# ensure to start with valid character
if not re.match(r"^[a-zA-Z_:]", prom_metric_name):
prom_metric_name = ":" + prom_metric_name

return prom_metric_name


def _create_prometheus_metric(prom_metric_name):
"""Create Prometheus metric if does not exist."""
if not prom_metrics.get(prom_metric_name):
labels = [settings.TOPIC_LABEL]
if settings.MQTT_EXPOSE_CLIENT_ID:
labels.append("client_id")

prom_metric_name = _normalize_prometheus_metric_name(prom_metric_name)

try:
prom_metrics[prom_metric_name] = Gauge(
prom_metric_name, "metric generated from MQTT message.", labels
Expand Down
1 change: 1 addition & 0 deletions tests/unit/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Unit tests."""
15 changes: 15 additions & 0 deletions tests/unit/test_normalize_prometheus_name.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
"""Tests of Prometheus normalization metrics."""
from mqtt_exporter.main import _normalize_prometheus_metric_name


def test_normalize_prometheus_metric_name():
"""Test _normalize_prometheus_metric_name."""
tests = {
"1234invalid": ":1234invalid",
"valid1234": "valid1234",
"_this_is_valid": "_this_is_valid",
"not_so_valid%_name": "not_so_valid_name",
}

for candidate, wanted in tests.items():
assert _normalize_prometheus_metric_name(candidate) == wanted

0 comments on commit ed110bb

Please sign in to comment.