Skip to content

feat: move suffix handling to scrape time with OTel preserve_names#1947

Closed
zeitlinger wants to merge 3 commits intomainfrom
scrape-time-suffix-handling
Closed

feat: move suffix handling to scrape time with OTel preserve_names#1947
zeitlinger wants to merge 3 commits intomainfrom
scrape-time-suffix-handling

Conversation

@zeitlinger
Copy link
Member

@zeitlinger zeitlinger commented Mar 14, 2026

Summary

Moves metric name suffix handling (_total, _info, unit suffixes) from creation time to scrape time. Closes #1941, part of #1942.

  • OM1: smart-appends suffixes (skips if already present)
  • OTel: legacy path strips _total + unit suffix; preserve_names=true passes names through exactly as the user wrote them
  • Registry: detects cross-format name collisions at registration time

Key changes

  • Remove all reserved metric name suffixes from PrometheusNaming
  • Store original user-provided name separately from exposition base name in MetricMetadata (originalName vs expositionBaseName)
  • Add preserve_names config to ExporterOpenTelemetryProperties
  • Smart-append logic in OM1/protobuf writers for _total and _info
  • Two-layer collision detection in PrometheusRegistry (base name + exposition names)

Key table

User provides OM1 OTel OTel preserve
Counter("events") events_total events events
Counter("events_total") events_total events events_total
Counter("req").unit(BYTES) req_bytes_total name req, unit By name req, unit By
Counter("req_bytes").unit(BYTES) req_bytes_total name req, unit By name req_bytes, unit By
Gauge("events_total") events_total events_total events_total

Test plan

  • mise run build passes (formatting, static analysis, checkstyle)
  • mise run test passes (all unit tests)
  • New tests for MetricMetadata 5-arg constructor and field accessors
  • New tests for OTel preserve_names=true with units, with unit already in name, and without unit
  • Existing PrometheusRegistryTest covers collision detection
  • Integration tests (mise run test-all)
  • Acceptance tests (mise run acceptance-test)

The OM2 writer selection previously activated when any feature flag was
set, but there was no way to just enable OM2 without opting into a
specific feature. This adds an explicit `enabled` gate
(io.prometheus.openmetrics2.enabled) as the single control for OM2
writer selection. Feature flags alone no longer activate OM2.

The programmatic `enableOpenMetrics2()` configurator sets enabled=true
implicitly, matching its name.
Signed-off-by: Gregor Zeitlinger <gregor.zeitlinger@grafana.com>
Move metric name suffix handling (_total, _info, unit suffixes) from
creation time to scrape time. Each format writer now owns its suffix
conventions:

- OM1: smart-appends suffixes (skip if already present)
- OTel: legacy path strips _total + unit; preserve_names=true passes
  names through exactly as the user wrote them
- Registry detects cross-format name collisions at registration time

Key changes:
- Remove all reserved metric name suffixes from PrometheusNaming
- Store original user-provided name separately from exposition base
  name in MetricMetadata (originalName vs expositionBaseName)
- Add preserve_names config to ExporterOpenTelemetryProperties
- Smart-append logic in OM1/protobuf writers for _total and _info
- Two-layer collision detection in PrometheusRegistry

Closes #1941
Signed-off-by: Gregor Zeitlinger <gregor.zeitlinger@grafana.com>
The OM2 writer now uses expositionBaseName instead of appending
_total (counters) or unit suffixes. The _info suffix is enforced
per the OM2 spec (MUST). Tests updated to verify OM2-specific
output rather than asserting identity with OM1.
Signed-off-by: Gregor Zeitlinger <gregor.zeitlinger@grafana.com>
@zeitlinger zeitlinger force-pushed the scrape-time-suffix-handling branch from e4a579d to 9ebf25a Compare March 17, 2026 08:48
@zeitlinger zeitlinger marked this pull request as ready for review March 17, 2026 10:02
@zeitlinger zeitlinger marked this pull request as draft March 17, 2026 10:10
@zeitlinger
Copy link
Member Author

Superseded by the split PRs: #1955 (core + OM1 writers), #1956 (OTel preserve_names), #1957 (OM2 writer no-suffix).

@zeitlinger zeitlinger closed this Mar 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Move suffix handling from creation time to scrape time (current release)

1 participant