-
Notifications
You must be signed in to change notification settings - Fork 1k
Sanitize metric names for the Prometheus client #4866
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Sanitize metric names for the Prometheus client #4866
Conversation
We need to sanitize metric names for the Prometheus client otherwise it fails with something like this: java.lang.IllegalArgumentException: 'jvm_info': Illegal metric name. The metric name must not include the '_info' suffix. This can be reproduced with: Gauge.builder("test.info", () -> 1).register(registry); The name of this Gauge will be test_info in Prometheus that is invalid according to the new client, see PrometheusNaming: https://github.com/prometheus/client_java/blob/8bb75446c6dca2a4e2c074e39fe34c1b061b028a/prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/PrometheusNaming.java#L37-L40 We have built-in instrumentation that fails this validation too, see JvmInfoMetrics: https://github.com/micrometer-metrics/micrometer/blob/966f5fe953a69c315b44bf4f63adf101a060bbfb/micrometer-core/src/main/java/io/micrometer/core/instrument/binder/jvm/JvmInfoMetrics.java#L32 If we don't want to break this, we need to sanitize the invalid suffixes. Please check the tests because the behavior can be unexpected sometimes: - If you create a Micrometer Gauge named test.info, the name of the Prometheus gauge will be test_info (since the registry removes but the Prometheus client adds back the `_info` suffix). - If you create a Micrometer Counter named test.total, the name of the Prometheus counter will be test_total (since the registry removes but the Prometheus client adds back the _total suffix). - If you create a Micrometer Counter named test.info, the name of the Prometheus counter will be test_total (since the registry removes the _info suffix and the Prometheus client adds the _total suffix for counters). - If you create a Micrometer Gauge named test.total, the name of the Prometheus counter will be test (since the registry removes the _total suffix and the Prometheus client does not add _info suffix for gauges). - Similarly, _created and _bucket will be removed otherwise the the Prometheus client will fail.
The client_java provides methods
I think the best solution is to call these before passing Micrometer names to the Prometheus library. For context here are two subtle facts about OpenMetric naming: Metric Name != Sample NameThere's a difference between the "metric name" and the "sample name". Here's an example from the OpenMetrics spec:
The metric name is This is more obvious when you have different sample names for one metric, like with counters:
Here, the metric name is The Prometheus client library stores the metric name (without suffix) and appends suffixes when metrics are exposed in OpenMetrics text format. Prometheus will support arbitrary UTF-8 Characters in the FuturePrometheus metric and label names currently allow only a very restricted set of characters, while OpenTelemetry metric and label names support arbitrary UTF-8 characters. This is annoying for users who store OpenTelemetry metrics in a Prometheus database, because the metric names get converted under that hood (for example The Prometheus community want to fix this by allowing arbitrary UTF-8 characters in Prometheus. There is currently discussion how to implement this (see this doc). The Prometheus Anyway, if you use |
This is tricky, because afaik Micrometer does not have Info metrics and uses Gauge to represent them. Possible solutions:
|
Thanks for the review @fstab. I agree we still need to update our
The PR right now does this except it does not check the value of the gauge. This could break some users who don't want that behavior, but it seems like a reasonable assumption. We'll have to see if we can get some early feedback from users on this. |
I think it is a good idea but that will not change the weird behavior above. I updated this PR with it, it should mean less code but similar behavior.
Oops, I meant to say a third name above: The issue here is that we have a Micrometer
Even if the metric name is
In order to do this, we need to remove the
I want to do emoji-metrics. ❤️ 😄
I updated the PR. It does not solve the weird behavior but it means less code for us and we will follow the changes in the sanitization logic out of the box. |
We need to sanitize metric names for the Prometheus client otherwise it fails with something like this:
This can be reproduced with:
The name of this
Gauge
will betest_info
in Prometheus that is invalid according to the new client, seePrometheusNaming
.We have built-in instrumentation that fails this validation too (see
JvmInfoMetrics
):If we don't want to break this, we need to sanitize the invalid suffixes.
Please check the tests because the behavior can be unexpected sometimes:
Gauge
namedtest.info
, the name of Prometheus gauge will betest_info
(since the registry removes but the Prometheus client adds back the_info
suffix).Counter
namedtest.total
, the name of the Prometheus counter will betest_total
(since the registry removes but the Prometheus client adds back the_total
suffix).Counter
namedtest.info
, the name of the Prometheus counter will betest_total
(since the registry removes the_info
suffix and the Prometheus client adds the_total
suffix for counters).Gauge
namedtest.total
, the name of the Prometheus counter will betest
(since the registry removes the_total
suffix and the Prometheus client does not add_info
suffix for gauges)._created
and_bucket
will be removed otherwise the Prometheus client will fail.