[Exporter.Prometheus] Sanitize metric unit#7033
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #7033 +/- ##
==========================================
+ Coverage 88.56% 88.58% +0.02%
==========================================
Files 270 270
Lines 12894 12909 +15
==========================================
+ Hits 11419 11435 +16
+ Misses 1475 1474 -1
Flags with carried forward coverage won't be shown. Click here to find out more.
|
Co-authored-by: Martin Costello <martin@martincostello.com>
There was a problem hiding this comment.
Pull request overview
This PR fixes malformed Prometheus metric names by sanitizing metric unit strings before appending them to metric names, addressing cases like Azure Cosmos DB units containing invalid characters (e.g., # RU) and handling multiple / characters in units.
Changes:
- Added unit sanitization logic and applied it when computing the unit suffix in
PrometheusMetric. - Updated/added unit-related unit tests, including multi-slash and special-character unit scenarios.
- Documented the fix in the Prometheus HttpListener and AspNetCore exporter changelogs.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/PrometheusMetricTests.cs | Updates expected name for multi-slash units and adds focused tests for unit sanitization behavior. |
| src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusMetric.cs | Introduces SanitizeMetricUnit and ensures units are sanitized before being appended to metric names. |
| src/OpenTelemetry.Exporter.Prometheus.HttpListener/CHANGELOG.md | Records the HttpListener exporter fix for invalid unit characters. |
| src/OpenTelemetry.Exporter.Prometheus.AspNetCore/CHANGELOG.md | Records the AspNetCore exporter fix for invalid unit characters. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
@nabutabu Please address the review comments from Copilot. |
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…ometheusMetric.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…ometheusMetric.cs Co-authored-by: Martin Costello <martin@martincostello.com>
|
@nabutabu, could you please check this comment occuring on the similar implementation? Thank you for pointing this out. I wasn't aware of PR #7033 when I submitted this. After reviewing it, both PRs take the same I'm happy to close this PR in favor of #7033 since it was submitted first and already has maintainer review. I'll keep a closer eye on open PRs in the future. Happy to contribute on other open issues! Originally posted by @Nik-Reddy in #7063 (comment) |
|
Hi @nabutabu, nice work on this PR! I took a closer look (I had independently worked on the same issue in #7063 before realizing yours was first) and have a couple of observations:
Happy to help with a follow-up commit if needed! |
|
I reviewed the 1. Trailing underscores not strippedThe method strips leading // Current: only strips leading
return result.Length > 0 && result[0] == '_'
? result.Substring(1)
: result;This means:
Per @tillig's original issue description: Fix — replace the return block with: var result = sb?.ToString() ?? metricUnit;
return result.Trim('_');This handles both leading AND trailing underscores in one call, and is simpler than the current leading-only check. 2. Test expectations need updatingTwo test cases assert the wrong expected values (with trailing underscores):
3. StringBuilder allocation (minor)The Copilot review flagged that Happy to submit a follow-up PR with these fixes found to be helpful. |
|
@Nik-Reddy, if you are fine, you could provide a diff here to be included by us in this PR. |
Fixes #6187
Changes
The Prometheus exporter was not sanitizing metric unit strings before appending
them to the metric name. This caused malformed metric names when units contained
characters invalid in Prometheus (e.g.
# RUfrom Azure Cosmos DB), whichPrometheus silently drops because
#denotes a comment line in the text format.A second related bug was also fixed: unit strings with multiple
/characters(e.g.
req/s/extra) only had the first/converted to_per_, leavingsubsequent slashes in the final name, which also violates the Prometheus naming
rules (
[a-zA-Z_][a-zA-Z0-9_]*).It mets OTel spec criteria; https://github.com/open-telemetry/opentelemetry-specification/blob/b2f923fb1650dde1f061507908b834035506a796/specification/compatibility/prometheus_and_openmetrics.md#metric-metadata-1
Merge requirement checklist
CHANGELOG.mdfiles updated for non-trivial changes