...
1
16
17 package metrics
18
19 import (
20 "fmt"
21 "sync"
22
23 "github.com/blang/semver/v4"
24 "github.com/prometheus/client_golang/prometheus"
25
26 "k8s.io/klog/v2"
27 )
28
29
30
31
32 type Desc struct {
33
34 fqName string
35
36 help string
37
38 constLabels Labels
39
40
41 variableLabels []string
42
43
44 promDesc *prometheus.Desc
45 annotatedHelp string
46
47
48 stabilityLevel StabilityLevel
49
50 deprecatedVersion string
51
52 isDeprecated bool
53 isHidden bool
54 isCreated bool
55 createLock sync.RWMutex
56 markDeprecationOnce sync.Once
57 createOnce sync.Once
58 deprecateOnce sync.Once
59 hideOnce sync.Once
60 annotateOnce sync.Once
61 }
62
63
64
65
66
67
68
69
70
71 func NewDesc(fqName string, help string, variableLabels []string, constLabels Labels,
72 stabilityLevel StabilityLevel, deprecatedVersion string) *Desc {
73 d := &Desc{
74 fqName: fqName,
75 help: help,
76 annotatedHelp: help,
77 variableLabels: variableLabels,
78 constLabels: constLabels,
79 stabilityLevel: stabilityLevel,
80 deprecatedVersion: deprecatedVersion,
81 }
82 d.stabilityLevel.setDefaults()
83
84 return d
85 }
86
87
88
89
90
91 func (d *Desc) String() string {
92 if d.isCreated {
93 return d.promDesc.String()
94 }
95
96 return prometheus.NewDesc(d.fqName, d.help, d.variableLabels, prometheus.Labels(d.constLabels)).String()
97 }
98
99
100 func (d *Desc) toPrometheusDesc() *prometheus.Desc {
101 return d.promDesc
102 }
103
104
105 func (d *Desc) DeprecatedVersion() *semver.Version {
106 return parseSemver(d.deprecatedVersion)
107
108 }
109
110 func (d *Desc) determineDeprecationStatus(version semver.Version) {
111 selfVersion := d.DeprecatedVersion()
112 if selfVersion == nil {
113 return
114 }
115 d.markDeprecationOnce.Do(func() {
116 if selfVersion.LTE(version) {
117 d.isDeprecated = true
118 }
119 if ShouldShowHidden() {
120 klog.Warningf("Hidden metrics(%s) have been manually overridden, showing this very deprecated metric.", d.fqName)
121 return
122 }
123 if shouldHide(&version, selfVersion) {
124
125
126 d.isHidden = true
127 }
128 })
129 }
130
131
132 func (d *Desc) IsHidden() bool {
133 return d.isHidden
134 }
135
136
137 func (d *Desc) IsDeprecated() bool {
138 return d.isDeprecated
139 }
140
141
142 func (d *Desc) IsCreated() bool {
143 d.createLock.RLock()
144 defer d.createLock.RUnlock()
145
146 return d.isCreated
147 }
148
149
150
151
152
153
154 func (d *Desc) create(version *semver.Version) bool {
155 if version != nil {
156 d.determineDeprecationStatus(*version)
157 }
158
159
160 if d.IsHidden() {
161 return false
162 }
163 d.createOnce.Do(func() {
164 d.createLock.Lock()
165 defer d.createLock.Unlock()
166
167 d.isCreated = true
168 if d.IsDeprecated() {
169 d.initializeDeprecatedDesc()
170 } else {
171 d.initialize()
172 }
173 })
174 return d.IsCreated()
175 }
176
177
178
179 func (d *Desc) ClearState() {
180 d.isDeprecated = false
181 d.isHidden = false
182 d.isCreated = false
183
184 d.markDeprecationOnce = *new(sync.Once)
185 d.createOnce = *new(sync.Once)
186 d.deprecateOnce = *new(sync.Once)
187 d.hideOnce = *new(sync.Once)
188 d.annotateOnce = *new(sync.Once)
189
190 d.annotatedHelp = d.help
191 d.promDesc = nil
192 }
193
194 func (d *Desc) markDeprecated() {
195 d.deprecateOnce.Do(func() {
196 d.annotatedHelp = fmt.Sprintf("(Deprecated since %s) %s", d.deprecatedVersion, d.annotatedHelp)
197 })
198 }
199
200 func (d *Desc) annotateStabilityLevel() {
201 d.annotateOnce.Do(func() {
202 d.annotatedHelp = fmt.Sprintf("[%v] %v", d.stabilityLevel, d.annotatedHelp)
203 })
204 }
205
206 func (d *Desc) initialize() {
207 d.annotateStabilityLevel()
208
209
210 d.promDesc = prometheus.NewDesc(d.fqName, d.annotatedHelp, d.variableLabels, prometheus.Labels(d.constLabels))
211 }
212
213 func (d *Desc) initializeDeprecatedDesc() {
214 d.markDeprecated()
215 d.initialize()
216 }
217
218
219
220
221
222
223 func (d *Desc) GetRawDesc() *Desc {
224 return NewDesc(d.fqName, d.help, d.variableLabels, d.constLabels, d.stabilityLevel, d.deprecatedVersion)
225 }
226
View as plain text