Skip to content

Commit 56dce38

Browse files
authored
Merge branch 'main' into issue_3198
2 parents d2e0219 + 8e81bbf commit 56dce38

File tree

4 files changed

+206
-1
lines changed

4 files changed

+206
-1
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
5353
([#3223](https://github.com/open-telemetry/opentelemetry-python/pull/3223))
5454
- Add speced out environment variables and arguments for BatchLogRecordProcessor
5555
([#3237](https://github.com/open-telemetry/opentelemetry-python/pull/3237))
56+
- Add benchmark tests for metrics
57+
([#3267](https://github.com/open-telemetry/opentelemetry-python/pull/3267))
5658

5759

5860
## Version 1.17.0/0.38b0 (2023-03-22)

opentelemetry-api/pyproject.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ dependencies = [
2828
"Deprecated >= 1.2.6",
2929
# FIXME This should be able to be removed after 3.12 is released if there is a reliable API
3030
# in importlib.metadata.
31-
"importlib-metadata ~= 6.0",
31+
"importlib-metadata >= 6.0",
3232
]
3333
dynamic = [
3434
"version",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
# Copyright The OpenTelemetry Authors
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
import pytest
15+
16+
from opentelemetry.sdk.metrics import Counter, MeterProvider
17+
from opentelemetry.sdk.metrics.export import (
18+
AggregationTemporality,
19+
InMemoryMetricReader,
20+
)
21+
22+
reader_cumulative = InMemoryMetricReader()
23+
reader_delta = InMemoryMetricReader(
24+
preferred_temporality={
25+
Counter: AggregationTemporality.DELTA,
26+
},
27+
)
28+
provider_reader_cumulative = MeterProvider(
29+
metric_readers=[reader_cumulative],
30+
)
31+
provider_reader_delta = MeterProvider(metric_readers=[reader_delta])
32+
meter_cumulative = provider_reader_cumulative.get_meter("sdk_meter_provider")
33+
meter_delta = provider_reader_delta.get_meter("sdk_meter_provider_delta")
34+
counter_cumulative = meter_cumulative.create_counter("test_counter")
35+
counter_delta = meter_delta.create_counter("test_counter2")
36+
udcounter = meter_cumulative.create_up_down_counter("test_udcounter")
37+
38+
39+
@pytest.mark.parametrize(
40+
("num_labels", "temporality"),
41+
[
42+
(0, "delta"),
43+
(1, "delta"),
44+
(3, "delta"),
45+
(5, "delta"),
46+
(10, "delta"),
47+
(0, "cumulative"),
48+
(1, "cumulative"),
49+
(3, "cumulative"),
50+
(5, "cumulative"),
51+
(10, "cumulative"),
52+
],
53+
)
54+
def test_counter_add(benchmark, num_labels, temporality):
55+
labels = {}
56+
for i in range(num_labels):
57+
labels = {f"Key{i}": f"Value{i}" for i in range(num_labels)}
58+
59+
def benchmark_counter_add():
60+
if temporality == "cumulative":
61+
counter_cumulative.add(1, labels)
62+
else:
63+
counter_delta.add(1, labels)
64+
65+
benchmark(benchmark_counter_add)
66+
67+
68+
@pytest.mark.parametrize("num_labels", [0, 1, 3, 5, 10])
69+
def test_up_down_counter_add(benchmark, num_labels):
70+
labels = {}
71+
for i in range(num_labels):
72+
labels = {f"Key{i}": f"Value{i}" for i in range(num_labels)}
73+
74+
def benchmark_up_down_counter_add():
75+
udcounter.add(1, labels)
76+
77+
benchmark(benchmark_up_down_counter_add)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
# Copyright The OpenTelemetry Authors
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
import random
15+
16+
import pytest
17+
18+
from opentelemetry.sdk.metrics import MeterProvider
19+
from opentelemetry.sdk.metrics.export import InMemoryMetricReader
20+
from opentelemetry.sdk.metrics.view import (
21+
ExplicitBucketHistogramAggregation,
22+
View,
23+
)
24+
25+
MAX_BOUND_VALUE = 10000
26+
27+
28+
def _generate_bounds(bound_count):
29+
bounds = []
30+
for i in range(bound_count):
31+
bounds.append(i * MAX_BOUND_VALUE / bound_count)
32+
return bounds
33+
34+
35+
hist_view_10 = View(
36+
instrument_name="test_histogram_10_bound",
37+
aggregation=ExplicitBucketHistogramAggregation(_generate_bounds(10)),
38+
)
39+
hist_view_49 = View(
40+
instrument_name="test_histogram_49_bound",
41+
aggregation=ExplicitBucketHistogramAggregation(_generate_bounds(49)),
42+
)
43+
hist_view_50 = View(
44+
instrument_name="test_histogram_50_bound",
45+
aggregation=ExplicitBucketHistogramAggregation(_generate_bounds(50)),
46+
)
47+
hist_view_1000 = View(
48+
instrument_name="test_histogram_1000_bound",
49+
aggregation=ExplicitBucketHistogramAggregation(_generate_bounds(1000)),
50+
)
51+
reader = InMemoryMetricReader()
52+
provider = MeterProvider(
53+
metric_readers=[reader],
54+
views=[
55+
hist_view_10,
56+
hist_view_49,
57+
hist_view_50,
58+
hist_view_1000,
59+
],
60+
)
61+
meter = provider.get_meter("sdk_meter_provider")
62+
hist = meter.create_histogram("test_histogram_default")
63+
hist10 = meter.create_histogram("test_histogram_10_bound")
64+
hist49 = meter.create_histogram("test_histogram_49_bound")
65+
hist50 = meter.create_histogram("test_histogram_50_bound")
66+
hist1000 = meter.create_histogram("test_histogram_1000_bound")
67+
68+
69+
@pytest.mark.parametrize("num_labels", [0, 1, 3, 5, 7])
70+
def test_histogram_record(benchmark, num_labels):
71+
labels = {}
72+
for i in range(num_labels):
73+
labels["Key{}".format(i)] = "Value{}".format(i)
74+
75+
def benchmark_histogram_record():
76+
hist.record(random.random() * MAX_BOUND_VALUE)
77+
78+
benchmark(benchmark_histogram_record)
79+
80+
81+
@pytest.mark.parametrize("num_labels", [0, 1, 3, 5, 7])
82+
def test_histogram_record_10(benchmark, num_labels):
83+
labels = {}
84+
for i in range(num_labels):
85+
labels["Key{}".format(i)] = "Value{}".format(i)
86+
87+
def benchmark_histogram_record_10():
88+
hist10.record(random.random() * MAX_BOUND_VALUE)
89+
90+
benchmark(benchmark_histogram_record_10)
91+
92+
93+
@pytest.mark.parametrize("num_labels", [0, 1, 3, 5, 7])
94+
def test_histogram_record_49(benchmark, num_labels):
95+
labels = {}
96+
for i in range(num_labels):
97+
labels["Key{}".format(i)] = "Value{}".format(i)
98+
99+
def benchmark_histogram_record_49():
100+
hist49.record(random.random() * MAX_BOUND_VALUE)
101+
102+
benchmark(benchmark_histogram_record_49)
103+
104+
105+
@pytest.mark.parametrize("num_labels", [0, 1, 3, 5, 7])
106+
def test_histogram_record_50(benchmark, num_labels):
107+
labels = {}
108+
for i in range(num_labels):
109+
labels["Key{}".format(i)] = "Value{}".format(i)
110+
111+
def benchmark_histogram_record_50():
112+
hist50.record(random.random() * MAX_BOUND_VALUE)
113+
114+
benchmark(benchmark_histogram_record_50)
115+
116+
117+
@pytest.mark.parametrize("num_labels", [0, 1, 3, 5, 7])
118+
def test_histogram_record_1000(benchmark, num_labels):
119+
labels = {}
120+
for i in range(num_labels):
121+
labels["Key{}".format(i)] = "Value{}".format(i)
122+
123+
def benchmark_histogram_record_1000():
124+
hist1000.record(random.random() * MAX_BOUND_VALUE)
125+
126+
benchmark(benchmark_histogram_record_1000)

0 commit comments

Comments
 (0)