Skip to content

feat: compositeValues and exemplarCompliance flags for OM2 writer#1991

Open
zeitlinger wants to merge 4 commits intomainfrom
feat/om2-composite-values
Open

feat: compositeValues and exemplarCompliance flags for OM2 writer#1991
zeitlinger wants to merge 4 commits intomainfrom
feat/om2-composite-values

Conversation

@zeitlinger
Copy link
Copy Markdown
Member

@zeitlinger zeitlinger commented Apr 9, 2026

Fixes #1989

Summary

  • compositeValues=true: Histogram, GaugeHistogram, and Summary are
    written as a single composite-value line per the OM2 spec:

    foo {count:17,sum:324789.3,bucket:[0.1:8,0.25:10,0.5:11,1.0:14,+Inf:17]} 1520879607.789 st@1520430000.123
    bar {count:17,sum:324789.3,quantile:[0.95:123.7,0.99:150.0]}
    
    • Bucket counts are cumulative (same semantics as OM1 _bucket lines)
    • GaugeHistogram uses gcount/gsum per spec (note: the tracking issue
      says "count/sum" but the spec is explicit about gcount/gsum)
    • Created timestamp moves inline as st@; no separate _created line
    • Latest exemplar (if present) is appended inline
    • No separate _bucket, _count, _sum lines emitted
    • When compositeValues=false (default), output is unchanged from before
  • exemplarCompliance=true: Exemplars without a timestamp are silently
    dropped. The OM2 spec mandates that all exemplars MUST have a timestamp.
    The 128-char LabelSet limit from OM1 was never enforced in the writer, so
    no change needed there.

Test plan

  • testCompositeHistogram — basic single-line histogram output
  • testCompositeHistogramWithLabelsTimestampAndCreated — labels, scrape
    timestamp, and st@ start timestamp
  • testCompositeHistogramWithExemplar — exemplar appended inline
  • testCompositeGaugeHistogramgcount/gsum fields
  • testCompositeSummary — basic single-line summary output
  • testCompositeSummaryWithCreatedAndExemplarst@ + exemplar
  • testExemplarComplianceSkipsExemplarWithoutTimestamp — compliance mode
    drops exemplars without timestamps; default mode still emits them
  • All 22 existing tests pass unchanged (non-composite path unaffected)

- compositeValues=true: write Histogram/GaugeHistogram/Summary as a
  single composite-value line per the OM2 spec, e.g.
    foo {count:17,sum:324789.3,bucket:[0.1:8,0.25:10,+Inf:17]} st@0.5
  GaugeHistogram uses gcount/gsum per spec. Replaces separate _bucket,
  _count, _sum, _created lines; created timestamp moves inline as st@.
  Exemplar (latest) is appended inline when present.
- exemplarCompliance=true: skip exemplars without a timestamp, as the
  OM2 spec mandates timestamps on all exemplars (MUST).

Signed-off-by: Gregor Zeitlinger <gregor.zeitlinger@grafana.com>
@zeitlinger zeitlinger marked this pull request as ready for review April 10, 2026 12:09
When compositeValues=false, OM2 histogram and summary output is
identical to OM1 format. Delegate to om1Writer instead of duplicating
writeClassicHistogramBuckets, writeNonCompositeSummaryDataPoint, and
writeCountAndSum.

Signed-off-by: Gregor Zeitlinger <gregor.zeitlinger@grafana.com>
Apply the same delegation pattern as histogram/summary: when
exemplarCompliance=false (default), delegate writeScrapeTimestampAndExemplar
and writeExemplar to om1Writer. When exemplarCompliance=true, apply the
OM2 spec requirement (drop exemplars without timestamps) then delegate
the actual writing to om1Writer.writeExemplar.

Extracts writeExemplar from om1Writer.writeScrapeTimestampAndExemplar so
OM2 can delegate exemplar formatting without duplicating it.

Signed-off-by: Gregor Zeitlinger <gregor.zeitlinger@grafana.com>
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.

OM2 - CompositeValue + start timestamp + exemplar compliance

1 participant