...
1
16
17 package metrics
18
19 import (
20 "context"
21 "time"
22
23 "github.com/blang/semver/v4"
24 promext "k8s.io/component-base/metrics/prometheusextension"
25 )
26
27
28
29 type PrometheusTimingHistogram interface {
30 GaugeMetric
31 }
32
33
34
35 type TimingHistogram struct {
36 PrometheusTimingHistogram
37 *TimingHistogramOpts
38 nowFunc func() time.Time
39 lazyMetric
40 selfCollector
41 }
42
43 var _ GaugeMetric = &TimingHistogram{}
44 var _ Registerable = &TimingHistogram{}
45 var _ kubeCollector = &TimingHistogram{}
46
47
48
49 func NewTimingHistogram(opts *TimingHistogramOpts) *TimingHistogram {
50 return NewTestableTimingHistogram(time.Now, opts)
51 }
52
53
54 func NewTestableTimingHistogram(nowFunc func() time.Time, opts *TimingHistogramOpts) *TimingHistogram {
55 opts.StabilityLevel.setDefaults()
56
57 h := &TimingHistogram{
58 TimingHistogramOpts: opts,
59 nowFunc: nowFunc,
60 lazyMetric: lazyMetric{stabilityLevel: opts.StabilityLevel},
61 }
62 h.setPrometheusHistogram(noopMetric{})
63 h.lazyInit(h, BuildFQName(opts.Namespace, opts.Subsystem, opts.Name))
64 return h
65 }
66
67
68 func (h *TimingHistogram) setPrometheusHistogram(histogram promext.TimingHistogram) {
69 h.PrometheusTimingHistogram = histogram
70 h.initSelfCollection(histogram)
71 }
72
73
74 func (h *TimingHistogram) DeprecatedVersion() *semver.Version {
75 return parseSemver(h.TimingHistogramOpts.DeprecatedVersion)
76 }
77
78
79
80 func (h *TimingHistogram) initializeMetric() {
81 h.TimingHistogramOpts.annotateStabilityLevel()
82
83 histogram, err := promext.NewTestableTimingHistogram(h.nowFunc, h.TimingHistogramOpts.toPromHistogramOpts())
84 if err != nil {
85 panic(err)
86 }
87 h.setPrometheusHistogram(histogram)
88 }
89
90
91
92 func (h *TimingHistogram) initializeDeprecatedMetric() {
93 h.TimingHistogramOpts.markDeprecated()
94 h.initializeMetric()
95 }
96
97
98 func (h *TimingHistogram) WithContext(ctx context.Context) GaugeMetric {
99 return h.PrometheusTimingHistogram
100 }
101
102
103
104 type TimingHistogramVec struct {
105 *promext.TimingHistogramVec
106 *TimingHistogramOpts
107 nowFunc func() time.Time
108 lazyMetric
109 originalLabels []string
110 }
111
112 var _ GaugeVecMetric = &TimingHistogramVec{}
113 var _ Registerable = &TimingHistogramVec{}
114 var _ kubeCollector = &TimingHistogramVec{}
115
116
117
118
119 func NewTimingHistogramVec(opts *TimingHistogramOpts, labels []string) *TimingHistogramVec {
120 return NewTestableTimingHistogramVec(time.Now, opts, labels)
121 }
122
123
124 func NewTestableTimingHistogramVec(nowFunc func() time.Time, opts *TimingHistogramOpts, labels []string) *TimingHistogramVec {
125 opts.StabilityLevel.setDefaults()
126
127 fqName := BuildFQName(opts.Namespace, opts.Subsystem, opts.Name)
128 allowListLock.RLock()
129 if allowList, ok := labelValueAllowLists[fqName]; ok {
130 opts.LabelValueAllowLists = allowList
131 }
132 allowListLock.RUnlock()
133
134 v := &TimingHistogramVec{
135 TimingHistogramVec: noopTimingHistogramVec,
136 TimingHistogramOpts: opts,
137 nowFunc: nowFunc,
138 originalLabels: labels,
139 lazyMetric: lazyMetric{stabilityLevel: opts.StabilityLevel},
140 }
141 v.lazyInit(v, fqName)
142 return v
143 }
144
145
146 func (v *TimingHistogramVec) DeprecatedVersion() *semver.Version {
147 return parseSemver(v.TimingHistogramOpts.DeprecatedVersion)
148 }
149
150 func (v *TimingHistogramVec) initializeMetric() {
151 v.TimingHistogramOpts.annotateStabilityLevel()
152 v.TimingHistogramVec = promext.NewTestableTimingHistogramVec(v.nowFunc, v.TimingHistogramOpts.toPromHistogramOpts(), v.originalLabels...)
153 }
154
155 func (v *TimingHistogramVec) initializeDeprecatedMetric() {
156 v.TimingHistogramOpts.markDeprecated()
157 v.initializeMetric()
158 }
159
160
161
162
163
164
165
166
167
168
169 func (v *TimingHistogramVec) WithLabelValuesChecked(lvs ...string) (GaugeMetric, error) {
170 if !v.IsCreated() {
171 if v.IsHidden() {
172 return noop, nil
173 }
174 return noop, errNotRegistered
175 }
176 if v.LabelValueAllowLists != nil {
177 v.LabelValueAllowLists.ConstrainToAllowedList(v.originalLabels, lvs)
178 }
179 ops, err := v.TimingHistogramVec.GetMetricWithLabelValues(lvs...)
180 if err != nil {
181 return noop, err
182 }
183 return ops.(GaugeMetric), err
184 }
185
186
187
188
189
190
191 func (v *TimingHistogramVec) WithLabelValues(lvs ...string) GaugeMetric {
192 ans, err := v.WithLabelValuesChecked(lvs...)
193 if err == nil || ErrIsNotRegistered(err) {
194 return ans
195 }
196 panic(err)
197 }
198
199
200
201
202
203
204
205
206
207
208 func (v *TimingHistogramVec) WithChecked(labels map[string]string) (GaugeMetric, error) {
209 if !v.IsCreated() {
210 if v.IsHidden() {
211 return noop, nil
212 }
213 return noop, errNotRegistered
214 }
215 if v.LabelValueAllowLists != nil {
216 v.LabelValueAllowLists.ConstrainLabelMap(labels)
217 }
218 ops, err := v.TimingHistogramVec.GetMetricWith(labels)
219 return ops.(GaugeMetric), err
220 }
221
222
223
224
225
226 func (v *TimingHistogramVec) With(labels map[string]string) GaugeMetric {
227 ans, err := v.WithChecked(labels)
228 if err == nil || ErrIsNotRegistered(err) {
229 return ans
230 }
231 panic(err)
232 }
233
234
235
236
237
238
239
240
241 func (v *TimingHistogramVec) Delete(labels map[string]string) bool {
242 if !v.IsCreated() {
243 return false
244 }
245 return v.TimingHistogramVec.Delete(labels)
246 }
247
248
249 func (v *TimingHistogramVec) Reset() {
250 if !v.IsCreated() {
251 return
252 }
253
254 v.TimingHistogramVec.Reset()
255 }
256
257
258 func (v *TimingHistogramVec) InterfaceWithContext(ctx context.Context) GaugeVecMetric {
259 return &TimingHistogramVecWithContext{
260 ctx: ctx,
261 TimingHistogramVec: v,
262 }
263 }
264
265
266
267 type TimingHistogramVecWithContext struct {
268 *TimingHistogramVec
269 ctx context.Context
270 }
271
View as plain text