...
1
16
17 package metrics
18
19 import (
20 "sync"
21
22 "github.com/blang/semver/v4"
23 "github.com/prometheus/client_golang/prometheus"
24 dto "github.com/prometheus/client_model/go"
25 promext "k8s.io/component-base/metrics/prometheusextension"
26
27 "k8s.io/klog/v2"
28 )
29
30
36 type kubeCollector interface {
37 Collector
38 lazyKubeMetric
39 DeprecatedVersion() *semver.Version
40
41
42
43
44 initializeMetric()
45 initializeDeprecatedMetric()
46 }
47
48
53 type lazyKubeMetric interface {
54 Create(*semver.Version) bool
55 IsCreated() bool
56 IsHidden() bool
57 IsDeprecated() bool
58 }
59
60
66 type lazyMetric struct {
67 fqName string
68 isDeprecated bool
69 isHidden bool
70 isCreated bool
71 createLock sync.RWMutex
72 markDeprecationOnce sync.Once
73 createOnce sync.Once
74 self kubeCollector
75 stabilityLevel StabilityLevel
76 }
77
78 func (r *lazyMetric) IsCreated() bool {
79 r.createLock.RLock()
80 defer r.createLock.RUnlock()
81 return r.isCreated
82 }
83
84
85
86
87 func (r *lazyMetric) lazyInit(self kubeCollector, fqName string) {
88 r.fqName = fqName
89 r.self = self
90 }
91
92
93
94
95
96
97
98
99
100
101
102 func (r *lazyMetric) preprocessMetric(version semver.Version) {
103 disabledMetricsLock.RLock()
104 defer disabledMetricsLock.RUnlock()
105
106 if _, ok := disabledMetrics[r.fqName]; ok {
107 r.isHidden = true
108 return
109 }
110 selfVersion := r.self.DeprecatedVersion()
111 if selfVersion == nil {
112 return
113 }
114 r.markDeprecationOnce.Do(func() {
115 if selfVersion.LTE(version) {
116 r.isDeprecated = true
117 }
118
119 if ShouldShowHidden() {
120 klog.Warningf("Hidden metrics (%s) have been manually overridden, showing this very deprecated metric.", r.fqName)
121 return
122 }
123 if shouldHide(&version, selfVersion) {
124
125
126 r.isHidden = true
127 }
128 })
129 }
130
131 func (r *lazyMetric) IsHidden() bool {
132 return r.isHidden
133 }
134
135 func (r *lazyMetric) IsDeprecated() bool {
136 return r.isDeprecated
137 }
138
139
140
141
142
143
144 func (r *lazyMetric) Create(version *semver.Version) bool {
145 if version != nil {
146 r.preprocessMetric(*version)
147 }
148
149 if r.IsHidden() {
150 return false
151 }
152
153 r.createOnce.Do(func() {
154 r.createLock.Lock()
155 defer r.createLock.Unlock()
156 r.isCreated = true
157 if r.IsDeprecated() {
158 r.self.initializeDeprecatedMetric()
159 } else {
160 r.self.initializeMetric()
161 }
162 })
163 sl := r.stabilityLevel
164 deprecatedV := r.self.DeprecatedVersion()
165 dv := ""
166 if deprecatedV != nil {
167 dv = deprecatedV.String()
168 }
169 registeredMetricsTotal.WithLabelValues(string(sl), dv).Inc()
170 return r.IsCreated()
171 }
172
173
174
175 func (r *lazyMetric) ClearState() {
176 r.createLock.Lock()
177 defer r.createLock.Unlock()
178
179 r.isDeprecated = false
180 r.isHidden = false
181 r.isCreated = false
182 r.markDeprecationOnce = sync.Once{}
183 r.createOnce = sync.Once{}
184 }
185
186
187 func (r *lazyMetric) FQName() string {
188 return r.fqName
189 }
190
191
197 type selfCollector struct {
198 metric prometheus.Metric
199 }
200
201 func (c *selfCollector) initSelfCollection(m prometheus.Metric) {
202 c.metric = m
203 }
204
205 func (c *selfCollector) Describe(ch chan<- *prometheus.Desc) {
206 ch <- c.metric.Desc()
207 }
208
209 func (c *selfCollector) Collect(ch chan<- prometheus.Metric) {
210 ch <- c.metric
211 }
212
213
214 var noopCounterVec = &prometheus.CounterVec{}
215 var noopHistogramVec = &prometheus.HistogramVec{}
216 var noopTimingHistogramVec = &promext.TimingHistogramVec{}
217 var noopGaugeVec = &prometheus.GaugeVec{}
218
219
220 var noop = &noopMetric{}
221
222 type noopMetric struct{}
223
224 func (noopMetric) Inc() {}
225 func (noopMetric) Add(float64) {}
226 func (noopMetric) Dec() {}
227 func (noopMetric) Set(float64) {}
228 func (noopMetric) Sub(float64) {}
229 func (noopMetric) Observe(float64) {}
230 func (noopMetric) ObserveWithWeight(float64, uint64) {}
231 func (noopMetric) SetToCurrentTime() {}
232 func (noopMetric) Desc() *prometheus.Desc { return nil }
233 func (noopMetric) Write(*dto.Metric) error { return nil }
234 func (noopMetric) Describe(chan<- *prometheus.Desc) {}
235 func (noopMetric) Collect(chan<- prometheus.Metric) {}
236
View as plain text