|
| 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. |
0 commit comments