Code refactoring for bpa operator
[icn.git] / cmd / bpa-operator / vendor / github.com / prometheus / client_golang / prometheus / value.go
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
14 package prometheus
15
16 import (
17         "fmt"
18         "sort"
19
20         "github.com/golang/protobuf/proto"
21
22         dto "github.com/prometheus/client_model/go"
23 )
24
25 // ValueType is an enumeration of metric types that represent a simple value.
26 type ValueType int
27
28 // Possible values for the ValueType enum.
29 const (
30         _ ValueType = iota
31         CounterValue
32         GaugeValue
33         UntypedValue
34 )
35
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
40 // UntypedFunc.
41 type valueFunc struct {
42         selfCollector
43
44         desc       *Desc
45         valType    ValueType
46         function   func() float64
47         labelPairs []*dto.LabelPair
48 }
49
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 {
57         result := &valueFunc{
58                 desc:       desc,
59                 valType:    valueType,
60                 function:   function,
61                 labelPairs: makeLabelPairs(desc, nil),
62         }
63         result.init(result)
64         return result
65 }
66
67 func (v *valueFunc) Desc() *Desc {
68         return v.desc
69 }
70
71 func (v *valueFunc) Write(out *dto.Metric) error {
72         return populateMetric(v.valType, v.function(), v.labelPairs, out)
73 }
74
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
81 // invalid.
82 func NewConstMetric(desc *Desc, valueType ValueType, value float64, labelValues ...string) (Metric, error) {
83         if desc.err != nil {
84                 return nil, desc.err
85         }
86         if err := validateLabelValues(labelValues, len(desc.variableLabels)); err != nil {
87                 return nil, err
88         }
89         return &constMetric{
90                 desc:       desc,
91                 valType:    valueType,
92                 val:        value,
93                 labelPairs: makeLabelPairs(desc, labelValues),
94         }, nil
95 }
96
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...)
101         if err != nil {
102                 panic(err)
103         }
104         return m
105 }
106
107 type constMetric struct {
108         desc       *Desc
109         valType    ValueType
110         val        float64
111         labelPairs []*dto.LabelPair
112 }
113
114 func (m *constMetric) Desc() *Desc {
115         return m.desc
116 }
117
118 func (m *constMetric) Write(out *dto.Metric) error {
119         return populateMetric(m.valType, m.val, m.labelPairs, out)
120 }
121
122 func populateMetric(
123         t ValueType,
124         v float64,
125         labelPairs []*dto.LabelPair,
126         m *dto.Metric,
127 ) error {
128         m.Label = labelPairs
129         switch t {
130         case CounterValue:
131                 m.Counter = &dto.Counter{Value: proto.Float64(v)}
132         case GaugeValue:
133                 m.Gauge = &dto.Gauge{Value: proto.Float64(v)}
134         case UntypedValue:
135                 m.Untyped = &dto.Untyped{Value: proto.Float64(v)}
136         default:
137                 return fmt.Errorf("encountered unknown type %v", t)
138         }
139         return nil
140 }
141
142 func makeLabelPairs(desc *Desc, labelValues []string) []*dto.LabelPair {
143         totalLen := len(desc.variableLabels) + len(desc.constLabelPairs)
144         if totalLen == 0 {
145                 // Super fast path.
146                 return nil
147         }
148         if len(desc.variableLabels) == 0 {
149                 // Moderately fast path.
150                 return desc.constLabelPairs
151         }
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]),
157                 })
158         }
159         labelPairs = append(labelPairs, desc.constLabelPairs...)
160         sort.Sort(labelPairSorter(labelPairs))
161         return labelPairs
162 }