Skip to content

Commit 46773f6

Browse files
committed
Add BenchmarkConvertMetricFamily comparing OpenMetrics 1.0 and 2.0 encoders
Signed-off-by: David Ashpole <dashpole@google.com>
1 parent 42ca72f commit 46773f6

3 files changed

Lines changed: 230 additions & 197 deletions

File tree

expfmt/benchmark_test.go

Lines changed: 230 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,230 @@
1+
// Copyright The Prometheus Authors
2+
// Licensed under the Apache License, Version 2.0 (the "License");
3+
// you may not use this file except in compliance with the License.
4+
// You may obtain a copy of the License at
5+
//
6+
// http://www.apache.org/licenses/LICENSE-2.0
7+
//
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
14+
package expfmt
15+
16+
import (
17+
"bytes"
18+
"math"
19+
"testing"
20+
21+
dto "github.com/prometheus/client_model/go"
22+
"google.golang.org/protobuf/proto"
23+
"google.golang.org/protobuf/types/known/timestamppb"
24+
)
25+
26+
func benchmarkMetricFamilies() []*dto.MetricFamily {
27+
return []*dto.MetricFamily{
28+
{
29+
Name: proto.String("network_transmit_bytes_total"),
30+
Help: proto.String("Total number of bytes transmitted over the network."),
31+
Type: dto.MetricType_COUNTER.Enum(),
32+
Unit: proto.String("bytes"),
33+
Metric: []*dto.Metric{
34+
{
35+
Label: []*dto.LabelPair{
36+
{Name: proto.String("device"), Value: proto.String("eth0")},
37+
},
38+
Counter: &dto.Counter{
39+
Value: proto.Float64(1024),
40+
CreatedTimestamp: &timestamppb.Timestamp{Seconds: 1234567890},
41+
Exemplar: &dto.Exemplar{
42+
Label: []*dto.LabelPair{
43+
{Name: proto.String("trace_id"), Value: proto.String("1234567890abcdef")},
44+
},
45+
Value: proto.Float64(512),
46+
Timestamp: &timestamppb.Timestamp{Seconds: 1234567890, Nanos: 500000000},
47+
},
48+
},
49+
TimestampMs: proto.Int64(1234567891000),
50+
},
51+
},
52+
},
53+
{
54+
Name: proto.String("process_cpu_seconds_total"),
55+
Help: proto.String("Total user and system CPU time spent in seconds."),
56+
Type: dto.MetricType_GAUGE.Enum(),
57+
Unit: proto.String("seconds"),
58+
Metric: []*dto.Metric{
59+
{
60+
Label: []*dto.LabelPair{
61+
{Name: proto.String("mode"), Value: proto.String("user")},
62+
},
63+
Gauge: &dto.Gauge{Value: proto.Float64(123.45)},
64+
TimestampMs: proto.Int64(1234567891000),
65+
},
66+
},
67+
},
68+
{
69+
Name: proto.String("memory_free_bytes"),
70+
Help: proto.String("Free memory in bytes."),
71+
Type: dto.MetricType_UNTYPED.Enum(),
72+
Unit: proto.String("bytes"),
73+
Metric: []*dto.Metric{
74+
{
75+
Label: []*dto.LabelPair{
76+
{Name: proto.String("numa_node"), Value: proto.String("0")},
77+
},
78+
Untyped: &dto.Untyped{Value: proto.Float64(4294967296.0)},
79+
TimestampMs: proto.Int64(1234567891000),
80+
},
81+
},
82+
},
83+
{
84+
Name: proto.String("rpc_duration_seconds"),
85+
Help: proto.String("RPC latency summary in seconds."),
86+
Type: dto.MetricType_SUMMARY.Enum(),
87+
Unit: proto.String("seconds"),
88+
Metric: []*dto.Metric{
89+
{
90+
Label: []*dto.LabelPair{
91+
{Name: proto.String("service"), Value: proto.String("auth")},
92+
},
93+
Summary: &dto.Summary{
94+
SampleCount: proto.Uint64(100),
95+
SampleSum: proto.Float64(25.5),
96+
CreatedTimestamp: &timestamppb.Timestamp{Seconds: 1234567890},
97+
Quantile: []*dto.Quantile{
98+
{Quantile: proto.Float64(0.5), Value: proto.Float64(0.12)},
99+
{Quantile: proto.Float64(0.9), Value: proto.Float64(0.45)},
100+
{Quantile: proto.Float64(0.99), Value: proto.Float64(0.89)},
101+
},
102+
},
103+
TimestampMs: proto.Int64(1234567891000),
104+
},
105+
},
106+
},
107+
{
108+
Name: proto.String("http_request_duration_seconds"),
109+
Help: proto.String("HTTP request latency in seconds."),
110+
Type: dto.MetricType_HISTOGRAM.Enum(),
111+
Unit: proto.String("seconds"),
112+
Metric: []*dto.Metric{
113+
{
114+
Label: []*dto.LabelPair{
115+
{Name: proto.String("handler"), Value: proto.String("query")},
116+
{Name: proto.String("user_agent"), Value: proto.String("Mozilla/5.0 (with \\backslash, \"quotes\", and\nnewline)")},
117+
{Name: proto.String("region"), Value: proto.String("Björn-佖佥")},
118+
},
119+
Histogram: &dto.Histogram{
120+
SampleCount: proto.Uint64(2693),
121+
SampleSum: proto.Float64(350.25),
122+
CreatedTimestamp: &timestamppb.Timestamp{Seconds: 1234567890},
123+
Schema: proto.Int32(1),
124+
ZeroThreshold: proto.Float64(0.001),
125+
ZeroCount: proto.Uint64(2),
126+
PositiveSpan: []*dto.BucketSpan{
127+
{Offset: proto.Int32(0), Length: proto.Uint32(2)},
128+
},
129+
PositiveDelta: []int64{1, 2},
130+
NegativeSpan: []*dto.BucketSpan{
131+
{Offset: proto.Int32(0), Length: proto.Uint32(1)},
132+
},
133+
NegativeDelta: []int64{1},
134+
Bucket: []*dto.Bucket{
135+
{UpperBound: proto.Float64(0.1), CumulativeCount: proto.Uint64(123)},
136+
{
137+
UpperBound: proto.Float64(0.2),
138+
CumulativeCount: proto.Uint64(412),
139+
Exemplar: &dto.Exemplar{
140+
Label: []*dto.LabelPair{
141+
{Name: proto.String("trace_id"), Value: proto.String("abcdef123456")},
142+
},
143+
Value: proto.Float64(0.1152),
144+
Timestamp: &timestamppb.Timestamp{Seconds: 1234567890},
145+
},
146+
},
147+
{UpperBound: proto.Float64(0.5), CumulativeCount: proto.Uint64(592)},
148+
{UpperBound: proto.Float64(math.Inf(+1)), CumulativeCount: proto.Uint64(2693)},
149+
},
150+
},
151+
TimestampMs: proto.Int64(1234567891000),
152+
},
153+
},
154+
},
155+
{
156+
Name: proto.String("queue_latency_seconds"),
157+
Help: proto.String("Gauge histogram of current queue wait time in seconds."),
158+
Type: dto.MetricType_GAUGE_HISTOGRAM.Enum(),
159+
Unit: proto.String("seconds"),
160+
Metric: []*dto.Metric{
161+
{
162+
Label: []*dto.LabelPair{
163+
{Name: proto.String("queue"), Value: proto.String("priority")},
164+
},
165+
Histogram: &dto.Histogram{
166+
SampleCount: proto.Uint64(500),
167+
SampleSum: proto.Float64(750.5),
168+
Schema: proto.Int32(1),
169+
ZeroThreshold: proto.Float64(0.01),
170+
ZeroCount: proto.Uint64(5),
171+
PositiveSpan: []*dto.BucketSpan{
172+
{Offset: proto.Int32(0), Length: proto.Uint32(2)},
173+
},
174+
PositiveDelta: []int64{10, 15},
175+
Bucket: []*dto.Bucket{
176+
{UpperBound: proto.Float64(1.0), CumulativeCount: proto.Uint64(100)},
177+
{UpperBound: proto.Float64(2.0), CumulativeCount: proto.Uint64(350)},
178+
{UpperBound: proto.Float64(math.Inf(+1)), CumulativeCount: proto.Uint64(500)},
179+
},
180+
},
181+
TimestampMs: proto.Int64(1234567891000),
182+
},
183+
},
184+
},
185+
}
186+
}
187+
188+
func BenchmarkConvertMetricFamily(b *testing.B) {
189+
mfs := benchmarkMetricFamilies()
190+
191+
for _, mf := range mfs {
192+
b.Run("TEXT/"+mf.GetType().String(), func(b *testing.B) {
193+
out := bytes.NewBuffer(make([]byte, 0, 1024))
194+
b.ResetTimer()
195+
for i := 0; i < b.N; i++ {
196+
_, err := MetricFamilyToText(out, mf)
197+
if err != nil {
198+
b.Fatal(err)
199+
}
200+
out.Reset()
201+
}
202+
})
203+
b.Run("OM1.0/"+mf.GetType().String(), func(b *testing.B) {
204+
out := bytes.NewBuffer(make([]byte, 0, 1024))
205+
b.ResetTimer()
206+
for i := 0; i < b.N; i++ {
207+
_, err := MetricFamilyToOpenMetrics(out, mf)
208+
if err != nil {
209+
b.Fatal(err)
210+
}
211+
out.Reset()
212+
}
213+
})
214+
b.Run("OM2.0/"+mf.GetType().String(), func(b *testing.B) {
215+
out := bytes.NewBuffer(make([]byte, 0, 1024))
216+
if _, err := MetricFamilyToOpenMetrics20(out, mf); err != nil {
217+
b.Skipf("skipping unsupported type: %v", err)
218+
}
219+
out.Reset()
220+
b.ResetTimer()
221+
for i := 0; i < b.N; i++ {
222+
_, err := MetricFamilyToOpenMetrics20(out, mf)
223+
if err != nil {
224+
b.Fatal(err)
225+
}
226+
out.Reset()
227+
}
228+
})
229+
}
230+
}

expfmt/openmetrics_create_test.go

Lines changed: 0 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ import (
2121
"time"
2222

2323
dto "github.com/prometheus/client_model/go"
24-
"github.com/stretchr/testify/require"
2524
"google.golang.org/protobuf/proto"
2625
"google.golang.org/protobuf/types/known/timestamppb"
2726

@@ -785,104 +784,6 @@ name_count 2693
785784
}
786785
}
787786

788-
func BenchmarkOpenMetricsCreate(b *testing.B) {
789-
mf := &dto.MetricFamily{
790-
Name: proto.String("request_duration_microseconds"),
791-
Help: proto.String("The response latency."),
792-
Type: dto.MetricType_HISTOGRAM.Enum(),
793-
Metric: []*dto.Metric{
794-
{
795-
Label: []*dto.LabelPair{
796-
{
797-
Name: proto.String("name_1"),
798-
Value: proto.String("val with\nnew line"),
799-
},
800-
{
801-
Name: proto.String("name_2"),
802-
Value: proto.String("val with \\backslash and \"quotes\""),
803-
},
804-
{
805-
Name: proto.String("name_3"),
806-
Value: proto.String("Just a quite long label value to test performance."),
807-
},
808-
},
809-
Histogram: &dto.Histogram{
810-
SampleCount: proto.Uint64(2693),
811-
SampleSum: proto.Float64(1756047.3),
812-
Bucket: []*dto.Bucket{
813-
{
814-
UpperBound: proto.Float64(100),
815-
CumulativeCount: proto.Uint64(123),
816-
},
817-
{
818-
UpperBound: proto.Float64(120),
819-
CumulativeCount: proto.Uint64(412),
820-
},
821-
{
822-
UpperBound: proto.Float64(144),
823-
CumulativeCount: proto.Uint64(592),
824-
},
825-
{
826-
UpperBound: proto.Float64(172.8),
827-
CumulativeCount: proto.Uint64(1524),
828-
},
829-
{
830-
UpperBound: proto.Float64(math.Inf(+1)),
831-
CumulativeCount: proto.Uint64(2693),
832-
},
833-
},
834-
},
835-
},
836-
{
837-
Label: []*dto.LabelPair{
838-
{
839-
Name: proto.String("name_1"),
840-
Value: proto.String("Björn"),
841-
},
842-
{
843-
Name: proto.String("name_2"),
844-
Value: proto.String("佖佥"),
845-
},
846-
{
847-
Name: proto.String("name_3"),
848-
Value: proto.String("Just a quite long label value to test performance."),
849-
},
850-
},
851-
Histogram: &dto.Histogram{
852-
SampleCount: proto.Uint64(5699),
853-
SampleSum: proto.Float64(49484343543.4343),
854-
Bucket: []*dto.Bucket{
855-
{
856-
UpperBound: proto.Float64(100),
857-
CumulativeCount: proto.Uint64(120),
858-
},
859-
{
860-
UpperBound: proto.Float64(120),
861-
CumulativeCount: proto.Uint64(412),
862-
},
863-
{
864-
UpperBound: proto.Float64(144),
865-
CumulativeCount: proto.Uint64(596),
866-
},
867-
{
868-
UpperBound: proto.Float64(172.8),
869-
CumulativeCount: proto.Uint64(1535),
870-
},
871-
},
872-
},
873-
TimestampMs: proto.Int64(1234567890),
874-
},
875-
},
876-
}
877-
out := bytes.NewBuffer(make([]byte, 0, 1024))
878-
879-
for i := 0; i < b.N; i++ {
880-
_, err := MetricFamilyToOpenMetrics(out, mf)
881-
require.NoError(b, err)
882-
out.Reset()
883-
}
884-
}
885-
886787
func TestOpenMetricsCreateError(t *testing.T) {
887788
scenarios := []struct {
888789
in *dto.MetricFamily

0 commit comments

Comments
 (0)