@@ -35,4 +35,252 @@ not implemented and the CollectorRegistry was created with `auto_describe=True`
3535(which is the case for the default registry) then ` collect ` will be called at
3636registration time instead of ` describe ` . If this could cause problems, either
3737implement a proper ` describe ` , or if that's not practical have ` describe `
38- return an empty list.
38+ return an empty list.
39+
40+ ## Collector protocol
41+
42+ A collector is any object that implements a ` collect ` method. Optionally it
43+ can also implement ` describe ` .
44+
45+ ### ` collect() `
46+
47+ Returns an iterable of metric family objects (` GaugeMetricFamily ` ,
48+ ` CounterMetricFamily ` , etc.). Called every time the registry is scraped.
49+
50+ ### ` describe() `
51+
52+ Returns an iterable of metric family objects used only to determine the metric
53+ names the collector produces. Samples on the returned objects are ignored. If
54+ not implemented and the registry has ` auto_describe=True ` , ` collect ` is called
55+ at registration time instead.
56+
57+ ## value vs labels
58+
59+ Every metric family constructor accepts either inline data or ` labels ` , but not
60+ both. The inline data parameter name varies by type: ` value ` for Gauge, Counter,
61+ and Info; ` count_value ` /` sum_value ` for Summary; ` buckets ` for Histogram.
62+
63+ - Pass inline data to emit a single unlabelled metric directly from the constructor.
64+ - Pass ` labels ` (a sequence of label names) and then call ` add_metric ` one or
65+ more times to emit labelled metrics.
66+
67+ ``` python
68+ # single unlabelled value
69+ GaugeMetricFamily(' my_gauge' , ' Help text' , value = 7 )
70+
71+ # labelled metrics via add_metric
72+ g = GaugeMetricFamily(' my_gauge' , ' Help text' , labels = [' region' ])
73+ g.add_metric([' us-east-1' ], 3 )
74+ g.add_metric([' eu-west-1' ], 5 )
75+ ```
76+
77+ ## API Reference
78+
79+ ### GaugeMetricFamily
80+
81+ ``` python
82+ GaugeMetricFamily(name, documentation, value = None , labels = None , unit = ' ' )
83+ ```
84+
85+ | Parameter | Type | Default | Description |
86+ | -----------| ------| ---------| -------------|
87+ | ` name ` | ` str ` | required | Metric name. |
88+ | ` documentation ` | ` str ` | required | Help text shown in the ` /metrics ` output. |
89+ | ` value ` | ` float ` | ` None ` | Emit a single unlabelled sample with this value. Mutually exclusive with ` labels ` . |
90+ | ` labels ` | ` Sequence[str] ` | ` None ` | Label names. Use with ` add_metric ` . Mutually exclusive with ` value ` . |
91+ | ` unit ` | ` str ` | ` '' ` | Optional unit suffix appended to the metric name. |
92+
93+ #### ` add_metric(labels, value, timestamp=None) `
94+
95+ Add a labelled sample to the metric family.
96+
97+ | Parameter | Type | Description |
98+ | -----------| ------| -------------|
99+ | ` labels ` | ` Sequence[str] ` | Label values in the same order as the ` labels ` constructor argument. |
100+ | ` value ` | ` float ` | The gauge value. |
101+ | ` timestamp ` | ` float ` or ` Timestamp ` | Optional Unix timestamp for the sample. |
102+
103+ ``` python
104+ g = GaugeMetricFamily(' temperature_celsius' , ' Temperature by location' , labels = [' location' ])
105+ g.add_metric([' living_room' ], 21.5 )
106+ g.add_metric([' basement' ], 18.0 )
107+ yield g
108+ ```
109+
110+ ### CounterMetricFamily
111+
112+ ``` python
113+ CounterMetricFamily(name, documentation, value = None , labels = None , created = None , unit = ' ' , exemplar = None )
114+ ```
115+
116+ If ` name ` ends with ` _total ` , the suffix is stripped automatically so the
117+ metric is stored without it and the ` _total ` suffix is added on exposition.
118+
119+ | Parameter | Type | Default | Description |
120+ | -----------| ------| ---------| -------------|
121+ | ` name ` | ` str ` | required | Metric name. A trailing ` _total ` is stripped and re-added on exposition. |
122+ | ` documentation ` | ` str ` | required | Help text. |
123+ | ` value ` | ` float ` | ` None ` | Emit a single unlabelled sample. Mutually exclusive with ` labels ` . |
124+ | ` labels ` | ` Sequence[str] ` | ` None ` | Label names. Use with ` add_metric ` . Mutually exclusive with ` value ` . |
125+ | ` created ` | ` float ` | ` None ` | Unix timestamp the counter was created at. Only used when ` value ` is set. |
126+ | ` unit ` | ` str ` | ` '' ` | Optional unit suffix. |
127+ | ` exemplar ` | ` Exemplar ` | ` None ` | Exemplar for the single-value form. Only used when ` value ` is set. |
128+
129+ #### ` add_metric(labels, value, created=None, timestamp=None, exemplar=None) `
130+
131+ | Parameter | Type | Description |
132+ | -----------| ------| -------------|
133+ | ` labels ` | ` Sequence[str] ` | Label values. |
134+ | ` value ` | ` float ` | The counter value. |
135+ | ` created ` | ` float ` | Optional Unix timestamp the counter was created at. |
136+ | ` timestamp ` | ` float ` or ` Timestamp ` | Optional Unix timestamp for the sample. |
137+ | ` exemplar ` | ` Exemplar ` | Optional exemplar. See [ Exemplars] ( ../../instrumenting/exemplars/ ) . |
138+
139+ ``` python
140+ c = CounterMetricFamily(' http_requests_total' , ' HTTP requests by status' , labels = [' status' ])
141+ c.add_metric([' 200' ], 1200 )
142+ c.add_metric([' 404' ], 43 )
143+ c.add_metric([' 500' ], 7 )
144+ yield c
145+ ```
146+
147+ ### SummaryMetricFamily
148+
149+ ``` python
150+ SummaryMetricFamily(name, documentation, count_value = None , sum_value = None , labels = None , unit = ' ' )
151+ ```
152+
153+ ` count_value ` and ` sum_value ` must always be provided together or not at all.
154+
155+ | Parameter | Type | Default | Description |
156+ | -----------| ------| ---------| -------------|
157+ | ` name ` | ` str ` | required | Metric name. |
158+ | ` documentation ` | ` str ` | required | Help text. |
159+ | ` count_value ` | ` int ` | ` None ` | Observation count for a single unlabelled metric. Must be paired with ` sum_value ` . |
160+ | ` sum_value ` | ` float ` | ` None ` | Observation sum for a single unlabelled metric. Must be paired with ` count_value ` . |
161+ | ` labels ` | ` Sequence[str] ` | ` None ` | Label names. Use with ` add_metric ` . Mutually exclusive with ` count_value ` /` sum_value ` . |
162+ | ` unit ` | ` str ` | ` '' ` | Optional unit suffix. |
163+
164+ #### ` add_metric(labels, count_value, sum_value, timestamp=None) `
165+
166+ | Parameter | Type | Description |
167+ | -----------| ------| -------------|
168+ | ` labels ` | ` Sequence[str] ` | Label values. |
169+ | ` count_value ` | ` int ` | The number of observations. |
170+ | ` sum_value ` | ` float ` | The sum of all observed values. |
171+ | ` timestamp ` | ` float ` or ` Timestamp ` | Optional Unix timestamp for the sample. |
172+
173+ ``` python
174+ s = SummaryMetricFamily(' rpc_duration_seconds' , ' RPC duration' , labels = [' method' ])
175+ s.add_metric([' get' ], count_value = 1000 , sum_value = 53.2 )
176+ s.add_metric([' put' ], count_value = 400 , sum_value = 28.7 )
177+ yield s
178+ ```
179+
180+ ### HistogramMetricFamily
181+
182+ ``` python
183+ HistogramMetricFamily(name, documentation, buckets = None , sum_value = None , labels = None , unit = ' ' )
184+ ```
185+
186+ | Parameter | Type | Default | Description |
187+ | -----------| ------| ---------| -------------|
188+ | ` name ` | ` str ` | required | Metric name. |
189+ | ` documentation ` | ` str ` | required | Help text. |
190+ | ` buckets ` | ` Sequence ` | ` None ` | Bucket data for a single unlabelled metric. Each entry is a ` (le, value) ` pair or ` (le, value, exemplar) ` triple. Must include a ` +Inf ` bucket. Mutually exclusive with ` labels ` . |
191+ | ` sum_value ` | ` float ` | ` None ` | Observation sum. Cannot be set without ` buckets ` . Omitted for histograms with negative buckets. |
192+ | ` labels ` | ` Sequence[str] ` | ` None ` | Label names. Use with ` add_metric ` . Mutually exclusive with ` buckets ` . |
193+ | ` unit ` | ` str ` | ` '' ` | Optional unit suffix. |
194+
195+ #### ` add_metric(labels, buckets, sum_value, timestamp=None) `
196+
197+ | Parameter | Type | Description |
198+ | -----------| ------| -------------|
199+ | ` labels ` | ` Sequence[str] ` | Label values. |
200+ | ` buckets ` | ` Sequence ` | Bucket data. Each entry is a ` (le, value) ` pair or ` (le, value, exemplar) ` triple. Must be sorted and include ` +Inf ` . |
201+ | ` sum_value ` | ` float ` or ` None ` | The sum of all observed values. Pass ` None ` for histograms with negative buckets. |
202+ | ` timestamp ` | ` float ` or ` Timestamp ` | Optional Unix timestamp. |
203+
204+ ``` python
205+ h = HistogramMetricFamily(' request_size_bytes' , ' Request sizes' , labels = [' handler' ])
206+ h.add_metric(
207+ [' api' ],
208+ buckets = [(' 100' , 5 ), (' 1000' , 42 ), (' +Inf' , 50 )],
209+ sum_value = 18350.0 ,
210+ )
211+ yield h
212+ ```
213+
214+ ### InfoMetricFamily
215+
216+ ``` python
217+ InfoMetricFamily(name, documentation, value = None , labels = None )
218+ ```
219+
220+ | Parameter | Type | Default | Description |
221+ | -----------| ------| ---------| -------------|
222+ | ` name ` | ` str ` | required | Metric name. The ` _info ` suffix is added automatically on exposition. |
223+ | ` documentation ` | ` str ` | required | Help text. |
224+ | ` value ` | ` Dict[str, str] ` | ` None ` | Key-value label pairs for a single unlabelled info metric. Mutually exclusive with ` labels ` . |
225+ | ` labels ` | ` Sequence[str] ` | ` None ` | Label names for the outer grouping. Use with ` add_metric ` . Mutually exclusive with ` value ` . |
226+
227+ #### ` add_metric(labels, value, timestamp=None) `
228+
229+ | Parameter | Type | Description |
230+ | -----------| ------| -------------|
231+ | ` labels ` | ` Sequence[str] ` | Outer label values (from the ` labels ` constructor argument). |
232+ | ` value ` | ` Dict[str, str] ` | Key-value label pairs that form the info payload. |
233+ | ` timestamp ` | ` float ` or ` Timestamp ` | Optional Unix timestamp. |
234+
235+ ``` python
236+ # single unlabelled info metric
237+ yield InfoMetricFamily(' build' , ' Build metadata' , value = {' version' : ' 1.2.3' , ' commit' : ' abc123' })
238+
239+ # labelled: one info metric per service
240+ i = InfoMetricFamily(' service_build' , ' Per-service build info' , labels = [' service' ])
241+ i.add_metric([' auth' ], {' version' : ' 2.0.1' , ' commit' : ' def456' })
242+ i.add_metric([' api' ], {' version' : ' 1.9.0' , ' commit' : ' ghi789' })
243+ yield i
244+ ```
245+
246+ ## Real-world example
247+
248+ Proxying metrics from an external source:
249+
250+ ``` python
251+ from prometheus_client.core import CounterMetricFamily, GaugeMetricFamily, REGISTRY
252+ from prometheus_client.registry import Collector
253+ from prometheus_client import start_http_server
254+
255+ # Simulated external data source
256+ _QUEUE_STATS = {
257+ ' orders' : {' depth' : 14 , ' processed' : 9821 },
258+ ' notifications' : {' depth' : 3 , ' processed' : 45210 },
259+ }
260+
261+ class QueueCollector (Collector ):
262+ def collect (self ):
263+ depth = GaugeMetricFamily(
264+ ' queue_depth' ,
265+ ' Current number of messages waiting in the queue' ,
266+ labels = [' queue' ],
267+ )
268+ processed = CounterMetricFamily(
269+ ' queue_messages_processed_total' ,
270+ ' Total messages processed from the queue' ,
271+ labels = [' queue' ],
272+ )
273+ for name, stats in _QUEUE_STATS .items():
274+ depth.add_metric([name], stats[' depth' ])
275+ processed.add_metric([name], stats[' processed' ])
276+ yield depth
277+ yield processed
278+
279+ REGISTRY .register(QueueCollector())
280+
281+ if __name__ == ' __main__' :
282+ start_http_server(8000 )
283+ import time
284+ while True :
285+ time.sleep(1 )
286+ ```
0 commit comments