Skip to content

Commit

Permalink
Bump prometheus/client_model
Browse files Browse the repository at this point in the history
By upgrading prometheus/client_model, several test functions had to be re-written due to 2 breaking changes made in protobuf when parsing messages to text:
1. '<' and '>' characters were replaced with '{' and '}' respectively.
2. The text format is non-deterministic. More information in golang/protobuf#1121

Signed-off-by: Arthur Silva Sens <arthur.sens@coralogix.com>
  • Loading branch information
ArthurSens committed Aug 11, 2023
1 parent e6d9092 commit 70294be
Show file tree
Hide file tree
Showing 11 changed files with 469 additions and 83 deletions.
2 changes: 1 addition & 1 deletion go.mod
Expand Up @@ -7,7 +7,7 @@ require (
github.com/cespare/xxhash/v2 v2.2.0
github.com/davecgh/go-spew v1.1.1
github.com/json-iterator/go v1.1.12
github.com/prometheus/client_model v0.3.0
github.com/prometheus/client_model v0.4.0
github.com/prometheus/common v0.42.0
github.com/prometheus/procfs v0.11.1
golang.org/x/sys v0.10.0
Expand Down
3 changes: 2 additions & 1 deletion go.sum
Expand Up @@ -151,8 +151,9 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4=
github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w=
github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY=
github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU=
github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA=
github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM=
github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc=
Expand Down
41 changes: 33 additions & 8 deletions prometheus/counter_test.go
Expand Up @@ -61,8 +61,15 @@ func TestCounterAdd(t *testing.T) {
m := &dto.Metric{}
counter.Write(m)

if expected, got := `label:<name:"a" value:"1" > label:<name:"b" value:"2" > counter:<value:67.42 > `, m.String(); expected != got {
t.Errorf("expected %q, got %q", expected, got)
expected := &dto.Metric{
Label: []*dto.LabelPair{
{Name: proto.String("a"), Value: proto.String("1")},
{Name: proto.String("b"), Value: proto.String("2")},
},
Counter: &dto.Counter{Value: proto.Float64(67.42)},
}
if !proto.Equal(expected, m) {
t.Errorf("expected %q, got %q", expected, m)
}
}

Expand Down Expand Up @@ -164,8 +171,14 @@ func TestCounterAddInf(t *testing.T) {
m := &dto.Metric{}
counter.Write(m)

if expected, got := `counter:<value:inf > `, m.String(); expected != got {
t.Errorf("expected %q, got %q", expected, got)
expected := &dto.Metric{
Counter: &dto.Counter{
Value: proto.Float64(math.Inf(1)),
},
}

if !proto.Equal(expected, m) {
t.Errorf("expected %q, got %q", expected, m)
}
}

Expand All @@ -188,8 +201,14 @@ func TestCounterAddLarge(t *testing.T) {
m := &dto.Metric{}
counter.Write(m)

if expected, got := fmt.Sprintf("counter:<value:%0.16e > ", large), m.String(); expected != got {
t.Errorf("expected %q, got %q", expected, got)
expected := &dto.Metric{
Counter: &dto.Counter{
Value: proto.Float64(large),
},
}

if !proto.Equal(expected, m) {
t.Errorf("expected %q, got %q", expected, m)
}
}

Expand All @@ -210,8 +229,14 @@ func TestCounterAddSmall(t *testing.T) {
m := &dto.Metric{}
counter.Write(m)

if expected, got := fmt.Sprintf("counter:<value:%0.0e > ", small), m.String(); expected != got {
t.Errorf("expected %q, got %q", expected, got)
expected := &dto.Metric{
Counter: &dto.Counter{
Value: proto.Float64(small),
},
}

if !proto.Equal(expected, m) {
t.Errorf("expected %q, got %q", expected, m)
}
}

Expand Down
11 changes: 7 additions & 4 deletions prometheus/example_metricvec_test.go
Expand Up @@ -14,8 +14,7 @@
package prometheus_test

import (
"fmt"

"google.golang.org/protobuf/encoding/protojson"
"google.golang.org/protobuf/proto"

dto "github.com/prometheus/client_model/go"
Expand Down Expand Up @@ -126,8 +125,12 @@ func ExampleMetricVec() {
if err != nil || len(metricFamilies) != 1 {
panic("unexpected behavior of custom test registry")
}
fmt.Println(metricFamilies[0].String())
metricAsJSON, err := protojson.Marshal(metricFamilies[0])
if err != nil {
panic("error marshling metricFamily")
}
printlnNormalized(metricAsJSON)

// Output:
// name:"library_version_info" help:"Versions of the libraries used in this binary." type:GAUGE metric:<label:<name:"library" value:"k8s.io/client-go" > label:<name:"version" value:"0.18.8" > gauge:<value:1 > > metric:<label:<name:"library" value:"prometheus/client_golang" > label:<name:"version" value:"1.7.1" > gauge:<value:1 > >
// {"name":"library_version_info","help":"Versions of the libraries used in this binary.","type":"GAUGE","metric":[{"label":[{"name":"library","value":"k8s.io/client-go"},{"name":"version","value":"0.18.8"}],"gauge":{"value":1}},{"label":[{"name":"library","value":"prometheus/client_golang"},{"name":"version","value":"1.7.1"}],"gauge":{"value":1}}]}
}
68 changes: 52 additions & 16 deletions prometheus/examples_test.go
Expand Up @@ -25,6 +25,7 @@ import (

dto "github.com/prometheus/client_model/go"
"github.com/prometheus/common/expfmt"
"google.golang.org/protobuf/encoding/protojson"

"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
Expand Down Expand Up @@ -319,10 +320,15 @@ func ExampleSummary() {
// internally).
metric := &dto.Metric{}
temps.Write(metric)
fmt.Println(metric.String())

metricAsJSON, err := protojson.Marshal(metric)
if err != nil {
panic("error marshling metric")
}
printlnNormalized(metricAsJSON)

// Output:
// summary:<sample_count:1000 sample_sum:29969.50000000001 quantile:<quantile:0.5 value:31.1 > quantile:<quantile:0.9 value:41.3 > quantile:<quantile:0.99 value:41.9 > >
// {"summary":{"sampleCount":"1000","sampleSum":29969.50000000001,"quantile":[{"quantile":0.5,"value":31.1},{"quantile":0.9,"value":41.3},{"quantile":0.99,"value":41.9}]}}
}

func ExampleSummaryVec() {
Expand Down Expand Up @@ -354,10 +360,14 @@ func ExampleSummaryVec() {
if err != nil || len(metricFamilies) != 1 {
panic("unexpected behavior of custom test registry")
}
fmt.Println(metricFamilies[0].String())
metricAsJSON, err := protojson.Marshal(metricFamilies[0])
if err != nil {
panic("error marshling metric")
}
printlnNormalized(metricAsJSON)

// Output:
// name:"pond_temperature_celsius" help:"The temperature of the frog pond." type:SUMMARY metric:<label:<name:"species" value:"leiopelma-hochstetteri" > summary:<sample_count:0 sample_sum:0 quantile:<quantile:0.5 value:nan > quantile:<quantile:0.9 value:nan > quantile:<quantile:0.99 value:nan > > > metric:<label:<name:"species" value:"lithobates-catesbeianus" > summary:<sample_count:1000 sample_sum:31956.100000000017 quantile:<quantile:0.5 value:32.4 > quantile:<quantile:0.9 value:41.4 > quantile:<quantile:0.99 value:41.9 > > > metric:<label:<name:"species" value:"litoria-caerulea" > summary:<sample_count:1000 sample_sum:29969.50000000001 quantile:<quantile:0.5 value:31.1 > quantile:<quantile:0.9 value:41.3 > quantile:<quantile:0.99 value:41.9 > > >
// {"name":"pond_temperature_celsius","help":"The temperature of the frog pond.","type":"SUMMARY","metric":[{"label":[{"name":"species","value":"leiopelma-hochstetteri"}],"summary":{"sampleCount":"0","sampleSum":0,"quantile":[{"quantile":0.5,"value":"NaN"},{"quantile":0.9,"value":"NaN"},{"quantile":0.99,"value":"NaN"}]}},{"label":[{"name":"species","value":"lithobates-catesbeianus"}],"summary":{"sampleCount":"1000","sampleSum":31956.100000000017,"quantile":[{"quantile":0.5,"value":32.4},{"quantile":0.9,"value":41.4},{"quantile":0.99,"value":41.9}]}},{"label":[{"name":"species","value":"litoria-caerulea"}],"summary":{"sampleCount":"1000","sampleSum":29969.50000000001,"quantile":[{"quantile":0.5,"value":31.1},{"quantile":0.9,"value":41.3},{"quantile":0.99,"value":41.9}]}}]}
}

func ExampleNewConstSummary() {
Expand All @@ -381,10 +391,14 @@ func ExampleNewConstSummary() {
// internally).
metric := &dto.Metric{}
s.Write(metric)
fmt.Println(metric.String())
metricAsJSON, err := protojson.Marshal(metric)
if err != nil {
panic("error marshling metric")
}
printlnNormalized(metricAsJSON)

// Output:
// label:<name:"code" value:"200" > label:<name:"method" value:"get" > label:<name:"owner" value:"example" > summary:<sample_count:4711 sample_sum:403.34 quantile:<quantile:0.5 value:42.3 > quantile:<quantile:0.9 value:323.3 > >
// {"label":[{"name":"code","value":"200"},{"name":"method","value":"get"},{"name":"owner","value":"example"}],"summary":{"sampleCount":"4711","sampleSum":403.34,"quantile":[{"quantile":0.5,"value":42.3},{"quantile":0.9,"value":323.3}]}}
}

func ExampleHistogram() {
Expand All @@ -404,10 +418,14 @@ func ExampleHistogram() {
// internally).
metric := &dto.Metric{}
temps.Write(metric)
fmt.Println(metric.String())
metricAsJSON, err := protojson.Marshal(metric)
if err != nil {
panic("error marshling metric")
}
printlnNormalized(metricAsJSON)

// Output:
// histogram:<sample_count:1000 sample_sum:29969.50000000001 bucket:<cumulative_count:192 upper_bound:20 > bucket:<cumulative_count:366 upper_bound:25 > bucket:<cumulative_count:501 upper_bound:30 > bucket:<cumulative_count:638 upper_bound:35 > bucket:<cumulative_count:816 upper_bound:40 > >
// {"histogram":{"sampleCount":"1000","sampleSum":29969.50000000001,"bucket":[{"cumulativeCount":"192","upperBound":20},{"cumulativeCount":"366","upperBound":25},{"cumulativeCount":"501","upperBound":30},{"cumulativeCount":"638","upperBound":35},{"cumulativeCount":"816","upperBound":40}]}}
}

func ExampleNewConstHistogram() {
Expand All @@ -431,10 +449,14 @@ func ExampleNewConstHistogram() {
// internally).
metric := &dto.Metric{}
h.Write(metric)
fmt.Println(metric.String())
metricAsJSON, err := protojson.Marshal(metric)
if err != nil {
panic("error marshling metric")
}
printlnNormalized(metricAsJSON)

// Output:
// label:<name:"code" value:"200" > label:<name:"method" value:"get" > label:<name:"owner" value:"example" > histogram:<sample_count:4711 sample_sum:403.34 bucket:<cumulative_count:121 upper_bound:25 > bucket:<cumulative_count:2403 upper_bound:50 > bucket:<cumulative_count:3221 upper_bound:100 > bucket:<cumulative_count:4233 upper_bound:200 > >
// {"label":[{"name":"code","value":"200"},{"name":"method","value":"get"},{"name":"owner","value":"example"}],"histogram":{"sampleCount":"4711","sampleSum":403.34,"bucket":[{"cumulativeCount":"121","upperBound":25},{"cumulativeCount":"2403","upperBound":50},{"cumulativeCount":"3221","upperBound":100},{"cumulativeCount":"4233","upperBound":200}]}}
}

func ExampleNewConstHistogram_WithExemplar() {
Expand Down Expand Up @@ -469,10 +491,14 @@ func ExampleNewConstHistogram_WithExemplar() {
// internally).
metric := &dto.Metric{}
h.Write(metric)
fmt.Println(metric.String())
metricAsJSON, err := protojson.Marshal(metric)
if err != nil {
panic("error marshling metric")
}
printlnNormalized(metricAsJSON)

// Output:
// label:<name:"code" value:"200" > label:<name:"method" value:"get" > label:<name:"owner" value:"example" > histogram:<sample_count:4711 sample_sum:403.34 bucket:<cumulative_count:121 upper_bound:25 exemplar:<label:<name:"testName" value:"testVal" > value:24 timestamp:<seconds:1136214245 > > > bucket:<cumulative_count:2403 upper_bound:50 exemplar:<label:<name:"testName" value:"testVal" > value:42 timestamp:<seconds:1136214245 > > > bucket:<cumulative_count:3221 upper_bound:100 exemplar:<label:<name:"testName" value:"testVal" > value:89 timestamp:<seconds:1136214245 > > > bucket:<cumulative_count:4233 upper_bound:200 exemplar:<label:<name:"testName" value:"testVal" > value:157 timestamp:<seconds:1136214245 > > > >
// {"label":[{"name":"code","value":"200"},{"name":"method","value":"get"},{"name":"owner","value":"example"}],"histogram":{"sampleCount":"4711","sampleSum":403.34,"bucket":[{"cumulativeCount":"121","upperBound":25,"exemplar":{"label":[{"name":"testName","value":"testVal"}],"value":24,"timestamp":"2006-01-02T15:04:05Z"}},{"cumulativeCount":"2403","upperBound":50,"exemplar":{"label":[{"name":"testName","value":"testVal"}],"value":42,"timestamp":"2006-01-02T15:04:05Z"}},{"cumulativeCount":"3221","upperBound":100,"exemplar":{"label":[{"name":"testName","value":"testVal"}],"value":89,"timestamp":"2006-01-02T15:04:05Z"}},{"cumulativeCount":"4233","upperBound":200,"exemplar":{"label":[{"name":"testName","value":"testVal"}],"value":157,"timestamp":"2006-01-02T15:04:05Z"}}]}}
}

func ExampleAlreadyRegisteredError() {
Expand Down Expand Up @@ -567,7 +593,13 @@ temperature_kelvin 4.5

gathering, err = gatherers.Gather()
if err != nil {
fmt.Println(err)
// We expect error collected metric "temperature_kelvin" { label:<name:"location" value:"outside" > gauge:<value:265.3 > } was collected before with the same name and label values
// We cannot assert it because of https://github.com/golang/protobuf/issues/1121
if strings.HasPrefix(err.Error(), `collected metric "temperature_kelvin" `) {
fmt.Println("Found duplicated metric `temperature_kelvin`")
} else {
fmt.Print(err)
}
}
// Note that still as many metrics as possible are returned:
out.Reset()
Expand All @@ -589,7 +621,7 @@ temperature_kelvin 4.5
// temperature_kelvin{location="outside"} 273.14
// temperature_kelvin{location="somewhere else"} 4.5
// ----------
// collected metric "temperature_kelvin" { label:<name:"location" value:"outside" > gauge:<value:265.3 > } was collected before with the same name and label values
// Found duplicated metric `temperature_kelvin`
// # HELP humidity_percent Humidity in %.
// # TYPE humidity_percent gauge
// humidity_percent{location="inside"} 33.2
Expand Down Expand Up @@ -625,8 +657,12 @@ func ExampleNewMetricWithTimestamp() {
// internally).
metric := &dto.Metric{}
s.Write(metric)
fmt.Println(metric.String())
metricAsJSON, err := protojson.Marshal(metric)
if err != nil {
panic("error marshling metric")
}
printlnNormalized(metricAsJSON)

// Output:
// gauge:<value:298.15 > timestamp_ms:1257894000012
// {"gauge":{"value":298.15},"timestampMs":"1257894000012"}
}
20 changes: 12 additions & 8 deletions prometheus/expvar_collector_test.go
Expand Up @@ -15,11 +15,11 @@ package prometheus_test

import (
"expvar"
"fmt"
"sort"
"strings"

dto "github.com/prometheus/client_model/go"
"google.golang.org/protobuf/encoding/protojson"

"github.com/prometheus/client_golang/prometheus"
)
Expand Down Expand Up @@ -81,17 +81,21 @@ func ExampleNewExpvarCollector() {
if !strings.Contains(m.Desc().String(), "expvar_memstats") {
metric.Reset()
m.Write(&metric)
metricStrings = append(metricStrings, metric.String())
metricAsJSON, err := protojson.Marshal(&metric)
if err != nil {
panic("error marshling metric")
}
metricStrings = append(metricStrings, string(metricAsJSON))
}
}
sort.Strings(metricStrings)
for _, s := range metricStrings {
fmt.Println(strings.TrimRight(s, " "))
printlnNormalized([]byte(s))
}
// Output:
// label:<name:"code" value:"200" > label:<name:"method" value:"GET" > untyped:<value:212 >
// label:<name:"code" value:"200" > label:<name:"method" value:"POST" > untyped:<value:11 >
// label:<name:"code" value:"404" > label:<name:"method" value:"GET" > untyped:<value:13 >
// label:<name:"code" value:"404" > label:<name:"method" value:"POST" > untyped:<value:3 >
// untyped:<value:42 >
// {"label":[{"name":"code","value":"200"},{"name":"method","value":"GET"}],"untyped":{"value":212}}
// {"label":[{"name":"code","value":"200"},{"name":"method","value":"POST"}],"untyped":{"value":11}}
// {"label":[{"name":"code","value":"404"},{"name":"method","value":"GET"}],"untyped":{"value":13}}
// {"label":[{"name":"code","value":"404"},{"name":"method","value":"POST"}],"untyped":{"value":3}}
// {"untyped":{"value":42}}
}
15 changes: 13 additions & 2 deletions prometheus/gauge_test.go
Expand Up @@ -22,6 +22,7 @@ import (
"time"

dto "github.com/prometheus/client_model/go"
"google.golang.org/protobuf/proto"
)

func listenGaugeStream(vals, result chan float64, done chan struct{}) {
Expand Down Expand Up @@ -177,8 +178,18 @@ func TestGaugeFunc(t *testing.T) {
m := &dto.Metric{}
gf.Write(m)

if expected, got := `label:<name:"a" value:"1" > label:<name:"b" value:"2" > gauge:<value:3.1415 > `, m.String(); expected != got {
t.Errorf("expected %q, got %q", expected, got)
expected := &dto.Metric{
Label: []*dto.LabelPair{
{Name: proto.String("a"), Value: proto.String("1")},
{Name: proto.String("b"), Value: proto.String("2")},
},
Gauge: &dto.Gauge{
Value: proto.Float64(3.1415),
},
}

if !proto.Equal(expected, m) {
t.Errorf("expected %q, got %q", expected, m)
}
}

Expand Down

0 comments on commit 70294be

Please sign in to comment.