Skip to content

Commit f313171

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 f313171

1 file changed

Lines changed: 230 additions & 0 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("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+
Unit: proto.String("events"),
75+
Metric: []*dto.Metric{
76+
{
77+
Label: []*dto.LabelPair{
78+
{Name: proto.String("facility"), Value: proto.String("auth")},
79+
},
80+
Untyped: &dto.Untyped{Value: proto.Float64(42.5)},
81+
TimestampMs: proto.Int64(1234567891000),
82+
},
83+
},
84+
},
85+
{
86+
Name: proto.String("rpc_duration_seconds"),
87+
Help: proto.String("RPC latency summary."),
88+
Type: dto.MetricType_SUMMARY.Enum(),
89+
Unit: proto.String("seconds"),
90+
Metric: []*dto.Metric{
91+
{
92+
Label: []*dto.LabelPair{
93+
{Name: proto.String("service"), Value: proto.String("auth")},
94+
},
95+
Summary: &dto.Summary{
96+
SampleCount: proto.Uint64(100),
97+
SampleSum: proto.Float64(25.5),
98+
CreatedTimestamp: &timestamppb.Timestamp{Seconds: 1234567890},
99+
Quantile: []*dto.Quantile{
100+
{Quantile: proto.Float64(0.5), Value: proto.Float64(0.12)},
101+
{Quantile: proto.Float64(0.9), Value: proto.Float64(0.45)},
102+
{Quantile: proto.Float64(0.99), Value: proto.Float64(0.89)},
103+
},
104+
},
105+
TimestampMs: proto.Int64(1234567891000),
106+
},
107+
},
108+
},
109+
{
110+
Name: proto.String("request_duration_microseconds"),
111+
Help: proto.String("The response latency."),
112+
Type: dto.MetricType_HISTOGRAM.Enum(),
113+
Unit: proto.String("microseconds"),
114+
Metric: []*dto.Metric{
115+
{
116+
Label: []*dto.LabelPair{
117+
{Name: proto.String("handler"), Value: proto.String("query")},
118+
},
119+
Histogram: &dto.Histogram{
120+
SampleCount: proto.Uint64(2693),
121+
SampleSum: proto.Float64(1756047.3),
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(100), CumulativeCount: proto.Uint64(123)},
136+
{
137+
UpperBound: proto.Float64(120),
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(115.2),
144+
Timestamp: &timestamppb.Timestamp{Seconds: 1234567890},
145+
},
146+
},
147+
{UpperBound: proto.Float64(144), 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_size_histogram"),
157+
Help: proto.String("Gauge histogram of queue sizes."),
158+
Type: dto.MetricType_GAUGE_HISTOGRAM.Enum(),
159+
Unit: proto.String("items"),
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(12500.0),
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(10), CumulativeCount: proto.Uint64(100)},
177+
{UpperBound: proto.Float64(20), 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+
}

0 commit comments

Comments
 (0)