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.
20 "github.com/golang/protobuf/proto"
22 dto "github.com/prometheus/client_model/go"
25 // ValueType is an enumeration of metric types that represent a simple value.
28 // Possible values for the ValueType enum.
36 // valueFunc is a generic metric for simple values retrieved on collect time
37 // from a function. It implements Metric and Collector. Its effective type is
38 // determined by ValueType. This is a low-level building block used by the
39 // library to back the implementations of CounterFunc, GaugeFunc, and
41 type valueFunc struct {
46 function func() float64
47 labelPairs []*dto.LabelPair
50 // newValueFunc returns a newly allocated valueFunc with the given Desc and
51 // ValueType. The value reported is determined by calling the given function
52 // from within the Write method. Take into account that metric collection may
53 // happen concurrently. If that results in concurrent calls to Write, like in
54 // the case where a valueFunc is directly registered with Prometheus, the
55 // provided function must be concurrency-safe.
56 func newValueFunc(desc *Desc, valueType ValueType, function func() float64) *valueFunc {
61 labelPairs: makeLabelPairs(desc, nil),
67 func (v *valueFunc) Desc() *Desc {
71 func (v *valueFunc) Write(out *dto.Metric) error {
72 return populateMetric(v.valType, v.function(), v.labelPairs, out)
75 // NewConstMetric returns a metric with one fixed value that cannot be
76 // changed. Users of this package will not have much use for it in regular
77 // operations. However, when implementing custom Collectors, it is useful as a
78 // throw-away metric that is generated on the fly to send it to Prometheus in
79 // the Collect method. NewConstMetric returns an error if the length of
80 // labelValues is not consistent with the variable labels in Desc or if Desc is
82 func NewConstMetric(desc *Desc, valueType ValueType, value float64, labelValues ...string) (Metric, error) {
86 if err := validateLabelValues(labelValues, len(desc.variableLabels)); err != nil {
93 labelPairs: makeLabelPairs(desc, labelValues),
97 // MustNewConstMetric is a version of NewConstMetric that panics where
98 // NewConstMetric would have returned an error.
99 func MustNewConstMetric(desc *Desc, valueType ValueType, value float64, labelValues ...string) Metric {
100 m, err := NewConstMetric(desc, valueType, value, labelValues...)
107 type constMetric struct {
111 labelPairs []*dto.LabelPair
114 func (m *constMetric) Desc() *Desc {
118 func (m *constMetric) Write(out *dto.Metric) error {
119 return populateMetric(m.valType, m.val, m.labelPairs, out)
125 labelPairs []*dto.LabelPair,
131 m.Counter = &dto.Counter{Value: proto.Float64(v)}
133 m.Gauge = &dto.Gauge{Value: proto.Float64(v)}
135 m.Untyped = &dto.Untyped{Value: proto.Float64(v)}
137 return fmt.Errorf("encountered unknown type %v", t)
142 func makeLabelPairs(desc *Desc, labelValues []string) []*dto.LabelPair {
143 totalLen := len(desc.variableLabels) + len(desc.constLabelPairs)
148 if len(desc.variableLabels) == 0 {
149 // Moderately fast path.
150 return desc.constLabelPairs
152 labelPairs := make([]*dto.LabelPair, 0, totalLen)
153 for i, n := range desc.variableLabels {
154 labelPairs = append(labelPairs, &dto.LabelPair{
155 Name: proto.String(n),
156 Value: proto.String(labelValues[i]),
159 labelPairs = append(labelPairs, desc.constLabelPairs...)
160 sort.Sort(labelPairSorter(labelPairs))