1 // Copyright 2014 The Prometheus Authors
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
6 // http://www.apache.org/licenses/LICENSE-2.0
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
16 // Collector is the interface implemented by anything that can be used by
17 // Prometheus to collect metrics. A Collector has to be registered for
18 // collection. See Registerer.Register.
20 // The stock metrics provided by this package (Gauge, Counter, Summary,
21 // Histogram, Untyped) are also Collectors (which only ever collect one metric,
22 // namely itself). An implementer of Collector may, however, collect multiple
23 // metrics in a coordinated fashion and/or create metrics on the fly. Examples
24 // for collectors already implemented in this library are the metric vectors
25 // (i.e. collection of multiple instances of the same Metric but with different
26 // label values) like GaugeVec or SummaryVec, and the ExpvarCollector.
27 type Collector interface {
28 // Describe sends the super-set of all possible descriptors of metrics
29 // collected by this Collector to the provided channel and returns once
30 // the last descriptor has been sent. The sent descriptors fulfill the
31 // consistency and uniqueness requirements described in the Desc
34 // It is valid if one and the same Collector sends duplicate
35 // descriptors. Those duplicates are simply ignored. However, two
36 // different Collectors must not send duplicate descriptors.
38 // Sending no descriptor at all marks the Collector as “unchecked”,
39 // i.e. no checks will be performed at registration time, and the
40 // Collector may yield any Metric it sees fit in its Collect method.
42 // This method idempotently sends the same descriptors throughout the
43 // lifetime of the Collector. It may be called concurrently and
44 // therefore must be implemented in a concurrency safe way.
46 // If a Collector encounters an error while executing this method, it
47 // must send an invalid descriptor (created with NewInvalidDesc) to
48 // signal the error to the registry.
49 Describe(chan<- *Desc)
50 // Collect is called by the Prometheus registry when collecting
51 // metrics. The implementation sends each collected metric via the
52 // provided channel and returns once the last metric has been sent. The
53 // descriptor of each sent metric is one of those returned by Describe
54 // (unless the Collector is unchecked, see above). Returned metrics that
55 // share the same descriptor must differ in their variable label
58 // This method may be called concurrently and must therefore be
59 // implemented in a concurrency safe way. Blocking occurs at the expense
60 // of total performance of rendering all registered metrics. Ideally,
61 // Collector implementations support concurrent readers.
62 Collect(chan<- Metric)
65 // DescribeByCollect is a helper to implement the Describe method of a custom
66 // Collector. It collects the metrics from the provided Collector and sends
67 // their descriptors to the provided channel.
69 // If a Collector collects the same metrics throughout its lifetime, its
70 // Describe method can simply be implemented as:
72 // func (c customCollector) Describe(ch chan<- *Desc) {
73 // DescribeByCollect(c, ch)
76 // However, this will not work if the metrics collected change dynamically over
77 // the lifetime of the Collector in a way that their combined set of descriptors
78 // changes as well. The shortcut implementation will then violate the contract
79 // of the Describe method. If a Collector sometimes collects no metrics at all
80 // (for example vectors like CounterVec, GaugeVec, etc., which only collect
81 // metrics after a metric with a fully specified label set has been accessed),
82 // it might even get registered as an unchecked Collector (cf. the Register
83 // method of the Registerer interface). Hence, only use this shortcut
84 // implementation of Describe if you are certain to fulfill the contract.
86 // The Collector example demonstrates a use of DescribeByCollect.
87 func DescribeByCollect(c Collector, descs chan<- *Desc) {
88 metrics := make(chan Metric)
93 for m := range metrics {
98 // selfCollector implements Collector for a single Metric so that the Metric
99 // collects itself. Add it as an anonymous field to a struct that implements
100 // Metric, and call init with the Metric itself as an argument.
101 type selfCollector struct {
105 // init provides the selfCollector with a reference to the metric it is supposed
106 // to collect. It is usually called within the factory function to create a
107 // metric. See example.
108 func (c *selfCollector) init(self Metric) {
112 // Describe implements Collector.
113 func (c *selfCollector) Describe(ch chan<- *Desc) {
117 // Collect implements Collector.
118 func (c *selfCollector) Collect(ch chan<- Metric) {