Skip to content

Fix Prometheus exporter to sanitize malformed unit strings#7063

Closed
Nik-Reddy wants to merge 1 commit intoopen-telemetry:mainfrom
Nik-Reddy:fix/prometheus-malformed-unit-6187
Closed

Fix Prometheus exporter to sanitize malformed unit strings#7063
Nik-Reddy wants to merge 1 commit intoopen-telemetry:mainfrom
Nik-Reddy:fix/prometheus-malformed-unit-6187

Conversation

@Nik-Reddy
Copy link
Copy Markdown

Description

Add SanitizeUnitName() to strip invalid characters from metric unit strings before they are used in Prometheus metric names. Units like '# RU' (from Azure Cosmos DB) previously produced invalid metric names containing comment markers and spaces.

The sanitizer replaces non-alphanumeric characters with underscores, collapses consecutive underscores, and strips leading/trailing underscores. Fully invalid units (e.g. '#') result in an empty string so no unit suffix is appended.

Fixes #6187

The Prometheus exporter does not sanitize unit strings after processing in
GetUnit(). When upstream libraries set malformed units (e.g., Azure Cosmos DB
uses # RU), the resulting Prometheus metric name contains invalid characters
like # and spaces, which breaks Prometheus scraping because # is interpreted
as a comment marker.

Expected behavior

Malformed unit strings should be sanitized so the final Prometheus metric name
only contains valid characters ([a-zA-Z0-9_]).

  • # RU → metric suffix becomes _RU
  • # → treated as unitless (no suffix)
  • #_R.U. → metric suffix becomes _R_U

Actual behavior

The unit string # RU is appended as-is, producing metric names like
azure_cosmosdb_client_operation_request_charge_# RU_bucket which Prometheus
cannot scrape.

Steps to reproduce

  1. Create a Meter with unit set to # RU
  2. Configure OpenTelemetry with the Prometheus exporter
  3. Query the Prometheus metrics endpoint
  4. Observe the metric name contains # and spaces

Environment

  • OpenTelemetry .NET SDK
  • .NET 8.0
  • Package: OpenTelemetry.Exporter.Prometheus.HttpListener

Changes

  • Added SanitizeUnitName() method to PrometheusMetric.cs that replaces
    invalid characters with _, collapses consecutive underscores, and strips
    leading/trailing underscores
  • Wired it as the final step in GetUnit() before returning
  • Added 9 new test cases for malformed unit scenarios
  • Updated 1 existing test expectation for multi-slash units

Type of change

  • Bug fix (non-breaking change which fixes an issue)

How Has This Been Tested?

All 188 tests pass via dotnet test.

Does This PR Require a Contrib Repo Change?

  • No

Merge Requirement Checklist:

  • CONTRIBUTING guidelines followed
    (license requirements, nullable enabled, static analysis, etc.)
  • Unit tests added/updated
  • Appropriate CHANGELOG.md files updated for non-trivial changes
  • Changes in public API reviewed (if applicable)

Add SanitizeUnitName() to strip invalid characters from metric unit
strings before they are used in Prometheus metric names. Units like
'# RU' (from Azure Cosmos DB) previously produced invalid metric
names containing comment markers and spaces.

The sanitizer replaces non-alphanumeric characters with underscores,
collapses consecutive underscores, and strips leading/trailing
underscores. Fully invalid units (e.g. '#') result in an empty
string so no unit suffix is appended.

Fixes open-telemetry#6187
@Nik-Reddy Nik-Reddy requested a review from a team as a code owner April 12, 2026 21:39
@linux-foundation-easycla
Copy link
Copy Markdown

linux-foundation-easycla Bot commented Apr 12, 2026

CLA Signed
The committers listed above are authorized under a signed CLA.

  • ✅ login: Nik-Reddy / name: Nik-Reddy (f8dbc36)

@github-actions github-actions Bot added the pkg:OpenTelemetry.Exporter.Prometheus.HttpListener Issues related to OpenTelemetry.Exporter.Prometheus.HttpListener NuGet package label Apr 12, 2026
@martincostello
Copy link
Copy Markdown
Member

Thanks for the PR, but this appears to duplicate the work already done in #7033?

@Nik-Reddy
Copy link
Copy Markdown
Author

Nik-Reddy commented Apr 12, 2026

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
approach of sanitizing the unit string in GetUnit() before it's returned.

I'm happy to close this PR in favor of #7033 since it was submitted first and already has maintainer review.
I do notice one difference: my implementation also strips trailing underscores (e.g., "##/RU!""RU" vs "RU_" in #7033), which might be worth incorporating there.

I'll keep a closer eye on open PRs in the future. Happy to contribute on other open issues!

@Kielek
Copy link
Copy Markdown
Member

Kielek commented Apr 13, 2026

@Nik-Reddy, thanks for your contribution. I have copied your comment to the other PR.
We are looking always for the contribution to review existing PRs if you are interested in helping in this way.

@Kielek Kielek closed this Apr 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pkg:OpenTelemetry.Exporter.Prometheus.HttpListener Issues related to OpenTelemetry.Exporter.Prometheus.HttpListener NuGet package

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[bug] Prometheus exporter does not handle malformed units strings

3 participants