blob: c0d70b2faf169973e3ea25b3c8da7ead42c29f19 [file] [log] [blame]
khenaidooffe076b2019-01-15 16:08:08 -05001// 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
5//
6// http://www.apache.org/licenses/LICENSE-2.0
7//
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.
13
14package prometheus
15
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.
19//
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.
27type 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
32 // documentation.
33 //
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.
37 //
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.
41 //
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.
45 //
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
56 // values.
57 //
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)
63}
64
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.
68//
69// If a Collector collects the same metrics throughout its lifetime, its
70// Describe method can simply be implemented as:
71//
72// func (c customCollector) Describe(ch chan<- *Desc) {
73// DescribeByCollect(c, ch)
74// }
75//
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 Collecter (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.
85//
86// The Collector example demonstrates a use of DescribeByCollect.
87func DescribeByCollect(c Collector, descs chan<- *Desc) {
88 metrics := make(chan Metric)
89 go func() {
90 c.Collect(metrics)
91 close(metrics)
92 }()
93 for m := range metrics {
94 descs <- m.Desc()
95 }
96}
97
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.
101type selfCollector struct {
102 self Metric
103}
104
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.
108func (c *selfCollector) init(self Metric) {
109 c.self = self
110}
111
112// Describe implements Collector.
113func (c *selfCollector) Describe(ch chan<- *Desc) {
114 ch <- c.self.Desc()
115}
116
117// Collect implements Collector.
118func (c *selfCollector) Collect(ch chan<- Metric) {
119 ch <- c.self
120}