Skip to content

proposal: Prometheus internal telemetry as an OTel semantic convention registry - #86

Open
nicolastakashi wants to merge 3 commits into
prometheus:mainfrom
nicolastakashi:semconv-internal-telemetry
Open

proposal: Prometheus internal telemetry as an OTel semantic convention registry#86
nicolastakashi wants to merge 3 commits into
prometheus:mainfrom
nicolastakashi:semconv-internal-telemetry

Conversation

@nicolastakashi

@nicolastakashi nicolastakashi commented Jun 27, 2026

Copy link
Copy Markdown

This proposal defines all metrics exported by the Prometheus binary as a formal OTel semantic convention registry. Making the schema machine-readable enables auto-generated instrumentation code, always-in-sync documentation, contract testing against live instances, and a lifecycle model for safe metric evolution across the Prometheus ecosystem.

Proof-of-concept implementation: prometheus/prometheus#17868

@nicolastakashi
nicolastakashi force-pushed the semconv-internal-telemetry branch 2 times, most recently from 459e052 to 293d5de Compare June 29, 2026 09:46
@roidelapluie

Copy link
Copy Markdown
Member

I would like to assess what alternatives we have that could be built-in e.g. client_golang and would be lighter. And I would also want to better understand the scope of this: a lifecycle model for safe metric evolution across the Prometheus ecosystem.

@nicolastakashi
nicolastakashi force-pushed the semconv-internal-telemetry branch from 2dac915 to 63633cc Compare August 18, 2026 20:19
…n registry

Define every metric the Prometheus binary exposes in a single OTel semantic
convention registry, and use it as the source of truth for instrumentation
code, documentation, and contract testing.

Instrumentation code and per-package documentation are generated from the
registry with Weaver, so neither can drift from the schema. Weaver is confined
to build-time authoring.

Contract testing runs without a Collector or a Weaver binary. `promtool check
metrics --schema` validates a running Prometheus from outside and works for any
exporter in any language. An in-process check over `Collector.Describe()` also
covers metrics that never produce a sample, which telemetry-based validation
cannot see. Both need a small, dependency-free addition to client_golang, since
`prometheus.Desc` exposes no structural accessors today.

Stability levels are recorded as schema information so lifecycle can be
expressed and changes to it reviewed. Defining what `stable` obligates, how long
a deprecation cycle runs, and which existing metrics are stable is left to a
follow-on proposal.

A consumable registry also lets downstream projects detect drift themselves.
awesome-prometheus-alerts hardcodes 37 distinct prometheus_* metric names and
perses/community-mixins writes them into dashboard queries, with no way to
validate either against a release. Publishing a versioned schema of renames
between releases stays a follow-on.
@nicolastakashi
nicolastakashi force-pushed the semconv-internal-telemetry branch from 63633cc to 52b69ae Compare August 18, 2026 20:27
@nicolastakashi

Copy link
Copy Markdown
Author

I would like to assess what alternatives we have that could be built-in e.g. client_golang and would be lighter. And I would also want to better understand the scope of this: a lifecycle model for safe metric evolution across the Prometheus ecosystem.

@roidelapluie thanks for comment, I've updated a few things in the doc aiming to cover what you raised, let me know your thoughts

@ArthurSens ArthurSens left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Had some minutes in the airport to review this, it's not a complete review though 😅

Comment thread proposals/0086-semconv-internal-telemetry.md Outdated
Comment thread proposals/0086-semconv-internal-telemetry.md Outdated
Comment thread proposals/0086-semconv-internal-telemetry.md Outdated
* [Required] Define Prometheus' internal telemetry as a formal OTel semantic convention registry (a single `registry.yaml`), making it the single machine-readable source of truth for every metric Prometheus exposes.
* [Required] Generate instrumentation code from the registry, eliminating hand-written metric definitions in Go.
* [Required] Generate metric documentation from the registry that cannot drift from the implementation.
* [Nice to have] Enable contract testing through `promtool`: validate that a running Prometheus exposes exactly what the registry says, with no OTel Collector and no Weaver binary in the test path.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

why not use the tools that already exist for this? 🙃

The primary surface is `promtool`. It already reads text exposition from stdin, already runs `promlint` over it, and already exits 3 when it finds problems:

```
curl -s http://localhost:9090/metrics | promtool check metrics --schema registry.yaml

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

By default, Prometheus does not emit all metrics it is instrumented with. For example, if Remote Write isn't configured for an instance, it won't expose any Remote Write metrics.

What would happen in that situation, should check metrics fail because the metric exists in the schema but not in the /metrics endpoint?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It also exposes other metrics that aren't Prometheus related, like go and http metrics, what happens in these situations?

Address review feedback that the goals stated the solution rather than
what it buys. The goals now describe the outcome (one machine-readable
description, no hand-written descriptors, docs that cannot drift), and
OTel semantic conventions appear as the mechanism in the How section.

Also replace the OTel-alignment bullet in Why with the concrete problem
underneath it: nothing can describe what a Prometheus emits without
scraping a live instance.

Signed-off-by: Nicolas Takashi <nicolas.takashi@dash0.com>
Address review feedback on the promtool path. Contract testing is now a
single mechanism: a Go test that reads Collector.Describe() and compares
the declared metrics to the registry.

Drop promtool --schema. It could not verify that every declared metric is
present, because text exposition only contains metrics that produced a
sample, and it would have failed on metrics Prometheus does not own. The
Describe() path sees the full declared surface either way.

Add Weaver live-check as an explicit alternative so the reasons for not
using the existing tool sit in Alternatives rather than buried in the
contract testing section. Remove promlint from the design; it stays only
in the alternative that exists to reject it.

Signed-off-by: Nicolas Takashi <nicolas.takashi@dash0.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.

3 participants