-
Notifications
You must be signed in to change notification settings - Fork 832
Open
Description
The OpenMetrics 2.0 spec is nearing completion. We should start implementing experimental support to validate the design and provide early feedback to the spec authors.
All features are behind opt-in flags (off by default) so there's no risk to existing users. The spec is still in draft, so the API is explicitly experimental and subject to change.
Flag design
Top-level gate + individual feature flags. The top-level gate (enableOpenMetrics2())
has no behavioral effect by itself — it just enables the sub-flags. Each sub-flag
independently controls one OM2 feature.
Java builder API:
PrometheusConfig config = PrometheusConfig.builder()
.enableOpenMetrics2(om2 -> om2
.contentNegotiation(true) // version=2.0.0 content type
.disableSuffixAppending(true) // _total, unit suffixes
.compositeValues(true) // single-line histogram/summary + st@
.exemplarCompliance(true) // mandatory timestamps, no size limit
)
.build();
// Or enable everything at once
PrometheusConfig config = PrometheusConfig.builder()
.enableOpenMetrics2(om2 -> om2.enableAll())
.build();Properties equivalent:
io.prometheus.openMetrics2.contentNegotiation=true
io.prometheus.openMetrics2.disableSuffixAppending=true
io.prometheus.openMetrics2.compositeValues=true
io.prometheus.openMetrics2.exemplarCompliance=true| Flag | Description | Spec reference |
|---|---|---|
contentNegotiation |
Gate OM2 features behind content negotiation: only apply them when the scraper requests version=2.0.0, and return OM1 format when the scraper requests OM1. Without this flag, OM2 features are applied even if the scraper requests OM1 |
Content Type |
disableSuffixAppending |
Don't append _total (Counter) or unit suffixes. OM2 downgrades these from MUST to SHOULD. This flag will remain useful even after OM2 is stable, since OM2 still says SHOULD (not MUST NOT) for these suffixes |
Counter, MetricFamily |
compositeValues |
Single-line Histogram/Summary/GaugeHistogram with inline st@ start timestamp. Also: reserved label prefix __, Histogram Count/Sum always present, bucket values may be float |
CompositeValue, Overall Structure |
exemplarCompliance |
Exemplar timestamps always emitted (MUST in OM2), 128-char LabelSet hard limit removed | Exemplar |
nativeHistograms |
Exponential buckets with schema, zero threshold/count, pos/neg spans | Native Buckets |
All flags default to false.
PR structure
PR 0: Flag infrastructure
│ enableOpenMetrics2() builder, OpenMetrics2Config class,
│ properties parsing — no behavioral changes
│
├── PR 1: disableSuffixAppending + contentNegotiation
│
├── PR 2: compositeValues + exemplarCompliance
│
└── PR 3: nativeHistograms
PRs 1–3 all depend only on PR 0 and can be done in parallel.
PR 0: Flag infrastructure
- Add
enableOpenMetrics2()toPrometheusConfig.Builder - Add
OpenMetrics2Configclass with all flag fields (defaulting tofalse) - Wire up properties parsing for
io.prometheus.openMetrics2.* - No behavioral changes — just the config plumbing
PR 1: Suffix relaxation + content negotiation
disableSuffixAppending: suppress_totalsuffix on Counters, suppress unit suffix on metric namescontentNegotiation: only return OM2 format when the scraper explicitly requestsversion=2.0.0. Without this flag, OM2 features are applied even if the scraper requests OM1- Spec: Counter
_total— "SHOULD have the suffix_total" (was MUST in OM1). Unit — "SHOULD be a suffix" (was MUST in OM1)
PR 2: CompositeValue + start timestamp + exemplar compliance
compositeValues:- Histogram as single line:
foo {count:17,sum:324789.3,bucket:[0.1:8,0.25:10,0.5:11,1.0:14,+Inf:17]} 1.0 st@0.5 - Summary as single line:
bar {count:17,sum:324789.3,quantile:[0.95:123.7,0.99:150.0]} - GaugeHistogram as single line with
count/sum(notgcount/gsum) _createdlines replaced by inlinest@start timestamp_count,_sum,_bucketsuffixed lines no longer emitted for these types- Reserved label prefix changed from
_to__ - Histogram/GaugeHistogram Count and Sum always present (MUST, was SHOULD for Sum)
- Histogram bucket values may be float (SHOULD be integer, was MUST)
- Spec: CompositeValue, Histogram, Summary
- Histogram as single line:
exemplarCompliance:- Exemplar timestamps always emitted (OM2: MUST, was MAY in OM1)
- 128-char LabelSet hard limit removed
PR 3: Native histograms
nativeHistograms:- Exponential bucket model: schema (-4 to 8), zero threshold/count, positive/negative spans and buckets
- Text serialization:
{count:X,sum:X,schema:N,zero_threshold:F,zero_count:X,positive_spans:[...],positive_buckets:[...]} - Can coexist with classic buckets on separate lines (native line MUST come first)
- GaugeHistogram also supports native buckets (same syntax)
- Multiple exemplars per native histogram sample
- Spec: Native Buckets, Histogram
- No known blockers:
- NHCB federation (#312) — still open but WG decided it won't change the spec (solution is a Prometheus scraping config, not an OM change)
- Exemplar timestamps (#308) — closed, resolved as MUST. We're aligned
Notes
- UTF-8 metric/label names are already supported (shipped in a previous release)
- The OM2 spec is still draft — some details may change, but no known blockers for the features covered here
- See also: OM 2.0 upgrade guide for SDK maintainers
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels