collector.go 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  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
  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. package prometheus
  14. // Collector is the interface implemented by anything that can be used by
  15. // Prometheus to collect metrics. A Collector has to be registered for
  16. // collection. See Registerer.Register.
  17. //
  18. // The stock metrics provided by this package (Gauge, Counter, Summary,
  19. // Histogram, Untyped) are also Collectors (which only ever collect one metric,
  20. // namely itself). An implementer of Collector may, however, collect multiple
  21. // metrics in a coordinated fashion and/or create metrics on the fly. Examples
  22. // for collectors already implemented in this library are the metric vectors
  23. // (i.e. collection of multiple instances of the same Metric but with different
  24. // label values) like GaugeVec or SummaryVec, and the ExpvarCollector.
  25. type Collector interface {
  26. // Describe sends the super-set of all possible descriptors of metrics
  27. // collected by this Collector to the provided channel and returns once
  28. // the last descriptor has been sent. The sent descriptors fulfill the
  29. // consistency and uniqueness requirements described in the Desc
  30. // documentation.
  31. //
  32. // It is valid if one and the same Collector sends duplicate
  33. // descriptors. Those duplicates are simply ignored. However, two
  34. // different Collectors must not send duplicate descriptors.
  35. //
  36. // Sending no descriptor at all marks the Collector as “unchecked”,
  37. // i.e. no checks will be performed at registration time, and the
  38. // Collector may yield any Metric it sees fit in its Collect method.
  39. //
  40. // This method idempotently sends the same descriptors throughout the
  41. // lifetime of the Collector.
  42. //
  43. // If a Collector encounters an error while executing this method, it
  44. // must send an invalid descriptor (created with NewInvalidDesc) to
  45. // signal the error to the registry.
  46. Describe(chan<- *Desc)
  47. // Collect is called by the Prometheus registry when collecting
  48. // metrics. The implementation sends each collected metric via the
  49. // provided channel and returns once the last metric has been sent. The
  50. // descriptor of each sent metric is one of those returned by Describe
  51. // (unless the Collector is unchecked, see above). Returned metrics that
  52. // share the same descriptor must differ in their variable label
  53. // values.
  54. //
  55. // This method may be called concurrently and must therefore be
  56. // implemented in a concurrency safe way. Blocking occurs at the expense
  57. // of total performance of rendering all registered metrics. Ideally,
  58. // Collector implementations support concurrent readers.
  59. Collect(chan<- Metric)
  60. }
  61. // DescribeByCollect is a helper to implement the Describe method of a custom
  62. // Collector. It collects the metrics from the provided Collector and sends
  63. // their descriptors to the provided channel.
  64. //
  65. // If a Collector collects the same metrics throughout its lifetime, its
  66. // Describe method can simply be implemented as:
  67. //
  68. // func (c customCollector) Describe(ch chan<- *Desc) {
  69. // DescribeByCollect(c, ch)
  70. // }
  71. //
  72. // However, this will not work if the metrics collected change dynamically over
  73. // the lifetime of the Collector in a way that their combined set of descriptors
  74. // changes as well. The shortcut implementation will then violate the contract
  75. // of the Describe method. If a Collector sometimes collects no metrics at all
  76. // (for example vectors like CounterVec, GaugeVec, etc., which only collect
  77. // metrics after a metric with a fully specified label set has been accessed),
  78. // it might even get registered as an unchecked Collecter (cf. the Register
  79. // method of the Registerer interface). Hence, only use this shortcut
  80. // implementation of Describe if you are certain to fulfill the contract.
  81. //
  82. // The Collector example demonstrates a use of DescribeByCollect.
  83. func DescribeByCollect(c Collector, descs chan<- *Desc) {
  84. metrics := make(chan Metric)
  85. go func() {
  86. c.Collect(metrics)
  87. close(metrics)
  88. }()
  89. for m := range metrics {
  90. descs <- m.Desc()
  91. }
  92. }
  93. // selfCollector implements Collector for a single Metric so that the Metric
  94. // collects itself. Add it as an anonymous field to a struct that implements
  95. // Metric, and call init with the Metric itself as an argument.
  96. type selfCollector struct {
  97. self Metric
  98. }
  99. // init provides the selfCollector with a reference to the metric it is supposed
  100. // to collect. It is usually called within the factory function to create a
  101. // metric. See example.
  102. func (c *selfCollector) init(self Metric) {
  103. c.self = self
  104. }
  105. // Describe implements Collector.
  106. func (c *selfCollector) Describe(ch chan<- *Desc) {
  107. ch <- c.self.Desc()
  108. }
  109. // Collect implements Collector.
  110. func (c *selfCollector) Collect(ch chan<- Metric) {
  111. ch <- c.self
  112. }