@@ -104,25 +104,39 @@ Validation of duplicate metric names and label schemas happens at registration t
104104Built-in metrics (Counter, Gauge, Histogram, etc.) participate in this validation.
105105
106106Custom collectors that implement the ` Collector ` or ` MultiCollector ` interface can optionally
107- implement ` getPrometheusName() ` and ` getMetricType() ` (and the MultiCollector per-name variants) so
108- the registry can enforce consistency. ** Validation is skipped when metric name or type is
109- unavailable:** if ` getPrometheusName() ` or ` getMetricType() ` returns ` null ` , the registry does not
110- validate that collector. If two such collectors produce the same metric name and same label set at
111- scrape time, the exposition output may contain duplicate time series and be invalid for Prometheus.
112-
113- When validation _ is_ performed (name and type are non-null), ** null label names are treated as an
114- empty label schema:** ` getLabelNames() ` returning ` null ` is normalized to ` Collections.emptySet() `
115- and full label-schema validation and duplicate detection still apply. A collector that returns a
116- non-null type but leaves ` getLabelNames() ` as ` null ` is still validated, with its labels treated as
117- empty.
107+ expose their registration-time metadata so the registry can enforce consistency. The recommended
108+ way is to override ` getMetricFamilyDescriptor() ` (or ` getMetricFamilyDescriptors() ` on
109+ ` MultiCollector ` ) and return a ` MetricFamilyDescriptor ` describing the metric name, type, label
110+ names, and metadata (help, unit) the collector will emit at scrape time.
111+
112+ ``` java
113+ @Override
114+ public MetricFamilyDescriptor getMetricFamilyDescriptor() {
115+ return MetricFamilyDescriptor . gauge(" my_metric" )
116+ .help(" Example metric" )
117+ .labelNames(" region" )
118+ .build();
119+ }
120+ ```
121+
122+ The fragmented ` getPrometheusName() ` , ` getMetricType() ` , ` getLabelNames() ` , and ` getMetadata() `
123+ methods (and their ` MultiCollector ` per-name variants) are deprecated. They remain bridged by a
124+ default implementation of ` getMetricFamilyDescriptor() ` for compatibility, so existing
125+ collectors keep working unchanged.
126+
127+ ** Validation is skipped when registration-time metadata is unavailable:** if
128+ ` getMetricFamilyDescriptor() ` returns ` null ` (the default when name or type is missing), the
129+ registry does not validate that collector. If two such collectors produce the same metric name and
130+ same label set at scrape time, the exposition output may contain duplicate time series and be
131+ invalid for Prometheus.
118132
119133This is also relevant for downstream adapter libraries that bridge to this registry. If an adapter
120134implements ` MultiCollector ` , its registration-time metadata must match the metric families it will
121- actually emit at scrape time. In practice, that means ` getPrometheusNames() ` , ` getMetricType(...) ` ,
122- ` getLabelNames(...) ` , and ` getMetadata(...) ` need to describe the same names, types, labels, and
123- suffix behavior as the eventual ` MetricSnapshot ` output. Otherwise an adapter may pass or fail
124- collision checks differently after upgrading to a newer client_java release, even if its scrape
125- output logic did not change.
135+ actually emit at scrape time. In practice, the ` MetricFamilyDescriptor ` s returned from
136+ ` getMetricFamilyDescriptors() ` need to describe the same names, types, labels, and suffix behavior
137+ as the eventual ` MetricSnapshot ` output. Otherwise an adapter may pass or fail collision checks
138+ differently after upgrading to a newer client_java release, even if its scrape output logic did not
139+ change.
126140
127141## Unregistering a Metric
128142
0 commit comments