Skip to content

expfmt: omit incompatible OpenMetrics unit metadata - #1012

Open
itsmeasadali wants to merge 1 commit into
prometheus:mainfrom
itsmeasadali:codex/prometheus-openmetrics-unit-suffix
Open

itsmeasadali wants to merge 1 commit into
prometheus:mainfrom
itsmeasadali:codex/prometheus-openmetrics-unit-suffix

Conversation

@itsmeasadali

Copy link
Copy Markdown

Fixes #1005.

OpenMetrics 1.0 requires a non-empty UNIT to match the metric family name's underscore-separated suffix. After #877 stopped adding units to metric names, the encoder could still emit incompatible UNIT metadata, which Prometheus rejects and which can fail the whole scrape.

This proposes the omission approach described in the issue: emit a non-empty UNIT only when it matches the family name, after the existing counter _total handling. Sample names and values are unchanged. Nil/empty units and valid units retain their behavior. The separate OpenMetrics 2.0 encoder is unchanged.

Add 12 table-driven regression cases for matching/mismatching units, missing separators, partial suffixes, counter/gauge suffix handling, compound units, nil and empty units, byte counts, and input immutability. Update existing expectations that previously required incompatible UNIT lines.

Validation on Windows amd64 with Go 1.27.1:

  • go test ./expfmt -count=1 passed.
  • go vet ./... passed.
  • Root tests passed excluding TestMissingBearerAuthFile, whose Windows error-message mismatch also reproduces without this change. The unfiltered root suite is not reported as fully passing.
  • Assets tests passed with original LF fixtures.
  • The real Prometheus v0.315.0 OpenMetrics parser rejected the old mismatched-unit output and accepted the fixed output; matching-unit output stayed accepted. This was parser interoperability testing, not a running-server scrape test.
  • golangci-lint 2.13.1 run ./... and go mod tidy -diff passed on a clean LF checkout.
  • Local race checks could not run because a usable C compiler was unavailable. The Go 1.26 CI matrix was not verified locally.

@roidelapluie @gotjosh: does omitting incompatible UNIT metadata look like the preferred resolution while preserving metric names?

Signed-off-by: Asad Ali <asad@ztabs.co>

@bwplotka bwplotka left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that's a valid solution, given our parser enforcement and the fact we add unit support after some time, thanks!

Ideally we notify user in some way this happens, but this is a good start

}
}

func TestCreateOpenMetricsUnitSuffix(t *testing.T) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we move this to the existing table test, to avoid test duplication?

@dashpole
dashpole self-requested a review October 14, 2026 16:01
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.

expfmt: OpenMetrics 1.0 output with a unit that is not a name suffix fails the whole scrape in Prometheus

2 participants