Skip to content

Commit b6496c7

Browse files
committed
fixup! fixup! fixup! fixup! fixup! fixup! fix: fallback to gauge for protofmt-based negotiations
1 parent 883296e commit b6496c7

File tree

2 files changed

+94
-75
lines changed

2 files changed

+94
-75
lines changed

pkg/metrics_store/metrics_writer.go

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -101,25 +101,45 @@ func SanitizeHeaders(contentType string, writers MetricsWriterList) MetricsWrite
101101

102102
// Removes duplicate headers from the given MetricsWriterList for the same family (generated through CRS).
103103
// These are expected to be consecutive since G** resolution generates groups of similar metrics with same headers before moving onto the next G** spec in the CRS configuration.
104-
if header == lastHeader {
105-
writer.stores[0].headers[i] = ""
106-
} else if strings.HasPrefix(header, "# HELP") {
107-
lastHeader = header
104+
// Skip this step if we encounter a repeated header, as it will be removed.
105+
if header != lastHeader && strings.HasPrefix(header, "# HELP") {
108106

109107
// If the requested content type was proto-based, replace "info" and "statesets" with "gauge", as they are not recognized by Prometheus' protobuf machinery.
110108
if strings.HasPrefix(contentType, expfmt.ProtoType) {
111109
infoTypeString := metric.Info.String()
112110
stateSetTypeString := metric.StateSet.String()
113111
if strings.HasSuffix(header, infoTypeString) {
114-
writer.stores[0].headers[i] = header[:len(header)-len(infoTypeString)] + string(metric.Gauge)
112+
header = header[:len(header)-len(infoTypeString)] + string(metric.Gauge)
113+
writer.stores[0].headers[i] = header
115114
}
116115
if strings.HasSuffix(header, stateSetTypeString) {
117-
writer.stores[0].headers[i] = header[:len(header)-len(stateSetTypeString)] + string(metric.Gauge)
116+
header = header[:len(header)-len(stateSetTypeString)] + string(metric.Gauge)
117+
writer.stores[0].headers[i] = header
118118
}
119119
}
120120
}
121+
122+
// Nullify duplicate headers after the sanitization to not miss out on any new candidates.
123+
if header == lastHeader {
124+
writer.stores[0].headers[i] = ""
125+
}
126+
127+
// Update the last header.
128+
lastHeader = header
121129
}
122130
}
123131
}
132+
133+
// Remove all empty headers.
134+
for _, writer := range writers {
135+
if len(writer.stores) > 0 {
136+
for i := len(writer.stores[0].headers) - 1; i >= 0; i-- {
137+
if writer.stores[0].headers[i] == "" {
138+
writer.stores[0].headers = append(writer.stores[0].headers[:i], writer.stores[0].headers[i+1:]...)
139+
}
140+
}
141+
}
142+
}
143+
124144
return writers
125145
}

pkg/metrics_store/metrics_writer_test.go

Lines changed: 68 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -267,90 +267,89 @@ func TestWriteAllWithEmptyStores(t *testing.T) {
267267
}
268268
}
269269

270-
// TODO: AFFAIR empty headers are ignored by Prometheus? If not, we should remove them.
271270
// No two consecutive headers will be entirely the same. The cases used below are only for their suffixes.
272271
func TestSanitizeHeaders(t *testing.T) {
273-
boilerplateHeaders := []string{
274-
"",
275-
"",
276-
"# HELP foo foo_help\n# TYPE foo gauge",
277-
"# HELP foo foo_help\n# TYPE foo info",
278-
"# HELP foo foo_help\n# TYPE foo stateset",
279-
"# HELP foo foo_help\n# TYPE foo counter",
280-
}
281-
duplicatedBoilerplateHeaders := []string{
282-
"",
283-
"",
284-
"# HELP foo foo_help\n# TYPE foo gauge",
285-
"# HELP foo foo_help\n# TYPE foo gauge",
286-
"# HELP foo foo_help\n# TYPE foo info",
287-
"# HELP foo foo_help\n# TYPE foo info",
288-
"# HELP foo foo_help\n# TYPE foo stateset",
289-
"# HELP foo foo_help\n# TYPE foo stateset",
290-
"# HELP foo foo_help\n# TYPE foo counter",
291-
"# HELP foo foo_help\n# TYPE foo counter",
292-
}
293-
dedepedBoilerplateHeaders := []string{
294-
"",
295-
"",
296-
"# HELP foo foo_help\n# TYPE foo gauge",
297-
"",
298-
"# HELP foo foo_help\n# TYPE foo info",
299-
"",
300-
"# HELP foo foo_help\n# TYPE foo stateset",
301-
"",
302-
"# HELP foo foo_help\n# TYPE foo counter",
303-
"",
304-
}
305-
protoIngestibleHeaders := []string{
306-
"",
307-
"",
308-
"# HELP foo foo_help\n# TYPE foo gauge",
309-
"# HELP foo foo_help\n# TYPE foo gauge",
310-
"# HELP foo foo_help\n# TYPE foo gauge",
311-
"# HELP foo foo_help\n# TYPE foo counter",
312-
}
313-
dedepedProtoIngestibleHeaders := []string{
314-
"",
315-
"",
316-
"# HELP foo foo_help\n# TYPE foo gauge",
317-
"",
318-
"# HELP foo foo_help\n# TYPE foo gauge",
319-
"",
320-
"# HELP foo foo_help\n# TYPE foo gauge",
321-
"",
322-
"# HELP foo foo_help\n# TYPE foo counter",
323-
"",
324-
}
325272
testcases := []struct {
326273
name string
327274
contentType expfmt.Format
328275
headers []string
329276
expectedHeaders []string
330277
}{
331278
{
332-
name: "text-format unique headers",
333-
contentType: expfmt.FmtText,
334-
headers: boilerplateHeaders,
335-
expectedHeaders: boilerplateHeaders,
279+
name: "text-format unique headers",
280+
contentType: expfmt.FmtText,
281+
headers: []string{
282+
"",
283+
"# HELP foo foo_help\n# TYPE foo gauge",
284+
"# HELP foo foo_help\n# TYPE foo info",
285+
"# HELP foo foo_help\n# TYPE foo stateset",
286+
"# HELP foo foo_help\n# TYPE foo counter",
287+
},
288+
expectedHeaders: []string{
289+
"# HELP foo foo_help\n# TYPE foo gauge",
290+
"# HELP foo foo_help\n# TYPE foo info",
291+
"# HELP foo foo_help\n# TYPE foo stateset",
292+
"# HELP foo foo_help\n# TYPE foo counter",
293+
},
336294
},
337295
{
338-
name: "text-format consecutive duplicate headers",
339-
contentType: expfmt.FmtText,
340-
headers: duplicatedBoilerplateHeaders,
341-
expectedHeaders: dedepedBoilerplateHeaders,
296+
name: "text-format consecutive duplicate headers",
297+
contentType: expfmt.FmtText,
298+
headers: []string{
299+
"",
300+
"",
301+
"",
302+
"# HELP foo foo_help\n# TYPE foo gauge",
303+
"# HELP foo foo_help\n# TYPE foo gauge",
304+
"# HELP foo foo_help\n# TYPE foo info",
305+
"# HELP foo foo_help\n# TYPE foo info",
306+
"# HELP foo foo_help\n# TYPE foo stateset",
307+
"# HELP foo foo_help\n# TYPE foo stateset",
308+
"# HELP foo foo_help\n# TYPE foo counter",
309+
"# HELP foo foo_help\n# TYPE foo counter",
310+
},
311+
expectedHeaders: []string{
312+
"# HELP foo foo_help\n# TYPE foo gauge",
313+
"# HELP foo foo_help\n# TYPE foo info",
314+
"# HELP foo foo_help\n# TYPE foo stateset",
315+
"# HELP foo foo_help\n# TYPE foo counter",
316+
},
342317
},
343318
{
344-
name: "proto-format unique headers",
345-
contentType: expfmt.ProtoFmt, // Prometheus ProtoFmt is the only proto-based format we check for.
346-
headers: boilerplateHeaders,
347-
expectedHeaders: protoIngestibleHeaders,
319+
name: "proto-format unique headers",
320+
contentType: expfmt.ProtoFmt, // Prometheus ProtoFmt is the only proto-based format we check for.
321+
headers: []string{
322+
"",
323+
"# HELP foo foo_help\n# TYPE foo gauge",
324+
"# HELP foo foo_help\n# TYPE foo info",
325+
"# HELP foo foo_help\n# TYPE foo stateset",
326+
"# HELP foo foo_help\n# TYPE foo counter",
327+
},
328+
expectedHeaders: []string{
329+
"# HELP foo foo_help\n# TYPE foo gauge",
330+
"# HELP foo foo_help\n# TYPE foo counter",
331+
},
348332
},
349333
{
350-
name: "proto-format consecutive duplicate headers",
351-
contentType: expfmt.ProtoFmt, // Prometheus ProtoFmt is the only proto-based format we check for.
352-
headers: duplicatedBoilerplateHeaders,
353-
expectedHeaders: dedepedProtoIngestibleHeaders,
334+
name: "proto-format consecutive duplicate headers",
335+
contentType: expfmt.ProtoFmt, // Prometheus ProtoFmt is the only proto-based format we check for.
336+
headers: []string{
337+
"",
338+
"",
339+
"",
340+
"# HELP foo foo_help\n# TYPE foo gauge",
341+
"# HELP foo foo_help\n# TYPE foo gauge",
342+
"# HELP foo foo_help\n# TYPE foo info",
343+
"# HELP foo foo_help\n# TYPE foo info",
344+
"# HELP foo foo_help\n# TYPE foo stateset",
345+
"# HELP foo foo_help\n# TYPE foo stateset",
346+
"# HELP foo foo_help\n# TYPE foo counter",
347+
"# HELP foo foo_help\n# TYPE foo counter",
348+
},
349+
expectedHeaders: []string{
350+
"# HELP foo foo_help\n# TYPE foo gauge",
351+
"# HELP foo foo_help\n# TYPE foo counter",
352+
},
354353
},
355354
}
356355

0 commit comments

Comments
 (0)