Skip to content

Commit 2f87680

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 2f87680

1 file changed

Lines changed: 226 additions & 0 deletions

File tree

expfmt/benchmark_test.go

Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
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("http_requests_total"),
30+
Help: proto.String("Total number of HTTP requests."),
31+
Type: dto.MetricType_COUNTER.Enum(),
32+
Unit: proto.String("requests"),
33+
Metric: []*dto.Metric{
34+
{
35+
Label: []*dto.LabelPair{
36+
{Name: proto.String("method"), Value: proto.String("GET")},
37+
{Name: proto.String("handler"), Value: proto.String("/api/v1/query")},
38+
{Name: proto.String("status"), Value: proto.String("200")},
39+
},
40+
Counter: &dto.Counter{
41+
Value: proto.Float64(1027),
42+
CreatedTimestamp: &timestamppb.Timestamp{Seconds: 1234567890},
43+
Exemplar: &dto.Exemplar{
44+
Label: []*dto.LabelPair{
45+
{Name: proto.String("trace_id"), Value: proto.String("1234567890abcdef")},
46+
},
47+
Value: proto.Float64(1.5),
48+
Timestamp: &timestamppb.Timestamp{Seconds: 1234567890, Nanos: 500000000},
49+
},
50+
},
51+
TimestampMs: proto.Int64(1234567891000),
52+
},
53+
},
54+
},
55+
{
56+
Name: proto.String("process_cpu_seconds_total"),
57+
Help: proto.String("Total user and system CPU time spent in seconds."),
58+
Type: dto.MetricType_GAUGE.Enum(),
59+
Unit: proto.String("seconds"),
60+
Metric: []*dto.Metric{
61+
{
62+
Label: []*dto.LabelPair{
63+
{Name: proto.String("mode"), Value: proto.String("user")},
64+
},
65+
Gauge: &dto.Gauge{Value: proto.Float64(123.45)},
66+
TimestampMs: proto.Int64(1234567891000),
67+
},
68+
},
69+
},
70+
{
71+
Name: proto.String("syslog_events_raw"),
72+
Help: proto.String("Raw untyped event count."),
73+
Type: dto.MetricType_UNTYPED.Enum(),
74+
Metric: []*dto.Metric{
75+
{
76+
Label: []*dto.LabelPair{
77+
{Name: proto.String("facility"), Value: proto.String("auth")},
78+
},
79+
Untyped: &dto.Untyped{Value: proto.Float64(42.5)},
80+
TimestampMs: proto.Int64(1234567891000),
81+
},
82+
},
83+
},
84+
{
85+
Name: proto.String("rpc_duration_seconds"),
86+
Help: proto.String("RPC latency summary."),
87+
Type: dto.MetricType_SUMMARY.Enum(),
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("request_duration_microseconds"),
109+
Help: proto.String("The response latency."),
110+
Type: dto.MetricType_HISTOGRAM.Enum(),
111+
Metric: []*dto.Metric{
112+
{
113+
Label: []*dto.LabelPair{
114+
{Name: proto.String("handler"), Value: proto.String("query")},
115+
},
116+
Histogram: &dto.Histogram{
117+
SampleCount: proto.Uint64(2693),
118+
SampleSum: proto.Float64(1756047.3),
119+
CreatedTimestamp: &timestamppb.Timestamp{Seconds: 1234567890},
120+
Schema: proto.Int32(1),
121+
ZeroThreshold: proto.Float64(0.001),
122+
ZeroCount: proto.Uint64(2),
123+
PositiveSpan: []*dto.BucketSpan{
124+
{Offset: proto.Int32(0), Length: proto.Uint32(2)},
125+
},
126+
PositiveDelta: []int64{1, 2},
127+
NegativeSpan: []*dto.BucketSpan{
128+
{Offset: proto.Int32(0), Length: proto.Uint32(1)},
129+
},
130+
NegativeDelta: []int64{1},
131+
Bucket: []*dto.Bucket{
132+
{UpperBound: proto.Float64(100), CumulativeCount: proto.Uint64(123)},
133+
{
134+
UpperBound: proto.Float64(120),
135+
CumulativeCount: proto.Uint64(412),
136+
Exemplar: &dto.Exemplar{
137+
Label: []*dto.LabelPair{
138+
{Name: proto.String("trace_id"), Value: proto.String("abcdef123456")},
139+
},
140+
Value: proto.Float64(115.2),
141+
Timestamp: &timestamppb.Timestamp{Seconds: 1234567890},
142+
},
143+
},
144+
{UpperBound: proto.Float64(144), CumulativeCount: proto.Uint64(592)},
145+
{UpperBound: proto.Float64(math.Inf(+1)), CumulativeCount: proto.Uint64(2693)},
146+
},
147+
},
148+
TimestampMs: proto.Int64(1234567891000),
149+
},
150+
},
151+
},
152+
{
153+
Name: proto.String("queue_size_histogram"),
154+
Help: proto.String("Gauge histogram of queue sizes."),
155+
Type: dto.MetricType_GAUGE_HISTOGRAM.Enum(),
156+
Metric: []*dto.Metric{
157+
{
158+
Label: []*dto.LabelPair{
159+
{Name: proto.String("queue"), Value: proto.String("priority")},
160+
},
161+
Histogram: &dto.Histogram{
162+
SampleCount: proto.Uint64(500),
163+
SampleSum: proto.Float64(12500.0),
164+
Schema: proto.Int32(1),
165+
ZeroThreshold: proto.Float64(0.01),
166+
ZeroCount: proto.Uint64(5),
167+
PositiveSpan: []*dto.BucketSpan{
168+
{Offset: proto.Int32(0), Length: proto.Uint32(2)},
169+
},
170+
PositiveDelta: []int64{10, 15},
171+
Bucket: []*dto.Bucket{
172+
{UpperBound: proto.Float64(10), CumulativeCount: proto.Uint64(100)},
173+
{UpperBound: proto.Float64(20), CumulativeCount: proto.Uint64(350)},
174+
{UpperBound: proto.Float64(math.Inf(+1)), CumulativeCount: proto.Uint64(500)},
175+
},
176+
},
177+
TimestampMs: proto.Int64(1234567891000),
178+
},
179+
},
180+
},
181+
}
182+
}
183+
184+
func BenchmarkConvertMetricFamily(b *testing.B) {
185+
mfs := benchmarkMetricFamilies()
186+
187+
for _, mf := range mfs {
188+
b.Run("TEXT/"+mf.GetType().String(), func(b *testing.B) {
189+
out := bytes.NewBuffer(make([]byte, 0, 1024))
190+
b.ResetTimer()
191+
for i := 0; i < b.N; i++ {
192+
_, err := MetricFamilyToText(out, mf)
193+
if err != nil {
194+
b.Fatal(err)
195+
}
196+
out.Reset()
197+
}
198+
})
199+
b.Run("OM1.0/"+mf.GetType().String(), func(b *testing.B) {
200+
out := bytes.NewBuffer(make([]byte, 0, 1024))
201+
b.ResetTimer()
202+
for i := 0; i < b.N; i++ {
203+
_, err := MetricFamilyToOpenMetrics(out, mf)
204+
if err != nil {
205+
b.Fatal(err)
206+
}
207+
out.Reset()
208+
}
209+
})
210+
b.Run("OM2.0/"+mf.GetType().String(), func(b *testing.B) {
211+
out := bytes.NewBuffer(make([]byte, 0, 1024))
212+
if _, err := MetricFamilyToOpenMetrics20(out, mf); err != nil {
213+
b.Skipf("skipping unsupported type: %v", err)
214+
}
215+
out.Reset()
216+
b.ResetTimer()
217+
for i := 0; i < b.N; i++ {
218+
_, err := MetricFamilyToOpenMetrics20(out, mf)
219+
if err != nil {
220+
b.Fatal(err)
221+
}
222+
out.Reset()
223+
}
224+
})
225+
}
226+
}

0 commit comments

Comments
 (0)