Skip to content

Commit 45d753c

Browse files
authored
docs: Document OM2 (#2059)
Fixes #1954. ## Summary This adds the OpenMetrics 2.0 preview documentation and clarifies related naming behavior. - Add a dedicated OpenMetrics 2.0 preview page covering enablement, name preservation, feature flags, content negotiation, and native histograms. - Describe `io.prometheus.openmetrics2.enabled` by its observable behavior: metric names are preserved as written by the application. - Clarify that OM1/Prometheus text still apply suffix behavior, while OM2 does not append `_total` or unit suffixes automatically. - Document the OpenTelemetry exporter `preserve_names` option. ## Notes The behavior fix is split into #2058. This PR is docs-only. ## Validation - `mise run lint` - `git diff --check` --------- Signed-off-by: Gregor Zeitlinger <gregor.zeitlinger@grafana.com>
1 parent 49a25e7 commit 45d753c

5 files changed

Lines changed: 182 additions & 4 deletions

File tree

docs/content/config/config.md

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,24 @@ This works for all Metrics properties.
137137

138138
(1) Boolean value, `true` or `false`. Default see Javadoc.
139139

140+
## OpenMetrics 2.0 Properties
141+
142+
<!-- editorconfig-checker-disable -->
143+
144+
| Name | Javadoc | Note |
145+
| ---------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | ---- |
146+
| io.prometheus.openmetrics2.enabled | [OpenMetrics2Properties.getEnabled()](</client_java/api/io/prometheus/metrics/config/OpenMetrics2Properties.html#getEnabled()>) | (1) |
147+
| io.prometheus.openmetrics2.content_negotiation | [OpenMetrics2Properties.getContentNegotiation()](</client_java/api/io/prometheus/metrics/config/OpenMetrics2Properties.html#getContentNegotiation()>) | (1) |
148+
| io.prometheus.openmetrics2.composite_values | [OpenMetrics2Properties.getCompositeValues()](</client_java/api/io/prometheus/metrics/config/OpenMetrics2Properties.html#getCompositeValues()>) | (1) |
149+
| io.prometheus.openmetrics2.exemplar_compliance | [OpenMetrics2Properties.getExemplarCompliance()](</client_java/api/io/prometheus/metrics/config/OpenMetrics2Properties.html#getExemplarCompliance()>) | (1) |
150+
| io.prometheus.openmetrics2.native_histograms | [OpenMetrics2Properties.getNativeHistograms()](</client_java/api/io/prometheus/metrics/config/OpenMetrics2Properties.html#getNativeHistograms()>) | (1) |
151+
152+
<!-- editorconfig-checker-enable -->
153+
154+
(1) Boolean value, `true` or `false`. `enabled=true` switches OpenMetrics responses to the OM2
155+
writer, preserving metric names as written by the application. The other OM2 properties remain
156+
opt-in. All OpenMetrics 2.0 flags are experimental and default to `false`.
157+
140158
## Exporter Filter Properties
141159

142160
| Name | Javadoc | Note |
@@ -176,12 +194,14 @@ Only metrics starting with these prefixes will be exposed.<br/>
176194
| io.prometheus.exporter.opentelemetry.service_instance_id | [OpenTelemetryExporter.Builder.serviceInstanceId()](</client_java/api/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.Builder.html#serviceInstanceId(java.lang.String)>) | |
177195
| io.prometheus.exporter.opentelemetry.service_version | [OpenTelemetryExporter.Builder.serviceVersion()](</client_java/api/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.Builder.html#serviceVersion(java.lang.String)>) | |
178196
| io.prometheus.exporter.opentelemetry.resource_attributes | [OpenTelemetryExporter.Builder.resourceAttributes()](</client_java/api/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.Builder.html#resourceAttribute(java.lang.String,java.lang.String)>) | (3) |
197+
| io.prometheus.exporter.opentelemetry.preserve_names | [ExporterOpenTelemetryProperties.getPreserveNames()](</client_java/api/io/prometheus/metrics/config/ExporterOpenTelemetryProperties.html#getPreserveNames()>) | (4) |
179198

180199
<!-- markdownlint-disable MD033 -->
181200

182201
(1) Protocol can be `grpc` or `http/protobuf`.<br>
183202
(2) Format: `key1=value1,key2=value2`<br>
184-
(3) Format: `key1=value1,key2=value2`
203+
(3) Format: `key1=value1,key2=value2`<br>
204+
(4) Boolean value, `true` or `false`. Default is `false` for backward compatibility.
185205

186206
<!-- markdownlint-enable MD033 -->
187207

docs/content/exporters/formats.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@ All exporters the following exposition formats:
1111

1212
Moreover, gzip encoding is supported for each of these formats.
1313

14+
## OpenMetrics 2.0 Preview
15+
16+
The library also includes an experimental OpenMetrics 2.0 writer. It is disabled by default and
17+
must be enabled explicitly. See [OpenMetrics 2.0 Preview]({{< relref "./openmetrics2.md" >}}).
18+
1419
## Scraping with a Prometheus server
1520

1621
The Prometheus server sends an `Accept` header to specify which format is requested. By default, the
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
---
2+
title: OpenMetrics 2.0 Preview
3+
weight: 2
4+
---
5+
6+
The Prometheus Java client library includes experimental support for the OpenMetrics 2.0 text
7+
format.
8+
9+
{{< hint type=warning >}}
10+
OpenMetrics 2.0 support is opt-in, experimental, and subject to change while the specification is
11+
still in draft.
12+
{{< /hint >}}
13+
14+
{{< toc >}}
15+
16+
## Enable OpenMetrics 2.0
17+
18+
To switch OpenMetrics responses from the legacy OM1 writer to the OM2 writer, set:
19+
20+
```properties
21+
io.prometheus.openmetrics2.enabled=true
22+
```
23+
24+
Programmatic configuration:
25+
26+
```java
27+
PrometheusProperties properties = PrometheusProperties.builder()
28+
.enableOpenMetrics2(om2 -> {})
29+
.build();
30+
```
31+
32+
Enabling `enableOpenMetrics2(...)` also enables the top-level `enabled` flag automatically, so you
33+
only need to configure the sub-flags you want.
34+
35+
With `enabled=true` alone:
36+
37+
- OpenMetrics requests use the OM2 writer.
38+
- Metric names are preserved as written by the application.
39+
- Optional OM2 features such as `composite_values`, `exemplar_compliance`, and
40+
`native_histograms` remain off.
41+
42+
To enable OM2 only when the scraper explicitly requests `version=2.0.0`, set:
43+
44+
```properties
45+
io.prometheus.openmetrics2.enabled=true
46+
io.prometheus.openmetrics2.content_negotiation=true
47+
```
48+
49+
Programmatic equivalent:
50+
51+
```java
52+
PrometheusProperties properties = PrometheusProperties.builder()
53+
.enableOpenMetrics2(om2 -> om2.contentNegotiation(true))
54+
.build();
55+
```
56+
57+
## Naming Behavior
58+
59+
OpenMetrics 2.0 removes OM1 suffix rewriting.
60+
61+
- Counters do not get `_total` appended automatically.
62+
- Units do not get appended automatically.
63+
- Info metrics still end in `_info` because that is required by the spec.
64+
65+
Examples:
66+
67+
| Metric builder input | OM1 output | OM2 output |
68+
| ---------------------------------- | ----------------- | -------------- |
69+
| `Counter("events")` | `events_total` | `events` |
70+
| `Counter("events_total")` | `events_total` | `events_total` |
71+
| `Counter("req").unit(BYTES)` | `req_bytes_total` | `req` |
72+
| `Counter("req_bytes").unit(BYTES)` | `req_bytes_total` | `req_bytes` |
73+
| `Info("target")` | `target_info` | `target_info` |
74+
75+
This means OpenMetrics 2.0 does not apply OM1 suffix behavior such as appending `_total` or unit
76+
suffixes, while the legacy OpenMetrics 1.0 and Prometheus text formats keep that existing suffix
77+
behavior.
78+
79+
## Feature Flags
80+
81+
All OpenMetrics 2.0 flags default to `false`.
82+
83+
| Property | Effect |
84+
| ------------------------------------------------ | -------------------------------------------------------------------------------------- |
85+
| `io.prometheus.openmetrics2.enabled` | Metric names are preserved as written by the application. |
86+
| `io.prometheus.openmetrics2.content_negotiation` | Apply OM2 behavior only when the scraper requests `version=2.0.0`. |
87+
| `io.prometheus.openmetrics2.composite_values` | Emit histograms, summaries, and gauge histograms as single composite lines with `st@`. |
88+
| `io.prometheus.openmetrics2.exemplar_compliance` | Emit only OM2-compliant exemplars with timestamps. |
89+
| `io.prometheus.openmetrics2.native_histograms` | Emit OM2 native histogram text fields. |
90+
91+
Enable all flags at once:
92+
93+
```java
94+
PrometheusProperties properties = PrometheusProperties.builder()
95+
.enableOpenMetrics2(om2 -> om2.enableAll())
96+
.build();
97+
```
98+
99+
Equivalent properties:
100+
101+
```properties
102+
io.prometheus.openmetrics2.enabled=true
103+
io.prometheus.openmetrics2.content_negotiation=true
104+
io.prometheus.openmetrics2.composite_values=true
105+
io.prometheus.openmetrics2.exemplar_compliance=true
106+
io.prometheus.openmetrics2.native_histograms=true
107+
```
108+
109+
## Content Negotiation
110+
111+
If `content_negotiation=false`, OpenMetrics 2.0 behavior is applied to OpenMetrics responses even
112+
if the scraper requested OpenMetrics 1.0.
113+
114+
If `content_negotiation=true`, OpenMetrics 2.0 behavior is only used when the scraper explicitly
115+
requests `version=2.0.0`. Otherwise the legacy OpenMetrics 1.0 response is returned.
116+
117+
## Native Histograms
118+
119+
With `io.prometheus.openmetrics2.native_histograms=true`, the OpenMetrics 2.0 writer emits native
120+
histogram fields such as:
121+
122+
- `schema`
123+
- `zero_threshold`
124+
- `zero_count`
125+
- positive and negative spans
126+
- positive and negative buckets
127+
128+
OM2 native histogram output can coexist with classic histogram buckets. When both are present, the
129+
native histogram sample is written first.

docs/content/getting-started/metric-types.md

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,13 @@ serviceTimeSeconds.inc(Unit.millisToSeconds(200));
3737
The resulting counter has the value `0.2`. As `SECONDS` is the standard time unit in Prometheus, the
3838
`Unit` utility class has methods to convert other time units to seconds.
3939

40-
As defined in [OpenMetrics](https://openmetrics.io/), counter metric names must have the `_total`
41-
suffix. If you create a counter without the `_total` suffix the suffix will be appended
42-
automatically.
40+
For the default OpenMetrics 1.0 and Prometheus text formats, counters are exposed with the
41+
`_total` suffix. You can name a counter either `service_time_seconds` or
42+
`service_time_seconds_total`; the exposed name will be `service_time_seconds_total` in both cases.
43+
44+
The experimental OpenMetrics 2.0 writer behaves differently: It preserves metric names instead of
45+
appending `_total` or unit suffixes automatically. In OpenMetrics 2.0, `_total` is recommended for
46+
counters, but not enforced by the Java client.
4347

4448
## Gauge
4549

docs/content/otel/names.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,26 @@ The main steps when converting OpenTelemetry metric names to Prometheus metric n
2222
- If the metric has a unit, append the unit to the metric name, like `_seconds`.
2323
- If the metric type has a suffix, append it, like `_total` for counters.
2424

25+
## `preserve_names`
26+
27+
The Prometheus Java client library can also export its own metrics to OpenTelemetry using the
28+
[OpenTelemetryExporter](/client_java/api/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.html). <!-- editorconfig-checker-disable-line -->
29+
30+
For that exporter, `io.prometheus.exporter.opentelemetry.preserve_names=true` preserves metric
31+
names exactly as they were written in the Prometheus Java client.
32+
33+
Examples:
34+
35+
| Prometheus Java metric | Default OTel export | With `preserve_names=true` |
36+
| ---------------------------------- | --------------------- | --------------------------- |
37+
| `Counter("events")` | `events` | `events` |
38+
| `Counter("events_total")` | `events` | `events_total` |
39+
| `Counter("req").unit(BYTES)` | name `req`, unit `By` | name `req`, unit `By` |
40+
| `Counter("req_bytes").unit(BYTES)` | name `req`, unit `By` | name `req_bytes`, unit `By` |
41+
42+
Today the default is `false` for backward compatibility. It is planned to change to `true` in the
43+
next major release.
44+
2545
## Dots in Metric and Label Names
2646

2747
OpenTelemetry defines not only a line protocol, but also _semantic conventions_, i.e. standardized

0 commit comments

Comments
 (0)