-
Notifications
You must be signed in to change notification settings - Fork 1.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
Gaugewill betest_infoin 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:
Gaugenamedtest.info, the name of Prometheus gauge will betest_info(since the registry removes but the Prometheus client adds back the_infosuffix).Counternamedtest.total, the name of the Prometheus counter will betest_total(since the registry removes but the Prometheus client adds back the_totalsuffix).Counternamedtest.info, the name of the Prometheus counter will betest_total(since the registry removes the_infosuffix and the Prometheus client adds the_totalsuffix for counters).Gaugenamedtest.total, the name of the Prometheus counter will betest(since the registry removes the_totalsuffix and the Prometheus client does not add_infosuffix for gauges)._createdand_bucketwill be removed otherwise the Prometheus client will fail.