diff --git a/expfmt/encode.go b/expfmt/encode.go index 64dc0eb4..e2d03ea8 100644 --- a/expfmt/encode.go +++ b/expfmt/encode.go @@ -99,8 +99,11 @@ func NegotiateIncludingOpenMetrics(h http.Header) Format { if ac.Type == "text" && ac.SubType == "plain" && (ver == TextVersion || ver == "") { return FmtText } - if ac.Type+"/"+ac.SubType == OpenMetricsType && (ver == OpenMetricsVersion || ver == "") { - return FmtOpenMetrics + if ac.Type+"/"+ac.SubType == OpenMetricsType && (ver == OpenMetricsVersion_0_0_1 || ver == OpenMetricsVersion_1_0_0 || ver == "") { + if ver == OpenMetricsVersion_1_0_0 { + return FmtOpenMetrics_1_0_0 + } + return FmtOpenMetrics_0_0_1 } } return FmtText @@ -146,7 +149,7 @@ func NewEncoder(w io.Writer, format Format) Encoder { }, close: func() error { return nil }, } - case FmtOpenMetrics: + case FmtOpenMetrics_0_0_1, FmtOpenMetrics_1_0_0: return encoderCloser{ encode: func(v *dto.MetricFamily) error { _, err := MetricFamilyToOpenMetrics(w, v) diff --git a/expfmt/encode_test.go b/expfmt/encode_test.go index 63d0bd44..c79a7d76 100644 --- a/expfmt/encode_test.go +++ b/expfmt/encode_test.go @@ -63,6 +63,45 @@ func TestNegotiate(t *testing.T) { } } +func TestNegotiateOpenMetrics(t *testing.T) { + tests := []struct { + name string + acceptHeaderValue string + expectedFmt string + }{ + { + name: "OM format, no version", + acceptHeaderValue: "application/openmetrics-text", + expectedFmt: string(FmtOpenMetrics_0_0_1), + }, + { + name: "OM format, 0.0.1 version", + acceptHeaderValue: "application/openmetrics-text;version=0.0.1", + expectedFmt: string(FmtOpenMetrics_0_0_1), + }, + { + name: "OM format, 1.0.0 version", + acceptHeaderValue: "application/openmetrics-text;version=1.0.0", + expectedFmt: string(FmtOpenMetrics_1_0_0), + }, + { + name: "OM format, invalid version", + acceptHeaderValue: "application/openmetrics-text;version=0.0.4", + expectedFmt: string(FmtText), + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + h := http.Header{} + h.Add(hdrAccept, test.acceptHeaderValue) + actualFmt := string(NegotiateIncludingOpenMetrics(h)) + if actualFmt != test.expectedFmt { + t.Errorf("expected Negotiate to return format %s, but got %s instead", test.expectedFmt, actualFmt) + } + }) + } +} func TestEncode(t *testing.T) { var buff bytes.Buffer delimEncoder := NewEncoder(&buff, FmtProtoDelim) diff --git a/expfmt/expfmt.go b/expfmt/expfmt.go index 0f176fa6..c4cb20f0 100644 --- a/expfmt/expfmt.go +++ b/expfmt/expfmt.go @@ -19,20 +19,22 @@ type Format string // Constants to assemble the Content-Type values for the different wire protocols. const ( - TextVersion = "0.0.4" - ProtoType = `application/vnd.google.protobuf` - ProtoProtocol = `io.prometheus.client.MetricFamily` - ProtoFmt = ProtoType + "; proto=" + ProtoProtocol + ";" - OpenMetricsType = `application/openmetrics-text` - OpenMetricsVersion = "0.0.1" + TextVersion = "0.0.4" + ProtoType = `application/vnd.google.protobuf` + ProtoProtocol = `io.prometheus.client.MetricFamily` + ProtoFmt = ProtoType + "; proto=" + ProtoProtocol + ";" + OpenMetricsType = `application/openmetrics-text` + OpenMetricsVersion_0_0_1 = "0.0.1" + OpenMetricsVersion_1_0_0 = "1.0.0" // The Content-Type values for the different wire protocols. - FmtUnknown Format = `` - FmtText Format = `text/plain; version=` + TextVersion + `; charset=utf-8` - FmtProtoDelim Format = ProtoFmt + ` encoding=delimited` - FmtProtoText Format = ProtoFmt + ` encoding=text` - FmtProtoCompact Format = ProtoFmt + ` encoding=compact-text` - FmtOpenMetrics Format = OpenMetricsType + `; version=` + OpenMetricsVersion + `; charset=utf-8` + FmtUnknown Format = `` + FmtText Format = `text/plain; version=` + TextVersion + `; charset=utf-8` + FmtProtoDelim Format = ProtoFmt + ` encoding=delimited` + FmtProtoText Format = ProtoFmt + ` encoding=text` + FmtProtoCompact Format = ProtoFmt + ` encoding=compact-text` + FmtOpenMetrics_1_0_0 Format = OpenMetricsType + `; version=` + OpenMetricsVersion_1_0_0 + `; charset=utf-8` + FmtOpenMetrics_0_0_1 Format = OpenMetricsType + `; version=` + OpenMetricsVersion_0_0_1 + `; charset=utf-8` ) const (