master
go 809 lines 27.5 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 package metrix
4
5 import (
6 "strconv"
7 "strings"
8 "sync"
9 )
10
11 // vecCache stores per-label-values instrument handles with a read-fast path.
12 //
13 // Contract: cache entries are intentionally unbounded for the lifetime of the
14 // vec handle. Store-level retention evicts committed series state, but it does
15 // not prune vecCache handles. Collectors must keep vec label cardinality bounded.
16 type vecCache[T any] struct {
17 backend meterBackend
18 base []LabelSet
19 keys []string
20
21 mu sync.RWMutex
22 cache map[string]T
23
24 makeHandle func(scope HostScope, base []LabelSet, vecSet LabelSet) T
25 }
26
27 func newVecCache[T any](
28 backend meterBackend,
29 base []LabelSet,
30 keys []string,
31 makeHandle func(scope HostScope, base []LabelSet, vecSet LabelSet) T,
32 ) *vecCache[T] {
33 return &vecCache[T]{
34 backend: backend,
35 base: base,
36 keys: keys,
37 cache: make(map[string]T),
38 makeHandle: makeHandle,
39 }
40 }
41
42 func (v *vecCache[T]) get(scope HostScope, labelValues ...string) (T, error) {
43 var zero T
44
45 cacheKey, err := vecSeriesCacheKey(v.keys, labelValues)
46 if err != nil {
47 return zero, err
48 }
49 scope = mustNormalizeHostScope(scope)
50 cacheKey = scopedVecCacheKey(scope.ScopeKey, cacheKey)
51
52 v.mu.RLock()
53 inst, ok := v.cache[cacheKey]
54 v.mu.RUnlock()
55 if ok {
56 return inst, nil
57 }
58
59 v.mu.Lock()
60 defer v.mu.Unlock()
61
62 inst, ok = v.cache[cacheKey]
63 if ok {
64 return inst, nil
65 }
66
67 vecSet, err := vecSeriesCompileLabelSet(v.backend, v.keys, labelValues)
68 if err != nil {
69 return zero, err
70 }
71
72 inst = v.makeHandle(scope, v.base, vecSet)
73 v.cache[cacheKey] = inst
74 return inst, nil
75 }
76
77 func appendVecSet(base []LabelSet, vecSet LabelSet) []LabelSet {
78 return appendLabelSets(base, []LabelSet{vecSet})
79 }
80
81 func mustRegisterInstrument(backend meterBackend, name string, kind metricKind, mode metricMode, opts ...InstrumentOption) *instrumentDescriptor {
82 desc, err := backend.registerInstrument(name, kind, mode, opts...)
83 if err != nil {
84 panic(err)
85 }
86 return desc
87 }
88
89 func mustNormalizeVecLabelKeys(labelKeys []string) []string {
90 keys, err := normalizeVecLabelKeys(labelKeys)
91 if err != nil {
92 panic(err)
93 }
94 return keys
95 }
96
97 // snapshotGaugeVec caches snapshot gauge series handles by vec label values.
98 type snapshotGaugeVec struct {
99 cache *vecCache[*snapshotGaugeInstrument]
100 scope HostScope
101 }
102
103 // statefulGaugeVec caches stateful gauge series handles by vec label values.
104 type statefulGaugeVec struct {
105 cache *vecCache[*statefulGaugeInstrument]
106 scope HostScope
107 }
108
109 // snapshotCounterVec caches snapshot counter series handles by vec label values.
110 type snapshotCounterVec struct {
111 cache *vecCache[*snapshotCounterInstrument]
112 scope HostScope
113 }
114
115 // statefulCounterVec caches stateful counter series handles by vec label values.
116 type statefulCounterVec struct {
117 cache *vecCache[*statefulCounterInstrument]
118 scope HostScope
119 }
120
121 // snapshotHistogramVec caches snapshot histogram series handles by vec label values.
122 type snapshotHistogramVec struct {
123 cache *vecCache[*snapshotHistogramInstrument]
124 scope HostScope
125 }
126
127 // statefulHistogramVec caches stateful histogram series handles by vec label values.
128 type statefulHistogramVec struct {
129 cache *vecCache[*statefulHistogramInstrument]
130 scope HostScope
131 }
132
133 // snapshotSummaryVec caches snapshot summary series handles by vec label values.
134 type snapshotSummaryVec struct {
135 cache *vecCache[*snapshotSummaryInstrument]
136 scope HostScope
137 }
138
139 // statefulSummaryVec caches stateful summary series handles by vec label values.
140 type statefulSummaryVec struct {
141 cache *vecCache[*statefulSummaryInstrument]
142 scope HostScope
143 }
144
145 // snapshotStateSetVec caches snapshot stateset series handles by vec label values.
146 type snapshotStateSetVec struct {
147 cache *vecCache[*snapshotStateSetInstrument]
148 scope HostScope
149 }
150
151 // statefulStateSetVec caches stateful stateset series handles by vec label values.
152 type statefulStateSetVec struct {
153 cache *vecCache[*statefulStateSetInstrument]
154 scope HostScope
155 }
156
157 // snapshotMeasureSetGaugeVec caches snapshot MeasureSet gauge series handles by vec label values.
158 type snapshotMeasureSetGaugeVec struct {
159 cache *vecCache[*snapshotMeasureSetGaugeInstrument]
160 scope HostScope
161 }
162
163 // snapshotMeasureSetCounterVec caches snapshot MeasureSet counter series handles by vec label values.
164 type snapshotMeasureSetCounterVec struct {
165 cache *vecCache[*snapshotMeasureSetCounterInstrument]
166 scope HostScope
167 }
168
169 // statefulMeasureSetGaugeVec caches stateful MeasureSet gauge series handles by vec label values.
170 type statefulMeasureSetGaugeVec struct {
171 cache *vecCache[*statefulMeasureSetGaugeInstrument]
172 scope HostScope
173 }
174
175 // statefulMeasureSetCounterVec caches stateful MeasureSet counter series handles by vec label values.
176 type statefulMeasureSetCounterVec struct {
177 cache *vecCache[*statefulMeasureSetCounterInstrument]
178 scope HostScope
179 }
180
181 // GaugeVec declares or reuses a snapshot gauge and exposes a label-values lookup API.
182 func (m *snapshotMeter) GaugeVec(name string, labelKeys []string, opts ...InstrumentOption) SnapshotGaugeVec {
183 desc := mustRegisterInstrument(m.backend, metricName(m.prefix, name), kindGauge, modeSnapshot, opts...)
184 keys := mustNormalizeVecLabelKeys(labelKeys)
185 base := appendLabelSets(m.sets, nil)
186 return &snapshotGaugeVec{
187 scope: m.scope,
188 cache: newVecCache(m.backend, base, keys, func(scope HostScope, base []LabelSet, vecSet LabelSet) *snapshotGaugeInstrument {
189 return &snapshotGaugeInstrument{
190 backend: m.backend,
191 desc: desc,
192 scope: scope,
193 base: appendVecSet(base, vecSet),
194 }
195 }),
196 }
197 }
198
199 // GaugeVec declares or reuses a stateful gauge and exposes a label-values lookup API.
200 func (m *statefulMeter) GaugeVec(name string, labelKeys []string, opts ...InstrumentOption) StatefulGaugeVec {
201 desc := mustRegisterInstrument(m.backend, metricName(m.prefix, name), kindGauge, modeStateful, opts...)
202 keys := mustNormalizeVecLabelKeys(labelKeys)
203 base := appendLabelSets(m.sets, nil)
204 return &statefulGaugeVec{
205 scope: m.scope,
206 cache: newVecCache(m.backend, base, keys, func(scope HostScope, base []LabelSet, vecSet LabelSet) *statefulGaugeInstrument {
207 return &statefulGaugeInstrument{
208 backend: m.backend,
209 desc: desc,
210 scope: scope,
211 base: appendVecSet(base, vecSet),
212 }
213 }),
214 }
215 }
216
217 // CounterVec declares or reuses a snapshot counter and exposes a label-values lookup API.
218 func (m *snapshotMeter) CounterVec(name string, labelKeys []string, opts ...InstrumentOption) SnapshotCounterVec {
219 desc := mustRegisterInstrument(m.backend, metricName(m.prefix, name), kindCounter, modeSnapshot, opts...)
220 keys := mustNormalizeVecLabelKeys(labelKeys)
221 base := appendLabelSets(m.sets, nil)
222 return &snapshotCounterVec{
223 scope: m.scope,
224 cache: newVecCache(m.backend, base, keys, func(scope HostScope, base []LabelSet, vecSet LabelSet) *snapshotCounterInstrument {
225 return &snapshotCounterInstrument{
226 backend: m.backend,
227 desc: desc,
228 scope: scope,
229 base: appendVecSet(base, vecSet),
230 }
231 }),
232 }
233 }
234
235 // CounterVec declares or reuses a stateful counter and exposes a label-values lookup API.
236 func (m *statefulMeter) CounterVec(name string, labelKeys []string, opts ...InstrumentOption) StatefulCounterVec {
237 desc := mustRegisterInstrument(m.backend, metricName(m.prefix, name), kindCounter, modeStateful, opts...)
238 keys := mustNormalizeVecLabelKeys(labelKeys)
239 base := appendLabelSets(m.sets, nil)
240 return &statefulCounterVec{
241 scope: m.scope,
242 cache: newVecCache(m.backend, base, keys, func(scope HostScope, base []LabelSet, vecSet LabelSet) *statefulCounterInstrument {
243 return &statefulCounterInstrument{
244 backend: m.backend,
245 desc: desc,
246 scope: scope,
247 base: appendVecSet(base, vecSet),
248 }
249 }),
250 }
251 }
252
253 // HistogramVec declares or reuses a snapshot histogram and exposes a label-values lookup API.
254 func (m *snapshotMeter) HistogramVec(name string, labelKeys []string, opts ...InstrumentOption) SnapshotHistogramVec {
255 desc := mustRegisterInstrument(m.backend, metricName(m.prefix, name), kindHistogram, modeSnapshot, opts...)
256 keys := mustNormalizeVecLabelKeys(labelKeys)
257 base := appendLabelSets(m.sets, nil)
258 return &snapshotHistogramVec{
259 scope: m.scope,
260 cache: newVecCache(m.backend, base, keys, func(scope HostScope, base []LabelSet, vecSet LabelSet) *snapshotHistogramInstrument {
261 return &snapshotHistogramInstrument{
262 backend: m.backend,
263 desc: desc,
264 scope: scope,
265 base: appendVecSet(base, vecSet),
266 }
267 }),
268 }
269 }
270
271 // HistogramVec declares or reuses a stateful histogram and exposes a label-values lookup API.
272 func (m *statefulMeter) HistogramVec(name string, labelKeys []string, opts ...InstrumentOption) StatefulHistogramVec {
273 desc := mustRegisterInstrument(m.backend, metricName(m.prefix, name), kindHistogram, modeStateful, opts...)
274 keys := mustNormalizeVecLabelKeys(labelKeys)
275 base := appendLabelSets(m.sets, nil)
276 return &statefulHistogramVec{
277 scope: m.scope,
278 cache: newVecCache(m.backend, base, keys, func(scope HostScope, base []LabelSet, vecSet LabelSet) *statefulHistogramInstrument {
279 return &statefulHistogramInstrument{
280 backend: m.backend,
281 desc: desc,
282 scope: scope,
283 base: appendVecSet(base, vecSet),
284 }
285 }),
286 }
287 }
288
289 // SummaryVec declares or reuses a snapshot summary and exposes a label-values lookup API.
290 func (m *snapshotMeter) SummaryVec(name string, labelKeys []string, opts ...InstrumentOption) SnapshotSummaryVec {
291 desc := mustRegisterInstrument(m.backend, metricName(m.prefix, name), kindSummary, modeSnapshot, opts...)
292 keys := mustNormalizeVecLabelKeys(labelKeys)
293 base := appendLabelSets(m.sets, nil)
294 return &snapshotSummaryVec{
295 scope: m.scope,
296 cache: newVecCache(m.backend, base, keys, func(scope HostScope, base []LabelSet, vecSet LabelSet) *snapshotSummaryInstrument {
297 return &snapshotSummaryInstrument{
298 backend: m.backend,
299 desc: desc,
300 scope: scope,
301 base: appendVecSet(base, vecSet),
302 }
303 }),
304 }
305 }
306
307 // SummaryVec declares or reuses a stateful summary and exposes a label-values lookup API.
308 func (m *statefulMeter) SummaryVec(name string, labelKeys []string, opts ...InstrumentOption) StatefulSummaryVec {
309 desc := mustRegisterInstrument(m.backend, metricName(m.prefix, name), kindSummary, modeStateful, opts...)
310 keys := mustNormalizeVecLabelKeys(labelKeys)
311 base := appendLabelSets(m.sets, nil)
312 return &statefulSummaryVec{
313 scope: m.scope,
314 cache: newVecCache(m.backend, base, keys, func(scope HostScope, base []LabelSet, vecSet LabelSet) *statefulSummaryInstrument {
315 return &statefulSummaryInstrument{
316 backend: m.backend,
317 desc: desc,
318 scope: scope,
319 base: appendVecSet(base, vecSet),
320 }
321 }),
322 }
323 }
324
325 // StateSetVec declares or reuses a snapshot stateset and exposes a label-values lookup API.
326 func (m *snapshotMeter) StateSetVec(name string, labelKeys []string, opts ...InstrumentOption) SnapshotStateSetVec {
327 desc := mustRegisterInstrument(m.backend, metricName(m.prefix, name), kindStateSet, modeSnapshot, opts...)
328 keys := mustNormalizeVecLabelKeys(labelKeys)
329 base := appendLabelSets(m.sets, nil)
330 return &snapshotStateSetVec{
331 scope: m.scope,
332 cache: newVecCache(m.backend, base, keys, func(scope HostScope, base []LabelSet, vecSet LabelSet) *snapshotStateSetInstrument {
333 return &snapshotStateSetInstrument{
334 backend: m.backend,
335 desc: desc,
336 scope: scope,
337 base: appendVecSet(base, vecSet),
338 }
339 }),
340 }
341 }
342
343 // StateSetVec declares or reuses a stateful stateset and exposes a label-values lookup API.
344 func (m *statefulMeter) StateSetVec(name string, labelKeys []string, opts ...InstrumentOption) StatefulStateSetVec {
345 desc := mustRegisterInstrument(m.backend, metricName(m.prefix, name), kindStateSet, modeStateful, opts...)
346 keys := mustNormalizeVecLabelKeys(labelKeys)
347 base := appendLabelSets(m.sets, nil)
348 return &statefulStateSetVec{
349 scope: m.scope,
350 cache: newVecCache(m.backend, base, keys, func(scope HostScope, base []LabelSet, vecSet LabelSet) *statefulStateSetInstrument {
351 return &statefulStateSetInstrument{
352 backend: m.backend,
353 desc: desc,
354 scope: scope,
355 base: appendVecSet(base, vecSet),
356 }
357 }),
358 }
359 }
360
361 // MeasureSetGaugeVec declares or reuses a snapshot MeasureSet gauge and exposes a label-values lookup API.
362 func (m *snapshotMeter) MeasureSetGaugeVec(name string, labelKeys []string, opts ...InstrumentOption) SnapshotMeasureSetGaugeVec {
363 desc := mustRegisterInstrument(m.backend, metricName(m.prefix, name), kindMeasureSet, modeSnapshot, appendMeasureSetSemantics(opts, MeasureSetSemanticsGauge)...)
364 keys := mustNormalizeVecLabelKeys(labelKeys)
365 base := appendLabelSets(m.sets, nil)
366 return &snapshotMeasureSetGaugeVec{
367 scope: m.scope,
368 cache: newVecCache(m.backend, base, keys, func(scope HostScope, base []LabelSet, vecSet LabelSet) *snapshotMeasureSetGaugeInstrument {
369 return &snapshotMeasureSetGaugeInstrument{
370 backend: m.backend,
371 desc: desc,
372 scope: scope,
373 base: appendVecSet(base, vecSet),
374 }
375 }),
376 }
377 }
378
379 // MeasureSetCounterVec declares or reuses a snapshot MeasureSet counter and exposes a label-values lookup API.
380 func (m *snapshotMeter) MeasureSetCounterVec(name string, labelKeys []string, opts ...InstrumentOption) SnapshotMeasureSetCounterVec {
381 desc := mustRegisterInstrument(m.backend, metricName(m.prefix, name), kindMeasureSet, modeSnapshot, appendMeasureSetSemantics(opts, MeasureSetSemanticsCounter)...)
382 keys := mustNormalizeVecLabelKeys(labelKeys)
383 base := appendLabelSets(m.sets, nil)
384 return &snapshotMeasureSetCounterVec{
385 scope: m.scope,
386 cache: newVecCache(m.backend, base, keys, func(scope HostScope, base []LabelSet, vecSet LabelSet) *snapshotMeasureSetCounterInstrument {
387 return &snapshotMeasureSetCounterInstrument{
388 backend: m.backend,
389 desc: desc,
390 scope: scope,
391 base: appendVecSet(base, vecSet),
392 }
393 }),
394 }
395 }
396
397 // MeasureSetGaugeVec declares or reuses a stateful MeasureSet gauge and exposes a label-values lookup API.
398 func (m *statefulMeter) MeasureSetGaugeVec(name string, labelKeys []string, opts ...InstrumentOption) StatefulMeasureSetGaugeVec {
399 desc := mustRegisterInstrument(m.backend, metricName(m.prefix, name), kindMeasureSet, modeStateful, appendMeasureSetSemantics(opts, MeasureSetSemanticsGauge)...)
400 keys := mustNormalizeVecLabelKeys(labelKeys)
401 base := appendLabelSets(m.sets, nil)
402 return &statefulMeasureSetGaugeVec{
403 scope: m.scope,
404 cache: newVecCache(m.backend, base, keys, func(scope HostScope, base []LabelSet, vecSet LabelSet) *statefulMeasureSetGaugeInstrument {
405 return &statefulMeasureSetGaugeInstrument{
406 backend: m.backend,
407 desc: desc,
408 scope: scope,
409 base: appendVecSet(base, vecSet),
410 }
411 }),
412 }
413 }
414
415 // MeasureSetCounterVec declares or reuses a stateful MeasureSet counter and exposes a label-values lookup API.
416 func (m *statefulMeter) MeasureSetCounterVec(name string, labelKeys []string, opts ...InstrumentOption) StatefulMeasureSetCounterVec {
417 desc := mustRegisterInstrument(m.backend, metricName(m.prefix, name), kindMeasureSet, modeStateful, appendMeasureSetSemantics(opts, MeasureSetSemanticsCounter)...)
418 keys := mustNormalizeVecLabelKeys(labelKeys)
419 base := appendLabelSets(m.sets, nil)
420 return &statefulMeasureSetCounterVec{
421 scope: m.scope,
422 cache: newVecCache(m.backend, base, keys, func(scope HostScope, base []LabelSet, vecSet LabelSet) *statefulMeasureSetCounterInstrument {
423 return &statefulMeasureSetCounterInstrument{
424 backend: m.backend,
425 desc: desc,
426 scope: scope,
427 base: appendVecSet(base, vecSet),
428 }
429 }),
430 }
431 }
432
433 func (v *snapshotGaugeVec) WithHostScope(scope HostScope) SnapshotGaugeVec {
434 return &snapshotGaugeVec{cache: v.cache, scope: mustNormalizeHostScope(scope)}
435 }
436
437 func (v *statefulGaugeVec) WithHostScope(scope HostScope) StatefulGaugeVec {
438 return &statefulGaugeVec{cache: v.cache, scope: mustNormalizeHostScope(scope)}
439 }
440
441 func (v *snapshotCounterVec) WithHostScope(scope HostScope) SnapshotCounterVec {
442 return &snapshotCounterVec{cache: v.cache, scope: mustNormalizeHostScope(scope)}
443 }
444
445 func (v *statefulCounterVec) WithHostScope(scope HostScope) StatefulCounterVec {
446 return &statefulCounterVec{cache: v.cache, scope: mustNormalizeHostScope(scope)}
447 }
448
449 func (v *snapshotHistogramVec) WithHostScope(scope HostScope) SnapshotHistogramVec {
450 return &snapshotHistogramVec{cache: v.cache, scope: mustNormalizeHostScope(scope)}
451 }
452
453 func (v *statefulHistogramVec) WithHostScope(scope HostScope) StatefulHistogramVec {
454 return &statefulHistogramVec{cache: v.cache, scope: mustNormalizeHostScope(scope)}
455 }
456
457 func (v *snapshotSummaryVec) WithHostScope(scope HostScope) SnapshotSummaryVec {
458 return &snapshotSummaryVec{cache: v.cache, scope: mustNormalizeHostScope(scope)}
459 }
460
461 func (v *statefulSummaryVec) WithHostScope(scope HostScope) StatefulSummaryVec {
462 return &statefulSummaryVec{cache: v.cache, scope: mustNormalizeHostScope(scope)}
463 }
464
465 func (v *snapshotStateSetVec) WithHostScope(scope HostScope) SnapshotStateSetVec {
466 return &snapshotStateSetVec{cache: v.cache, scope: mustNormalizeHostScope(scope)}
467 }
468
469 func (v *statefulStateSetVec) WithHostScope(scope HostScope) StatefulStateSetVec {
470 return &statefulStateSetVec{cache: v.cache, scope: mustNormalizeHostScope(scope)}
471 }
472
473 func (v *snapshotMeasureSetGaugeVec) WithHostScope(scope HostScope) SnapshotMeasureSetGaugeVec {
474 return &snapshotMeasureSetGaugeVec{cache: v.cache, scope: mustNormalizeHostScope(scope)}
475 }
476
477 func (v *snapshotMeasureSetCounterVec) WithHostScope(scope HostScope) SnapshotMeasureSetCounterVec {
478 return &snapshotMeasureSetCounterVec{cache: v.cache, scope: mustNormalizeHostScope(scope)}
479 }
480
481 func (v *statefulMeasureSetGaugeVec) WithHostScope(scope HostScope) StatefulMeasureSetGaugeVec {
482 return &statefulMeasureSetGaugeVec{cache: v.cache, scope: mustNormalizeHostScope(scope)}
483 }
484
485 func (v *statefulMeasureSetCounterVec) WithHostScope(scope HostScope) StatefulMeasureSetCounterVec {
486 return &statefulMeasureSetCounterVec{cache: v.cache, scope: mustNormalizeHostScope(scope)}
487 }
488
489 // GetWithLabelValues returns a snapshot gauge handle for the provided vec label values.
490 func (v *snapshotGaugeVec) GetWithLabelValues(labelValues ...string) (SnapshotGauge, error) {
491 inst, err := v.cache.get(v.scope, labelValues...)
492 if err != nil {
493 return nil, err
494 }
495 return inst, nil
496 }
497
498 // WithLabelValues returns a snapshot gauge handle and panics on invalid label values.
499 func (v *snapshotGaugeVec) WithLabelValues(labelValues ...string) SnapshotGauge {
500 inst, err := v.GetWithLabelValues(labelValues...)
501 if err != nil {
502 panic(err)
503 }
504 return inst
505 }
506
507 // GetWithLabelValues returns a stateful gauge handle for the provided vec label values.
508 func (v *statefulGaugeVec) GetWithLabelValues(labelValues ...string) (StatefulGauge, error) {
509 inst, err := v.cache.get(v.scope, labelValues...)
510 if err != nil {
511 return nil, err
512 }
513 return inst, nil
514 }
515
516 // WithLabelValues returns a stateful gauge handle and panics on invalid label values.
517 func (v *statefulGaugeVec) WithLabelValues(labelValues ...string) StatefulGauge {
518 inst, err := v.GetWithLabelValues(labelValues...)
519 if err != nil {
520 panic(err)
521 }
522 return inst
523 }
524
525 // GetWithLabelValues returns a snapshot counter handle for the provided vec label values.
526 func (v *snapshotCounterVec) GetWithLabelValues(labelValues ...string) (SnapshotCounter, error) {
527 inst, err := v.cache.get(v.scope, labelValues...)
528 if err != nil {
529 return nil, err
530 }
531 return inst, nil
532 }
533
534 // WithLabelValues returns a snapshot counter handle and panics on invalid label values.
535 func (v *snapshotCounterVec) WithLabelValues(labelValues ...string) SnapshotCounter {
536 inst, err := v.GetWithLabelValues(labelValues...)
537 if err != nil {
538 panic(err)
539 }
540 return inst
541 }
542
543 // GetWithLabelValues returns a stateful counter handle for the provided vec label values.
544 func (v *statefulCounterVec) GetWithLabelValues(labelValues ...string) (StatefulCounter, error) {
545 inst, err := v.cache.get(v.scope, labelValues...)
546 if err != nil {
547 return nil, err
548 }
549 return inst, nil
550 }
551
552 // WithLabelValues returns a stateful counter handle and panics on invalid label values.
553 func (v *statefulCounterVec) WithLabelValues(labelValues ...string) StatefulCounter {
554 inst, err := v.GetWithLabelValues(labelValues...)
555 if err != nil {
556 panic(err)
557 }
558 return inst
559 }
560
561 // GetWithLabelValues returns a snapshot histogram handle for the provided vec label values.
562 func (v *snapshotHistogramVec) GetWithLabelValues(labelValues ...string) (SnapshotHistogram, error) {
563 inst, err := v.cache.get(v.scope, labelValues...)
564 if err != nil {
565 return nil, err
566 }
567 return inst, nil
568 }
569
570 // WithLabelValues returns a snapshot histogram handle and panics on invalid label values.
571 func (v *snapshotHistogramVec) WithLabelValues(labelValues ...string) SnapshotHistogram {
572 inst, err := v.GetWithLabelValues(labelValues...)
573 if err != nil {
574 panic(err)
575 }
576 return inst
577 }
578
579 // GetWithLabelValues returns a stateful histogram handle for the provided vec label values.
580 func (v *statefulHistogramVec) GetWithLabelValues(labelValues ...string) (StatefulHistogram, error) {
581 inst, err := v.cache.get(v.scope, labelValues...)
582 if err != nil {
583 return nil, err
584 }
585 return inst, nil
586 }
587
588 // WithLabelValues returns a stateful histogram handle and panics on invalid label values.
589 func (v *statefulHistogramVec) WithLabelValues(labelValues ...string) StatefulHistogram {
590 inst, err := v.GetWithLabelValues(labelValues...)
591 if err != nil {
592 panic(err)
593 }
594 return inst
595 }
596
597 // GetWithLabelValues returns a snapshot summary handle for the provided vec label values.
598 func (v *snapshotSummaryVec) GetWithLabelValues(labelValues ...string) (SnapshotSummary, error) {
599 inst, err := v.cache.get(v.scope, labelValues...)
600 if err != nil {
601 return nil, err
602 }
603 return inst, nil
604 }
605
606 // WithLabelValues returns a snapshot summary handle and panics on invalid label values.
607 func (v *snapshotSummaryVec) WithLabelValues(labelValues ...string) SnapshotSummary {
608 inst, err := v.GetWithLabelValues(labelValues...)
609 if err != nil {
610 panic(err)
611 }
612 return inst
613 }
614
615 // GetWithLabelValues returns a stateful summary handle for the provided vec label values.
616 func (v *statefulSummaryVec) GetWithLabelValues(labelValues ...string) (StatefulSummary, error) {
617 inst, err := v.cache.get(v.scope, labelValues...)
618 if err != nil {
619 return nil, err
620 }
621 return inst, nil
622 }
623
624 // WithLabelValues returns a stateful summary handle and panics on invalid label values.
625 func (v *statefulSummaryVec) WithLabelValues(labelValues ...string) StatefulSummary {
626 inst, err := v.GetWithLabelValues(labelValues...)
627 if err != nil {
628 panic(err)
629 }
630 return inst
631 }
632
633 // GetWithLabelValues returns a snapshot stateset handle for the provided vec label values.
634 func (v *snapshotStateSetVec) GetWithLabelValues(labelValues ...string) (StateSetInstrument, error) {
635 inst, err := v.cache.get(v.scope, labelValues...)
636 if err != nil {
637 return nil, err
638 }
639 return inst, nil
640 }
641
642 // WithLabelValues returns a snapshot stateset handle and panics on invalid label values.
643 func (v *snapshotStateSetVec) WithLabelValues(labelValues ...string) StateSetInstrument {
644 inst, err := v.GetWithLabelValues(labelValues...)
645 if err != nil {
646 panic(err)
647 }
648 return inst
649 }
650
651 // GetWithLabelValues returns a stateful stateset handle for the provided vec label values.
652 func (v *statefulStateSetVec) GetWithLabelValues(labelValues ...string) (StateSetInstrument, error) {
653 inst, err := v.cache.get(v.scope, labelValues...)
654 if err != nil {
655 return nil, err
656 }
657 return inst, nil
658 }
659
660 // WithLabelValues returns a stateful stateset handle and panics on invalid label values.
661 func (v *statefulStateSetVec) WithLabelValues(labelValues ...string) StateSetInstrument {
662 inst, err := v.GetWithLabelValues(labelValues...)
663 if err != nil {
664 panic(err)
665 }
666 return inst
667 }
668
669 // GetWithLabelValues returns a snapshot MeasureSet gauge handle for the provided vec label values.
670 func (v *snapshotMeasureSetGaugeVec) GetWithLabelValues(labelValues ...string) (SnapshotMeasureSetGauge, error) {
671 inst, err := v.cache.get(v.scope, labelValues...)
672 if err != nil {
673 return nil, err
674 }
675 return inst, nil
676 }
677
678 // WithLabelValues returns a snapshot MeasureSet gauge handle and panics on invalid label values.
679 func (v *snapshotMeasureSetGaugeVec) WithLabelValues(labelValues ...string) SnapshotMeasureSetGauge {
680 inst, err := v.GetWithLabelValues(labelValues...)
681 if err != nil {
682 panic(err)
683 }
684 return inst
685 }
686
687 // GetWithLabelValues returns a snapshot MeasureSet counter handle for the provided vec label values.
688 func (v *snapshotMeasureSetCounterVec) GetWithLabelValues(labelValues ...string) (SnapshotMeasureSetCounter, error) {
689 inst, err := v.cache.get(v.scope, labelValues...)
690 if err != nil {
691 return nil, err
692 }
693 return inst, nil
694 }
695
696 // WithLabelValues returns a snapshot MeasureSet counter handle and panics on invalid label values.
697 func (v *snapshotMeasureSetCounterVec) WithLabelValues(labelValues ...string) SnapshotMeasureSetCounter {
698 inst, err := v.GetWithLabelValues(labelValues...)
699 if err != nil {
700 panic(err)
701 }
702 return inst
703 }
704
705 // GetWithLabelValues returns a stateful MeasureSet gauge handle for the provided vec label values.
706 func (v *statefulMeasureSetGaugeVec) GetWithLabelValues(labelValues ...string) (StatefulMeasureSetGauge, error) {
707 inst, err := v.cache.get(v.scope, labelValues...)
708 if err != nil {
709 return nil, err
710 }
711 return inst, nil
712 }
713
714 // WithLabelValues returns a stateful MeasureSet gauge handle and panics on invalid label values.
715 func (v *statefulMeasureSetGaugeVec) WithLabelValues(labelValues ...string) StatefulMeasureSetGauge {
716 inst, err := v.GetWithLabelValues(labelValues...)
717 if err != nil {
718 panic(err)
719 }
720 return inst
721 }
722
723 // GetWithLabelValues returns a stateful MeasureSet counter handle for the provided vec label values.
724 func (v *statefulMeasureSetCounterVec) GetWithLabelValues(labelValues ...string) (StatefulMeasureSetCounter, error) {
725 inst, err := v.cache.get(v.scope, labelValues...)
726 if err != nil {
727 return nil, err
728 }
729 return inst, nil
730 }
731
732 // WithLabelValues returns a stateful MeasureSet counter handle and panics on invalid label values.
733 func (v *statefulMeasureSetCounterVec) WithLabelValues(labelValues ...string) StatefulMeasureSetCounter {
734 inst, err := v.GetWithLabelValues(labelValues...)
735 if err != nil {
736 panic(err)
737 }
738 return inst
739 }
740
741 // normalizeVecLabelKeys validates and copies vec label keys in declared order.
742 func normalizeVecLabelKeys(labelKeys []string) ([]string, error) {
743 keys := append([]string(nil), labelKeys...)
744 seen := make(map[string]struct{}, len(keys))
745 for _, k := range keys {
746 if k == "" {
747 return nil, errInvalidLabelKey
748 }
749 if _, ok := seen[k]; ok {
750 return nil, errDuplicateLabelKey
751 }
752 seen[k] = struct{}{}
753 }
754 return keys, nil
755 }
756
757 // vecSeriesCacheKey validates vec arity and returns a collision-safe cache key.
758 func vecSeriesCacheKey(keys []string, values []string) (string, error) {
759 if len(values) != len(keys) {
760 return "", errVecLabelValueCount
761 }
762 if len(keys) == 0 {
763 return "", nil
764 }
765 return packVecLabelValues(values), nil
766 }
767
768 // vecSeriesCompileLabelSet compiles a vec label-values tuple into a store-owned LabelSet.
769 // Callers should validate arity first via vecSeriesCacheKey.
770 func vecSeriesCompileLabelSet(backend meterBackend, keys []string, values []string) (LabelSet, error) {
771 if len(values) != len(keys) {
772 return LabelSet{}, errVecLabelValueCount
773 }
774 if len(keys) == 0 {
775 return backend.compileLabelSet(), nil
776 }
777
778 labels := make([]Label, len(keys))
779 for i, key := range keys {
780 labels[i] = Label{Key: key, Value: values[i]}
781 }
782 return backend.compileLabelSet(labels...), nil
783 }
784
785 // packVecLabelValues builds a collision-safe cache key for an ordered values tuple.
786 func packVecLabelValues(values []string) string {
787 if len(values) == 0 {
788 return ""
789 }
790
791 var b strings.Builder
792 for _, v := range values {
793 b.WriteString(strconv.Itoa(len(v)))
794 b.WriteByte(':')
795 b.WriteString(v)
796 b.WriteByte('\xff')
797 }
798 return b.String()
799 }
800
801 func scopedVecCacheKey(scopeKey, labelsKey string) string {
802 if scopeKey == "" {
803 return labelsKey
804 }
805 if labelsKey == "" {
806 return "\xfe" + scopeKey
807 }
808 return "\xfe" + scopeKey + "\xff" + labelsKey
809 }