Skip to content

Commit 67f3128

Browse files
committed
refactor: Defer metrics label value allow list initialization
Defer the initialization of label value allow lists until the first invocation of `WithLabelValues` or `With`. This fixes the issue that metrics initialized before flag applied which results in label value allow list is not honored.
1 parent 55b83c9 commit 67f3128

File tree

6 files changed

+142
-72
lines changed

6 files changed

+142
-72
lines changed

staging/src/k8s.io/component-base/metrics/counter.go

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -119,11 +119,6 @@ func NewCounterVec(opts *CounterOpts, labels []string) *CounterVec {
119119
opts.StabilityLevel.setDefaults()
120120

121121
fqName := BuildFQName(opts.Namespace, opts.Subsystem, opts.Name)
122-
allowListLock.RLock()
123-
if allowList, ok := labelValueAllowLists[fqName]; ok {
124-
opts.LabelValueAllowLists = allowList
125-
}
126-
allowListLock.RUnlock()
127122

128123
cv := &CounterVec{
129124
CounterVec: noopCounterVec,
@@ -176,7 +171,17 @@ func (v *CounterVec) WithLabelValues(lvs ...string) CounterMetric {
176171
}
177172
if v.LabelValueAllowLists != nil {
178173
v.LabelValueAllowLists.ConstrainToAllowedList(v.originalLabels, lvs)
174+
} else {
175+
v.initializeLabelAllowListsOnce.Do(func() {
176+
allowListLock.RLock()
177+
if allowList, ok := labelValueAllowLists[v.FQName()]; ok {
178+
v.LabelValueAllowLists = allowList
179+
allowList.ConstrainToAllowedList(v.originalLabels, lvs)
180+
}
181+
allowListLock.RUnlock()
182+
})
179183
}
184+
180185
return v.CounterVec.WithLabelValues(lvs...)
181186
}
182187

@@ -190,6 +195,15 @@ func (v *CounterVec) With(labels map[string]string) CounterMetric {
190195
}
191196
if v.LabelValueAllowLists != nil {
192197
v.LabelValueAllowLists.ConstrainLabelMap(labels)
198+
} else {
199+
v.initializeLabelAllowListsOnce.Do(func() {
200+
allowListLock.RLock()
201+
if allowList, ok := labelValueAllowLists[v.FQName()]; ok {
202+
v.LabelValueAllowLists = allowList
203+
allowList.ConstrainLabelMap(labels)
204+
}
205+
allowListLock.RUnlock()
206+
})
193207
}
194208
return v.CounterVec.With(labels)
195209
}

staging/src/k8s.io/component-base/metrics/gauge.go

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -105,11 +105,6 @@ func NewGaugeVec(opts *GaugeOpts, labels []string) *GaugeVec {
105105
opts.StabilityLevel.setDefaults()
106106

107107
fqName := BuildFQName(opts.Namespace, opts.Subsystem, opts.Name)
108-
allowListLock.RLock()
109-
if allowList, ok := labelValueAllowLists[fqName]; ok {
110-
opts.LabelValueAllowLists = allowList
111-
}
112-
allowListLock.RUnlock()
113108

114109
cv := &GaugeVec{
115110
GaugeVec: noopGaugeVec,
@@ -149,6 +144,15 @@ func (v *GaugeVec) WithLabelValuesChecked(lvs ...string) (GaugeMetric, error) {
149144
}
150145
if v.LabelValueAllowLists != nil {
151146
v.LabelValueAllowLists.ConstrainToAllowedList(v.originalLabels, lvs)
147+
} else {
148+
v.initializeLabelAllowListsOnce.Do(func() {
149+
allowListLock.RLock()
150+
if allowList, ok := labelValueAllowLists[v.FQName()]; ok {
151+
v.LabelValueAllowLists = allowList
152+
allowList.ConstrainToAllowedList(v.originalLabels, lvs)
153+
}
154+
allowListLock.RUnlock()
155+
})
152156
}
153157
elt, err := v.GaugeVec.GetMetricWithLabelValues(lvs...)
154158
return elt, err
@@ -186,6 +190,15 @@ func (v *GaugeVec) WithChecked(labels map[string]string) (GaugeMetric, error) {
186190
}
187191
if v.LabelValueAllowLists != nil {
188192
v.LabelValueAllowLists.ConstrainLabelMap(labels)
193+
} else {
194+
v.initializeLabelAllowListsOnce.Do(func() {
195+
allowListLock.RLock()
196+
if allowList, ok := labelValueAllowLists[v.FQName()]; ok {
197+
v.LabelValueAllowLists = allowList
198+
allowList.ConstrainLabelMap(labels)
199+
}
200+
allowListLock.RUnlock()
201+
})
189202
}
190203
elt, err := v.GaugeVec.GetMetricWith(labels)
191204
return elt, err

staging/src/k8s.io/component-base/metrics/histogram.go

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -96,11 +96,6 @@ func NewHistogramVec(opts *HistogramOpts, labels []string) *HistogramVec {
9696
opts.StabilityLevel.setDefaults()
9797

9898
fqName := BuildFQName(opts.Namespace, opts.Subsystem, opts.Name)
99-
allowListLock.RLock()
100-
if allowList, ok := labelValueAllowLists[fqName]; ok {
101-
opts.LabelValueAllowLists = allowList
102-
}
103-
allowListLock.RUnlock()
10499

105100
v := &HistogramVec{
106101
HistogramVec: noopHistogramVec,
@@ -148,6 +143,15 @@ func (v *HistogramVec) WithLabelValues(lvs ...string) ObserverMetric {
148143
}
149144
if v.LabelValueAllowLists != nil {
150145
v.LabelValueAllowLists.ConstrainToAllowedList(v.originalLabels, lvs)
146+
} else {
147+
v.initializeLabelAllowListsOnce.Do(func() {
148+
allowListLock.RLock()
149+
if allowList, ok := labelValueAllowLists[v.FQName()]; ok {
150+
v.LabelValueAllowLists = allowList
151+
allowList.ConstrainToAllowedList(v.originalLabels, lvs)
152+
}
153+
allowListLock.RUnlock()
154+
})
151155
}
152156
return v.HistogramVec.WithLabelValues(lvs...)
153157
}
@@ -162,6 +166,15 @@ func (v *HistogramVec) With(labels map[string]string) ObserverMetric {
162166
}
163167
if v.LabelValueAllowLists != nil {
164168
v.LabelValueAllowLists.ConstrainLabelMap(labels)
169+
} else {
170+
v.initializeLabelAllowListsOnce.Do(func() {
171+
allowListLock.RLock()
172+
if allowList, ok := labelValueAllowLists[v.FQName()]; ok {
173+
v.LabelValueAllowLists = allowList
174+
allowList.ConstrainLabelMap(labels)
175+
}
176+
allowListLock.RUnlock()
177+
})
165178
}
166179
return v.HistogramVec.With(labels)
167180
}

staging/src/k8s.io/component-base/metrics/opts.go

Lines changed: 51 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -44,16 +44,17 @@ var (
4444
// Name must be set to a non-empty string. DeprecatedVersion is defined only
4545
// if the metric for which this options applies is, in fact, deprecated.
4646
type KubeOpts struct {
47-
Namespace string
48-
Subsystem string
49-
Name string
50-
Help string
51-
ConstLabels map[string]string
52-
DeprecatedVersion string
53-
deprecateOnce sync.Once
54-
annotateOnce sync.Once
55-
StabilityLevel StabilityLevel
56-
LabelValueAllowLists *MetricLabelAllowList
47+
Namespace string
48+
Subsystem string
49+
Name string
50+
Help string
51+
ConstLabels map[string]string
52+
DeprecatedVersion string
53+
deprecateOnce sync.Once
54+
annotateOnce sync.Once
55+
StabilityLevel StabilityLevel
56+
initializeLabelAllowListsOnce sync.Once
57+
LabelValueAllowLists *MetricLabelAllowList
5758
}
5859

5960
// BuildFQName joins the given three name components by "_". Empty name
@@ -160,17 +161,18 @@ func (o *GaugeOpts) toPromGaugeOpts() prometheus.GaugeOpts {
160161
// and can safely be left at their zero value, although it is strongly
161162
// encouraged to set a Help string.
162163
type HistogramOpts struct {
163-
Namespace string
164-
Subsystem string
165-
Name string
166-
Help string
167-
ConstLabels map[string]string
168-
Buckets []float64
169-
DeprecatedVersion string
170-
deprecateOnce sync.Once
171-
annotateOnce sync.Once
172-
StabilityLevel StabilityLevel
173-
LabelValueAllowLists *MetricLabelAllowList
164+
Namespace string
165+
Subsystem string
166+
Name string
167+
Help string
168+
ConstLabels map[string]string
169+
Buckets []float64
170+
DeprecatedVersion string
171+
deprecateOnce sync.Once
172+
annotateOnce sync.Once
173+
StabilityLevel StabilityLevel
174+
initializeLabelAllowListsOnce sync.Once
175+
LabelValueAllowLists *MetricLabelAllowList
174176
}
175177

176178
// Modify help description on the metric description.
@@ -206,18 +208,19 @@ func (o *HistogramOpts) toPromHistogramOpts() prometheus.HistogramOpts {
206208
// and can safely be left at their zero value, although it is strongly
207209
// encouraged to set a Help string.
208210
type TimingHistogramOpts struct {
209-
Namespace string
210-
Subsystem string
211-
Name string
212-
Help string
213-
ConstLabels map[string]string
214-
Buckets []float64
215-
InitialValue float64
216-
DeprecatedVersion string
217-
deprecateOnce sync.Once
218-
annotateOnce sync.Once
219-
StabilityLevel StabilityLevel
220-
LabelValueAllowLists *MetricLabelAllowList
211+
Namespace string
212+
Subsystem string
213+
Name string
214+
Help string
215+
ConstLabels map[string]string
216+
Buckets []float64
217+
InitialValue float64
218+
DeprecatedVersion string
219+
deprecateOnce sync.Once
220+
annotateOnce sync.Once
221+
StabilityLevel StabilityLevel
222+
initializeLabelAllowListsOnce sync.Once
223+
LabelValueAllowLists *MetricLabelAllowList
221224
}
222225

223226
// Modify help description on the metric description.
@@ -255,20 +258,21 @@ func (o *TimingHistogramOpts) toPromHistogramOpts() promext.TimingHistogramOpts
255258
// a help string and to explicitly set the Objectives field to the desired value
256259
// as the default value will change in the upcoming v0.10 of the library.
257260
type SummaryOpts struct {
258-
Namespace string
259-
Subsystem string
260-
Name string
261-
Help string
262-
ConstLabels map[string]string
263-
Objectives map[float64]float64
264-
MaxAge time.Duration
265-
AgeBuckets uint32
266-
BufCap uint32
267-
DeprecatedVersion string
268-
deprecateOnce sync.Once
269-
annotateOnce sync.Once
270-
StabilityLevel StabilityLevel
271-
LabelValueAllowLists *MetricLabelAllowList
261+
Namespace string
262+
Subsystem string
263+
Name string
264+
Help string
265+
ConstLabels map[string]string
266+
Objectives map[float64]float64
267+
MaxAge time.Duration
268+
AgeBuckets uint32
269+
BufCap uint32
270+
DeprecatedVersion string
271+
deprecateOnce sync.Once
272+
annotateOnce sync.Once
273+
StabilityLevel StabilityLevel
274+
initializeLabelAllowListsOnce sync.Once
275+
LabelValueAllowLists *MetricLabelAllowList
272276
}
273277

274278
// Modify help description on the metric description.

staging/src/k8s.io/component-base/metrics/summary.go

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -109,11 +109,6 @@ func NewSummaryVec(opts *SummaryOpts, labels []string) *SummaryVec {
109109
opts.StabilityLevel.setDefaults()
110110

111111
fqName := BuildFQName(opts.Namespace, opts.Subsystem, opts.Name)
112-
allowListLock.RLock()
113-
if allowList, ok := labelValueAllowLists[fqName]; ok {
114-
opts.LabelValueAllowLists = allowList
115-
}
116-
allowListLock.RUnlock()
117112

118113
v := &SummaryVec{
119114
SummaryOpts: opts,
@@ -160,6 +155,15 @@ func (v *SummaryVec) WithLabelValues(lvs ...string) ObserverMetric {
160155
}
161156
if v.LabelValueAllowLists != nil {
162157
v.LabelValueAllowLists.ConstrainToAllowedList(v.originalLabels, lvs)
158+
} else {
159+
v.initializeLabelAllowListsOnce.Do(func() {
160+
allowListLock.RLock()
161+
if allowList, ok := labelValueAllowLists[v.FQName()]; ok {
162+
v.LabelValueAllowLists = allowList
163+
allowList.ConstrainToAllowedList(v.originalLabels, lvs)
164+
}
165+
allowListLock.RUnlock()
166+
})
163167
}
164168
return v.SummaryVec.WithLabelValues(lvs...)
165169
}
@@ -174,6 +178,15 @@ func (v *SummaryVec) With(labels map[string]string) ObserverMetric {
174178
}
175179
if v.LabelValueAllowLists != nil {
176180
v.LabelValueAllowLists.ConstrainLabelMap(labels)
181+
} else {
182+
v.initializeLabelAllowListsOnce.Do(func() {
183+
allowListLock.RLock()
184+
if allowList, ok := labelValueAllowLists[v.FQName()]; ok {
185+
v.LabelValueAllowLists = allowList
186+
allowList.ConstrainLabelMap(labels)
187+
}
188+
allowListLock.RUnlock()
189+
})
177190
}
178191
return v.SummaryVec.With(labels)
179192
}

staging/src/k8s.io/component-base/metrics/timing_histogram.go

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -125,11 +125,6 @@ func NewTestableTimingHistogramVec(nowFunc func() time.Time, opts *TimingHistogr
125125
opts.StabilityLevel.setDefaults()
126126

127127
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()
133128

134129
v := &TimingHistogramVec{
135130
TimingHistogramVec: noopTimingHistogramVec,
@@ -175,6 +170,15 @@ func (v *TimingHistogramVec) WithLabelValuesChecked(lvs ...string) (GaugeMetric,
175170
}
176171
if v.LabelValueAllowLists != nil {
177172
v.LabelValueAllowLists.ConstrainToAllowedList(v.originalLabels, lvs)
173+
} else {
174+
v.initializeLabelAllowListsOnce.Do(func() {
175+
allowListLock.RLock()
176+
if allowList, ok := labelValueAllowLists[v.FQName()]; ok {
177+
v.LabelValueAllowLists = allowList
178+
allowList.ConstrainToAllowedList(v.originalLabels, lvs)
179+
}
180+
allowListLock.RUnlock()
181+
})
178182
}
179183
ops, err := v.TimingHistogramVec.GetMetricWithLabelValues(lvs...)
180184
if err != nil {
@@ -214,6 +218,15 @@ func (v *TimingHistogramVec) WithChecked(labels map[string]string) (GaugeMetric,
214218
}
215219
if v.LabelValueAllowLists != nil {
216220
v.LabelValueAllowLists.ConstrainLabelMap(labels)
221+
} else {
222+
v.initializeLabelAllowListsOnce.Do(func() {
223+
allowListLock.RLock()
224+
if allowList, ok := labelValueAllowLists[v.FQName()]; ok {
225+
v.LabelValueAllowLists = allowList
226+
allowList.ConstrainLabelMap(labels)
227+
}
228+
allowListLock.RUnlock()
229+
})
217230
}
218231
ops, err := v.TimingHistogramVec.GetMetricWith(labels)
219232
return ops.(GaugeMetric), err

0 commit comments

Comments
 (0)