Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion docs/content/config/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,24 @@ This works for all Metrics properties.

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

## OpenMetrics 2.0 Properties

<!-- editorconfig-checker-disable -->

| Name | Javadoc | Note |
| ---------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | ---- |
| io.prometheus.openmetrics2.enabled | [OpenMetrics2Properties.getEnabled()](</client_java/api/io/prometheus/metrics/config/OpenMetrics2Properties.html#getEnabled()>) | (1) |
| io.prometheus.openmetrics2.content_negotiation | [OpenMetrics2Properties.getContentNegotiation()](</client_java/api/io/prometheus/metrics/config/OpenMetrics2Properties.html#getContentNegotiation()>) | (1) |
| io.prometheus.openmetrics2.composite_values | [OpenMetrics2Properties.getCompositeValues()](</client_java/api/io/prometheus/metrics/config/OpenMetrics2Properties.html#getCompositeValues()>) | (1) |
| io.prometheus.openmetrics2.exemplar_compliance | [OpenMetrics2Properties.getExemplarCompliance()](</client_java/api/io/prometheus/metrics/config/OpenMetrics2Properties.html#getExemplarCompliance()>) | (1) |
| io.prometheus.openmetrics2.native_histograms | [OpenMetrics2Properties.getNativeHistograms()](</client_java/api/io/prometheus/metrics/config/OpenMetrics2Properties.html#getNativeHistograms()>) | (1) |

<!-- editorconfig-checker-enable -->

(1) Boolean value, `true` or `false`. `enabled=true` switches OpenMetrics responses to the OM2
writer, preserving metric names as written by the application. The other OM2 properties remain
opt-in. All OpenMetrics 2.0 flags are experimental and default to `false`.

## Exporter Filter Properties

<!-- editorconfig-checker-disable -->
Expand Down Expand Up @@ -198,14 +216,16 @@ Only metrics starting with these prefixes will be exposed.<br/>
| 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)>) | |
| io.prometheus.exporter.opentelemetry.service_version | [OpenTelemetryExporter.Builder.serviceVersion()](</client_java/api/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.Builder.html#serviceVersion(java.lang.String)>) | |
| 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) |
| io.prometheus.exporter.opentelemetry.preserve_names | [ExporterOpenTelemetryProperties.getPreserveNames()](</client_java/api/io/prometheus/metrics/config/ExporterOpenTelemetryProperties.html#getPreserveNames()>) | (4) |

<!-- editorconfig-checker-enable -->

<!-- markdownlint-disable MD033 -->

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

<!-- markdownlint-enable MD033 -->

Expand Down
5 changes: 5 additions & 0 deletions docs/content/exporters/formats.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ All exporters the following exposition formats:

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

## OpenMetrics 2.0 Preview

The library also includes an experimental OpenMetrics 2.0 writer. It is disabled by default and
must be enabled explicitly. See [OpenMetrics 2.0 Preview]({{< relref "./openmetrics2.md" >}}).

## Scraping with a Prometheus server

The Prometheus server sends an `Accept` header to specify which format is requested. By default, the
Expand Down
129 changes: 129 additions & 0 deletions docs/content/exporters/openmetrics2.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
---
title: OpenMetrics 2.0 Preview
weight: 2
---

The Prometheus Java client library includes experimental support for the OpenMetrics 2.0 text
format.

{{< hint type=warning >}}
OpenMetrics 2.0 support is opt-in, experimental, and subject to change while the specification is
still in draft.
{{< /hint >}}

{{< toc >}}

## Enable OpenMetrics 2.0

To switch OpenMetrics responses from the legacy OM1 writer to the OM2 writer, set:

```properties
io.prometheus.openmetrics2.enabled=true
```

Programmatic configuration:

```java
PrometheusProperties properties = PrometheusProperties.builder()
.enableOpenMetrics2(om2 -> {})
.build();
```

Enabling `enableOpenMetrics2(...)` also enables the top-level `enabled` flag automatically, so you
only need to configure the sub-flags you want.
Comment on lines +20 to +33
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

fairly minor, but should these two examples match?

For example, either adding io.prometheus.openmetrics2.content_negotiation=true to the properties file example, or removing the content negotiation from the programmatic one?

PrometheusProperties properties = PrometheusProperties.builder()
    .enableOpenMetrics2(om2 -> {})
    .build();

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Aligned the examples in both directions. The first pair now shows the minimal enablement case without content negotiation, and I added a separate properties/programmatic pair for content_negotiation=true / contentNegotiation(true).


With `enabled=true` alone:

- OpenMetrics requests use the OM2 writer.
- Metric names are preserved as written by the application.
- Optional OM2 features such as `composite_values`, `exemplar_compliance`, and
`native_histograms` remain off.

To enable OM2 only when the scraper explicitly requests `version=2.0.0`, set:

```properties
io.prometheus.openmetrics2.enabled=true
io.prometheus.openmetrics2.content_negotiation=true
```

Programmatic equivalent:

```java
PrometheusProperties properties = PrometheusProperties.builder()
.enableOpenMetrics2(om2 -> om2.contentNegotiation(true))
.build();
```

## Naming Behavior

OpenMetrics 2.0 removes OM1 suffix rewriting.

- Counters do not get `_total` appended automatically.
- Units do not get appended automatically.
- Info metrics still end in `_info` because that is required by the spec.

Examples:

| Metric builder input | OM1 output | OM2 output |
| ---------------------------------- | ----------------- | -------------- |
| `Counter("events")` | `events_total` | `events` |
| `Counter("events_total")` | `events_total` | `events_total` |
| `Counter("req").unit(BYTES)` | `req_bytes_total` | `req` |
| `Counter("req_bytes").unit(BYTES)` | `req_bytes_total` | `req_bytes` |
| `Info("target")` | `target_info` | `target_info` |

This means OpenMetrics 2.0 does not apply OM1 suffix behavior such as appending `_total` or unit
suffixes, while the legacy OpenMetrics 1.0 and Prometheus text formats keep that existing suffix
behavior.

## Feature Flags

All OpenMetrics 2.0 flags default to `false`.

| Property | Effect |
| ------------------------------------------------ | -------------------------------------------------------------------------------------- |
| `io.prometheus.openmetrics2.enabled` | Metric names are preserved as written by the application. |
| `io.prometheus.openmetrics2.content_negotiation` | Apply OM2 behavior only when the scraper requests `version=2.0.0`. |
| `io.prometheus.openmetrics2.composite_values` | Emit histograms, summaries, and gauge histograms as single composite lines with `st@`. |
| `io.prometheus.openmetrics2.exemplar_compliance` | Emit only OM2-compliant exemplars with timestamps. |
| `io.prometheus.openmetrics2.native_histograms` | Emit OM2 native histogram text fields. |

Enable all flags at once:

```java
PrometheusProperties properties = PrometheusProperties.builder()
.enableOpenMetrics2(om2 -> om2.enableAll())
.build();
```

Equivalent properties:

```properties
io.prometheus.openmetrics2.enabled=true
io.prometheus.openmetrics2.content_negotiation=true
io.prometheus.openmetrics2.composite_values=true
io.prometheus.openmetrics2.exemplar_compliance=true
io.prometheus.openmetrics2.native_histograms=true
```

## Content Negotiation

If `content_negotiation=false`, OpenMetrics 2.0 behavior is applied to OpenMetrics responses even
if the scraper requested OpenMetrics 1.0.

If `content_negotiation=true`, OpenMetrics 2.0 behavior is only used when the scraper explicitly
requests `version=2.0.0`. Otherwise the legacy OpenMetrics 1.0 response is returned.

## Native Histograms

With `io.prometheus.openmetrics2.native_histograms=true`, the OpenMetrics 2.0 writer emits native
histogram fields such as:

- `schema`
- `zero_threshold`
- `zero_count`
- positive and negative spans
- positive and negative buckets

OM2 native histogram output can coexist with classic histogram buckets. When both are present, the
native histogram sample is written first.
10 changes: 7 additions & 3 deletions docs/content/getting-started/metric-types.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,13 @@ serviceTimeSeconds.inc(Unit.millisToSeconds(200));
The resulting counter has the value `0.2`. As `SECONDS` is the standard time unit in Prometheus, the
`Unit` utility class has methods to convert other time units to seconds.

As defined in [OpenMetrics](https://openmetrics.io/), counter metric names must have the `_total`
suffix. If you create a counter without the `_total` suffix the suffix will be appended
automatically.
For the default OpenMetrics 1.0 and Prometheus text formats, counters are exposed with the
`_total` suffix. You can name a counter either `service_time_seconds` or
`service_time_seconds_total`; the exposed name will be `service_time_seconds_total` in both cases.

The experimental OpenMetrics 2.0 writer behaves differently: It preserves metric names instead of
appending `_total` or unit suffixes automatically. In OpenMetrics 2.0, `_total` is recommended for
counters, but not enforced by the Java client.

## Gauge

Expand Down
20 changes: 20 additions & 0 deletions docs/content/otel/names.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,26 @@ The main steps when converting OpenTelemetry metric names to Prometheus metric n
- If the metric has a unit, append the unit to the metric name, like `_seconds`.
- If the metric type has a suffix, append it, like `_total` for counters.

## `preserve_names`

The Prometheus Java client library can also export its own metrics to OpenTelemetry using the
[OpenTelemetryExporter](/client_java/api/io/prometheus/metrics/exporter/opentelemetry/OpenTelemetryExporter.html). <!-- editorconfig-checker-disable-line -->

For that exporter, `io.prometheus.exporter.opentelemetry.preserve_names=true` preserves metric
names exactly as they were written in the Prometheus Java client.

Examples:

| Prometheus Java metric | Default OTel export | With `preserve_names=true` |
| ---------------------------------- | --------------------- | --------------------------- |
| `Counter("events")` | `events` | `events` |
| `Counter("events_total")` | `events` | `events_total` |
| `Counter("req").unit(BYTES)` | name `req`, unit `By` | name `req`, unit `By` |
| `Counter("req_bytes").unit(BYTES)` | name `req`, unit `By` | name `req_bytes`, unit `By` |

Today the default is `false` for backward compatibility. It is planned to change to `true` in the
next major release.

## Dots in Metric and Label Names

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