Skip to content

feat(metrics): add protobuf and OpenMetrics text encoders, collection, and info metrics.#237

Draft
ethanolchik wants to merge 16 commits into
cloudflare:mainfrom
ethanolchik:encoders-and-collect
Draft

feat(metrics): add protobuf and OpenMetrics text encoders, collection, and info metrics.#237
ethanolchik wants to merge 16 commits into
cloudflare:mainfrom
ethanolchik:encoders-and-collect

Conversation

@ethanolchik

@ethanolchik ethanolchik commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Overview

This PR completes the path from registered metrics to Prometheus-compatible wire output:

  1. Collect registered metrics into the canonical protobuf MetricFamily model.
  2. Encode those families as length-delimited Prometheus protobuf or OpenMetrics text.

The public API now exposes collect, CollectionOptions, ServiceNameFormat, encode_to_protobuf, and encode_to_text.

Collection

collect iterates over the global registry and encodes each registered metric into one or more MetricFamily values.

CollectionOptions controls whether optional metrics are included and how a service name is represented:

  • MetricPrefix prefixes metric family names, except metrics registered as unprefixed.
  • LabelWithName adds the service name as a label to every row.

The resulting Vec<MetricFamily> provides a common boundary between metric implementations and wire encoders.

Encoding

encode_to_protobuf serialises metric families as concatenated, length-delimited Prometheus protobuf messages. This preserves fields that OpenMetrics text cannot fully represent, including native histogram data.

encode_to_text supports:

  • Counters
  • Gauges
  • GaugeHistograms
  • Summaries
  • Untyped metrics
  • Classic histograms
  • Legacy info metrics, represented as gauge families valued 1 with their fields as labels

Legacy info metrics preserve their existing wire representation in both formats: the family name remains unchanged (for example, build_info), the protobuf type is gauge, and text output emits # TYPE build_info gauge.

The text encoder emits # HELP, # TYPE, and # UNIT metadata and terminates output with # EOF.

Histogram encoding:

  • Maps the terminal f64::MAX bucket to +Inf.
  • Adds a terminal +Inf bucket when missing.
  • Preserves classic histogram bucket exemplars.
  • Skips native-only histogram rows.
  • Skips histogram rows with positive floating-point counts.

The encoder also handles metric and exemplar timestamps, escapes help text and label values, and emits NaN, +Inf, and -Inf using OpenMetrics syntax.

Summary and GaugeHistogram families are fully supported. Protobuf passes them through unchanged. In text, summaries emit their quantile rows plus _sum and _count; gauge histograms emit _bucket rows plus _gsum and _gcount.

For text output, families without a non-empty name or recognised type, and rows missing data for their declared type, are skipped and reported through the non-fatal collection error hook.

@ethanolchik
ethanolchik force-pushed the encoders-and-collect branch from b420c26 to 6a04141 Compare July 24, 2026 14:43
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.

1 participant