1
- // Copyright 2017 The Prometheus Authors
1
+ // Copyright 2020 The Prometheus Authors
2
2
// Licensed under the Apache License, Version 2.0 (the "License");
3
3
// you may not use this file except in compliance with the License.
4
4
// You may obtain a copy of the License at
@@ -21,8 +21,9 @@ import (
21
21
"sort"
22
22
"strings"
23
23
24
- dto "github.com/prometheus/client_model/go"
25
24
"github.com/prometheus/common/expfmt"
25
+
26
+ dto "github.com/prometheus/client_model/go"
26
27
)
27
28
28
29
// A Linter is a Prometheus metrics linter. It identifies issues with metric
@@ -40,21 +41,16 @@ type Problem struct {
40
41
Text string
41
42
}
42
43
43
- // problems is a slice of Problems with a helper method to easily append
44
- // additional Problems to the slice.
45
- type problems []Problem
46
-
47
- // Add appends a new Problem to the slice for the specified metric, with
48
- // the specified issue text.
49
- func (p * problems ) Add (mf dto.MetricFamily , text string ) {
50
- * p = append (* p , Problem {
44
+ // newProblem is helper function to create a Problem.
45
+ func newProblem (mf dto.MetricFamily , text string ) Problem {
46
+ return Problem {
51
47
Metric : mf .GetName (),
52
48
Text : text ,
53
- })
49
+ }
54
50
}
55
51
56
52
// New creates a new Linter that reads an input stream of Prometheus metrics.
57
- // Only the text exposition format is supported.
53
+ // Only the Prometheus text exposition format is supported.
58
54
func New (r io.Reader ) * Linter {
59
55
return & Linter {
60
56
r : r ,
@@ -118,19 +114,19 @@ func lint(mf dto.MetricFamily) []Problem {
118
114
119
115
// lintHelp detects issues related to the help text for a metric.
120
116
func lintHelp (mf dto.MetricFamily ) []Problem {
121
- var problems problems
117
+ var problems [] Problem
122
118
123
119
// Expect all metrics to have help text available.
124
120
if mf .Help == nil {
125
- problems . Add ( mf , "no help text" )
121
+ problems = append ( problems , newProblem ( mf , "no help text" ) )
126
122
}
127
123
128
124
return problems
129
125
}
130
126
131
127
// lintMetricUnits detects issues with metric unit names.
132
128
func lintMetricUnits (mf dto.MetricFamily ) []Problem {
133
- var problems problems
129
+ var problems [] Problem
134
130
135
131
unit , base , ok := metricUnits (* mf .Name )
136
132
if ! ok {
@@ -143,25 +139,25 @@ func lintMetricUnits(mf dto.MetricFamily) []Problem {
143
139
return nil
144
140
}
145
141
146
- problems . Add ( mf , fmt .Sprintf ("use base unit %q instead of %q" , base , unit ))
142
+ problems = append ( problems , newProblem ( mf , fmt .Sprintf ("use base unit %q instead of %q" , base , unit ) ))
147
143
148
144
return problems
149
145
}
150
146
151
147
// lintCounter detects issues specific to counters, as well as patterns that should
152
148
// only be used with counters.
153
149
func lintCounter (mf dto.MetricFamily ) []Problem {
154
- var problems problems
150
+ var problems [] Problem
155
151
156
152
isCounter := mf .GetType () == dto .MetricType_COUNTER
157
153
isUntyped := mf .GetType () == dto .MetricType_UNTYPED
158
154
hasTotalSuffix := strings .HasSuffix (mf .GetName (), "_total" )
159
155
160
156
switch {
161
157
case isCounter && ! hasTotalSuffix :
162
- problems . Add ( mf , `counter metrics should have "_total" suffix` )
158
+ problems = append ( problems , newProblem ( mf , `counter metrics should have "_total" suffix` ) )
163
159
case ! isUntyped && ! isCounter && hasTotalSuffix :
164
- problems . Add ( mf , `non-counter metrics should not have "_total" suffix` )
160
+ problems = append ( problems , newProblem ( mf , `non-counter metrics should not have "_total" suffix` ) )
165
161
}
166
162
167
163
return problems
@@ -176,32 +172,32 @@ func lintHistogramSummaryReserved(mf dto.MetricFamily) []Problem {
176
172
return nil
177
173
}
178
174
179
- var problems problems
175
+ var problems [] Problem
180
176
181
177
isHistogram := t == dto .MetricType_HISTOGRAM
182
178
isSummary := t == dto .MetricType_SUMMARY
183
179
184
180
n := mf .GetName ()
185
181
186
182
if ! isHistogram && strings .HasSuffix (n , "_bucket" ) {
187
- problems . Add ( mf , `non-histogram metrics should not have "_bucket" suffix` )
183
+ problems = append ( problems , newProblem ( mf , `non-histogram metrics should not have "_bucket" suffix` ) )
188
184
}
189
185
if ! isHistogram && ! isSummary && strings .HasSuffix (n , "_count" ) {
190
- problems . Add ( mf , `non-histogram and non-summary metrics should not have "_count" suffix` )
186
+ problems = append ( problems , newProblem ( mf , `non-histogram and non-summary metrics should not have "_count" suffix` ) )
191
187
}
192
188
if ! isHistogram && ! isSummary && strings .HasSuffix (n , "_sum" ) {
193
- problems . Add ( mf , `non-histogram and non-summary metrics should not have "_sum" suffix` )
189
+ problems = append ( problems , newProblem ( mf , `non-histogram and non-summary metrics should not have "_sum" suffix` ) )
194
190
}
195
191
196
192
for _ , m := range mf .GetMetric () {
197
193
for _ , l := range m .GetLabel () {
198
194
ln := l .GetName ()
199
195
200
196
if ! isHistogram && ln == "le" {
201
- problems . Add ( mf , `non-histogram metrics should not have "le" label` )
197
+ problems = append ( problems , newProblem ( mf , `non-histogram metrics should not have "le" label` ) )
202
198
}
203
199
if ! isSummary && ln == "quantile" {
204
- problems . Add ( mf , `non-summary metrics should not have "quantile" label` )
200
+ problems = append ( problems , newProblem ( mf , `non-summary metrics should not have "quantile" label` ) )
205
201
}
206
202
}
207
203
}
@@ -211,7 +207,7 @@ func lintHistogramSummaryReserved(mf dto.MetricFamily) []Problem {
211
207
212
208
// lintMetricTypeInName detects when metric types are included in the metric name.
213
209
func lintMetricTypeInName (mf dto.MetricFamily ) []Problem {
214
- var problems problems
210
+ var problems [] Problem
215
211
n := strings .ToLower (mf .GetName ())
216
212
217
213
for i , t := range dto .MetricType_name {
@@ -221,17 +217,17 @@ func lintMetricTypeInName(mf dto.MetricFamily) []Problem {
221
217
222
218
typename := strings .ToLower (t )
223
219
if strings .Contains (n , "_" + typename + "_" ) || strings .HasSuffix (n , "_" + typename ) {
224
- problems . Add ( mf , fmt .Sprintf (`metric name should not include type '%s'` , typename ))
220
+ problems = append ( problems , newProblem ( mf , fmt .Sprintf (`metric name should not include type '%s'` , typename ) ))
225
221
}
226
222
}
227
223
return problems
228
224
}
229
225
230
226
// lintReservedChars detects colons in metric names.
231
227
func lintReservedChars (mf dto.MetricFamily ) []Problem {
232
- var problems problems
228
+ var problems [] Problem
233
229
if strings .Contains (mf .GetName (), ":" ) {
234
- problems . Add ( mf , "metric names should not contain ':'" )
230
+ problems = append ( problems , newProblem ( mf , "metric names should not contain ':'" ) )
235
231
}
236
232
return problems
237
233
}
@@ -240,15 +236,15 @@ var camelCase = regexp.MustCompile(`[a-z][A-Z]`)
240
236
241
237
// lintCamelCase detects metric names and label names written in camelCase.
242
238
func lintCamelCase (mf dto.MetricFamily ) []Problem {
243
- var problems problems
239
+ var problems [] Problem
244
240
if camelCase .FindString (mf .GetName ()) != "" {
245
- problems . Add ( mf , "metric names should be written in 'snake_case' not 'camelCase'" )
241
+ problems = append ( problems , newProblem ( mf , "metric names should be written in 'snake_case' not 'camelCase'" ) )
246
242
}
247
243
248
244
for _ , m := range mf .GetMetric () {
249
245
for _ , l := range m .GetLabel () {
250
246
if camelCase .FindString (l .GetName ()) != "" {
251
- problems . Add ( mf , "label names should be written in 'snake_case' not 'camelCase'" )
247
+ problems = append ( problems , newProblem ( mf , "label names should be written in 'snake_case' not 'camelCase'" ) )
252
248
}
253
249
}
254
250
}
@@ -257,11 +253,11 @@ func lintCamelCase(mf dto.MetricFamily) []Problem {
257
253
258
254
// lintUnitAbbreviations detects abbreviated units in the metric name.
259
255
func lintUnitAbbreviations (mf dto.MetricFamily ) []Problem {
260
- var problems problems
256
+ var problems [] Problem
261
257
n := strings .ToLower (mf .GetName ())
262
258
for _ , s := range unitAbbreviations {
263
259
if strings .Contains (n , "_" + s + "_" ) || strings .HasSuffix (n , "_" + s ) {
264
- problems . Add ( mf , "metric names should not contain abbreviated units" )
260
+ problems = append ( problems , newProblem ( mf , "metric names should not contain abbreviated units" ) )
265
261
}
266
262
}
267
263
return problems
0 commit comments