Skip to content

Commit 9840d1e

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 9840d1e

1 file changed

Lines changed: 228 additions & 0 deletions

File tree

expfmt/benchmark_test.go

Lines changed: 228 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,228 @@
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+
},
117+
Histogram: &dto.Histogram{
118+
SampleCount: proto.Uint64(2693),
119+
SampleSum: proto.Float64(350.25),
120+
CreatedTimestamp: &timestamppb.Timestamp{Seconds: 1234567890},
121+
Schema: proto.Int32(1),
122+
ZeroThreshold: proto.Float64(0.001),
123+
ZeroCount: proto.Uint64(2),
124+
PositiveSpan: []*dto.BucketSpan{
125+
{Offset: proto.Int32(0), Length: proto.Uint32(2)},
126+
},
127+
PositiveDelta: []int64{1, 2},
128+
NegativeSpan: []*dto.BucketSpan{
129+
{Offset: proto.Int32(0), Length: proto.Uint32(1)},
130+
},
131+
NegativeDelta: []int64{1},
132+
Bucket: []*dto.Bucket{
133+
{UpperBound: proto.Float64(0.1), CumulativeCount: proto.Uint64(123)},
134+
{
135+
UpperBound: proto.Float64(0.2),
136+
CumulativeCount: proto.Uint64(412),
137+
Exemplar: &dto.Exemplar{
138+
Label: []*dto.LabelPair{
139+
{Name: proto.String("trace_id"), Value: proto.String("abcdef123456")},
140+
},
141+
Value: proto.Float64(0.1152),
142+
Timestamp: &timestamppb.Timestamp{Seconds: 1234567890},
143+
},
144+
},
145+
{UpperBound: proto.Float64(0.5), CumulativeCount: proto.Uint64(592)},
146+
{UpperBound: proto.Float64(math.Inf(+1)), CumulativeCount: proto.Uint64(2693)},
147+
},
148+
},
149+
TimestampMs: proto.Int64(1234567891000),
150+
},
151+
},
152+
},
153+
{
154+
Name: proto.String("queue_latency_seconds"),
155+
Help: proto.String("Gauge histogram of current queue wait time in seconds."),
156+
Type: dto.MetricType_GAUGE_HISTOGRAM.Enum(),
157+
Unit: proto.String("seconds"),
158+
Metric: []*dto.Metric{
159+
{
160+
Label: []*dto.LabelPair{
161+
{Name: proto.String("queue"), Value: proto.String("priority")},
162+
},
163+
Histogram: &dto.Histogram{
164+
SampleCount: proto.Uint64(500),
165+
SampleSum: proto.Float64(750.5),
166+
Schema: proto.Int32(1),
167+
ZeroThreshold: proto.Float64(0.01),
168+
ZeroCount: proto.Uint64(5),
169+
PositiveSpan: []*dto.BucketSpan{
170+
{Offset: proto.Int32(0), Length: proto.Uint32(2)},
171+
},
172+
PositiveDelta: []int64{10, 15},
173+
Bucket: []*dto.Bucket{
174+
{UpperBound: proto.Float64(1.0), CumulativeCount: proto.Uint64(100)},
175+
{UpperBound: proto.Float64(2.0), CumulativeCount: proto.Uint64(350)},
176+
{UpperBound: proto.Float64(math.Inf(+1)), CumulativeCount: proto.Uint64(500)},
177+
},
178+
},
179+
TimestampMs: proto.Int64(1234567891000),
180+
},
181+
},
182+
},
183+
}
184+
}
185+
186+
func BenchmarkConvertMetricFamily(b *testing.B) {
187+
mfs := benchmarkMetricFamilies()
188+
189+
for _, mf := range mfs {
190+
b.Run("TEXT/"+mf.GetType().String(), func(b *testing.B) {
191+
out := bytes.NewBuffer(make([]byte, 0, 1024))
192+
b.ResetTimer()
193+
for i := 0; i < b.N; i++ {
194+
_, err := MetricFamilyToText(out, mf)
195+
if err != nil {
196+
b.Fatal(err)
197+
}
198+
out.Reset()
199+
}
200+
})
201+
b.Run("OM1.0/"+mf.GetType().String(), func(b *testing.B) {
202+
out := bytes.NewBuffer(make([]byte, 0, 1024))
203+
b.ResetTimer()
204+
for i := 0; i < b.N; i++ {
205+
_, err := MetricFamilyToOpenMetrics(out, mf)
206+
if err != nil {
207+
b.Fatal(err)
208+
}
209+
out.Reset()
210+
}
211+
})
212+
b.Run("OM2.0/"+mf.GetType().String(), func(b *testing.B) {
213+
out := bytes.NewBuffer(make([]byte, 0, 1024))
214+
if _, err := MetricFamilyToOpenMetrics20(out, mf); err != nil {
215+
b.Skipf("skipping unsupported type: %v", err)
216+
}
217+
out.Reset()
218+
b.ResetTimer()
219+
for i := 0; i < b.N; i++ {
220+
_, err := MetricFamilyToOpenMetrics20(out, mf)
221+
if err != nil {
222+
b.Fatal(err)
223+
}
224+
out.Reset()
225+
}
226+
})
227+
}
228+
}

0 commit comments

Comments
 (0)