prometheus/client_java

Inconsistencies between PrometheusNaming.sanitizeMetricName() methods

mimaison opened this issue · 0 comments

We have 2 methods to sanitize metric name:

These behave slightly differently and I think both are incorrect:

1. Handling of colons

String metricName = "some.metric:name";
System.out.println(PrometheusNaming.sanitizeMetricName(metricName));
System.out.println(PrometheusNaming.sanitizeMetricName(metricName, Unit.SECONDS));

This prints:

some.metric:name
some.metric_name_seconds

This is because the variant with the unit argument calls sanitizeLabelName() on the metric name before appending the unit suffix instead of calling sanitizeMetricName(): https://github.com/prometheus/client_java/blob/main/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/PrometheusNaming.java#L160C25-L160C42

While colons are allowed in Prometheus metric names (https://prometheus.io/docs/concepts/data_model/#metric-names-and-labels), they should only be used in recording rules. So sanitizeMetricName(String metricName) should replace colons with underscores.

2. Handling of underscore prefix

String metricName = "__some_metric_name";
System.out.println(PrometheusNaming.sanitizeMetricName(metricName));
System.out.println(PrometheusNaming.sanitizeMetricName(metricName, Unit.SECONDS));

This prints:

__some_metric_name
_some_metric_name_seconds

Metric names should be allowed to start with __, this is only disallowed for labels. So sanitizeMetricName(String metricName, Unit unit) should not call sanitizeLabelName() and allow metric names starting with __.