Skip to content

Commit f0a0cc4

Browse files
ocelotldependabot[bot]lzchensrikanthccvaabmass
authored
Add Exponential Histogram (#2964)
* Bump werkzeug in /docs/examples/fork-process-model/flask-gunicorn (#3179) Bumps [werkzeug](https://github.com/pallets/werkzeug) from 1.0.1 to 2.2.3. - [Release notes](https://github.com/pallets/werkzeug/releases) - [Changelog](https://github.com/pallets/werkzeug/blob/main/CHANGES.rst) - [Commits](pallets/werkzeug@1.0.1...2.2.3) --- updated-dependencies: - dependency-name: werkzeug dependency-type: direct:production ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Leighton Chen <[email protected]> Co-authored-by: Srikanth Chekuri <[email protected]> * Refactor buckets interface * Add missing test case * Remove wrong return * Add comments * Refactor object resetting * More fixes * Refactor exporting of buckets * Fix bug * Fix spelling * Update opentelemetry-sdk/src/opentelemetry/sdk/metrics/_internal/aggregation.py Co-authored-by: Aaron Abbott <[email protected]> * Update opentelemetry-sdk/src/opentelemetry/sdk/metrics/_internal/aggregation.py Co-authored-by: Aaron Abbott <[email protected]> * Fix exception messages * Remove scaling check * Fix typo * Remove wrong instrument * Update opentelemetry-sdk/src/opentelemetry/sdk/metrics/_internal/aggregation.py Co-authored-by: Aaron Abbott <[email protected]> * Add attribute setting lo lock scope * Update opentelemetry-sdk/src/opentelemetry/sdk/metrics/_internal/exponential_histogram/buckets.py Co-authored-by: Srikanth Chekuri <[email protected]> * Fix collect * Remove unreachable code * Fix exporter test cases * Add comment * Expand lock scope * Revert "Expand lock scope" This reverts commit fd9c47b. * Expand lock scope * Add min_max_size test case * Fix lint * Use properties for buckets attributes * Fix bug * Add comment * WIP * Reset values at the beginning of collect * Merging WIP * Add merge submethods * Refactor to use auxiliary methods * Add downscale method * WIP * Finish merge * Refactor storage of positive and negative WIP * WIP * Add test_merge_simple_event_test * WIP * WIP * WIP * WIP * Fix lint * Fix lint * Add delta test case * Avoid using current_point attributes --------- Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Leighton Chen <[email protected]> Co-authored-by: Srikanth Chekuri <[email protected]> Co-authored-by: Aaron Abbott <[email protected]>
1 parent f05fa77 commit f0a0cc4

File tree

9 files changed

+1950
-4
lines changed

9 files changed

+1950
-4
lines changed

CHANGELOG.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1111
- Fix formatting of ConsoleMetricExporter.
1212
([#3197](https://github.com/open-telemetry/opentelemetry-python/pull/3197))
1313

14-
## Version 1.16.0/0.37b0 (2023-02-17)
14+
- Add exponential histogram
15+
([#2964](https://github.com/open-telemetry/opentelemetry-python/pull/2964))
16+
17+
## Version 1.16.0/0.37b0 (2023-02-15)
18+
1519
- Change ``__all__`` to be statically defined.
1620
([#3143](https://github.com/open-telemetry/opentelemetry-python/pull/3143))
1721
- Remove the ability to set a global metric prefix for Prometheus exporter

exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/metric_exporter/__init__.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
ResourceMetrics,
6161
ScopeMetrics,
6262
Sum,
63+
ExponentialHistogram as ExponentialHistogramType,
6364
)
6465

6566
_logger = getLogger(__name__)
@@ -266,6 +267,51 @@ def _translate_data(
266267
metric.data.is_monotonic
267268
)
268269
pb2_metric.sum.data_points.append(pt)
270+
271+
elif isinstance(metric.data, ExponentialHistogramType):
272+
for data_point in metric.data.data_points:
273+
274+
if data_point.positive.bucket_counts:
275+
positive = pb2.ExponentialHistogramDataPoint.Buckets(
276+
offset=data_point.positive.offset,
277+
bucket_counts=data_point.positive.bucket_counts,
278+
)
279+
else:
280+
positive = None
281+
282+
if data_point.negative.bucket_counts:
283+
negative = pb2.ExponentialHistogramDataPoint.Buckets(
284+
offset=data_point.negative.offset,
285+
bucket_counts=data_point.negative.bucket_counts,
286+
)
287+
else:
288+
negative = None
289+
290+
pt = pb2.ExponentialHistogramDataPoint(
291+
attributes=self._translate_attributes(
292+
data_point.attributes
293+
),
294+
time_unix_nano=data_point.time_unix_nano,
295+
start_time_unix_nano=(
296+
data_point.start_time_unix_nano
297+
),
298+
count=data_point.count,
299+
sum=data_point.sum,
300+
scale=data_point.scale,
301+
zero_count=data_point.zero_count,
302+
positive=positive,
303+
negative=negative,
304+
flags=data_point.flags,
305+
max=data_point.max,
306+
min=data_point.min,
307+
)
308+
pb2_metric.exponential_histogram.aggregation_temporality = (
309+
metric.data.aggregation_temporality
310+
)
311+
pb2_metric.exponential_histogram.data_points.append(
312+
pt
313+
)
314+
269315
else:
270316
_logger.warning(
271317
"unsupported data type %s",

exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_metrics_exporter.py

Lines changed: 129 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,14 @@
6262
ObservableUpDownCounter,
6363
UpDownCounter,
6464
)
65-
from opentelemetry.sdk.metrics.export import AggregationTemporality, Gauge
65+
from opentelemetry.sdk.metrics.export import AggregationTemporality, Buckets
66+
from opentelemetry.sdk.metrics.export import (
67+
ExponentialHistogram as ExponentialHistogramType,
68+
)
69+
from opentelemetry.sdk.metrics.export import (
70+
ExponentialHistogramDataPoint,
71+
Gauge,
72+
)
6673
from opentelemetry.sdk.metrics.export import Histogram as HistogramType
6774
from opentelemetry.sdk.metrics.export import (
6875
HistogramDataPoint,
@@ -163,6 +170,31 @@ def setUp(self):
163170
),
164171
)
165172

173+
exponential_histogram = Metric(
174+
name="exponential_histogram",
175+
description="description",
176+
unit="unit",
177+
data=ExponentialHistogramType(
178+
data_points=[
179+
ExponentialHistogramDataPoint(
180+
attributes={"a": 1, "b": True},
181+
start_time_unix_nano=0,
182+
time_unix_nano=1,
183+
count=2,
184+
sum=3,
185+
scale=4,
186+
zero_count=5,
187+
positive=Buckets(offset=6, bucket_counts=[7, 8]),
188+
negative=Buckets(offset=9, bucket_counts=[10, 11]),
189+
flags=12,
190+
min=13.0,
191+
max=14.0,
192+
)
193+
],
194+
aggregation_temporality=AggregationTemporality.DELTA,
195+
),
196+
)
197+
166198
self.metrics = {
167199
"sum_int": MetricsData(
168200
resource_metrics=[
@@ -276,6 +308,28 @@ def setUp(self):
276308
)
277309
]
278310
),
311+
"exponential_histogram": MetricsData(
312+
resource_metrics=[
313+
ResourceMetrics(
314+
resource=Resource(
315+
attributes={"a": 1, "b": False},
316+
schema_url="resource_schema_url",
317+
),
318+
scope_metrics=[
319+
ScopeMetrics(
320+
scope=SDKInstrumentationScope(
321+
name="first_name",
322+
version="first_version",
323+
schema_url="insrumentation_scope_schema_url",
324+
),
325+
metrics=[exponential_histogram],
326+
schema_url="instrumentation_scope_schema_url",
327+
)
328+
],
329+
schema_url="resource_schema_url",
330+
)
331+
]
332+
),
279333
}
280334

281335
self.multiple_scope_histogram = MetricsData(
@@ -896,6 +950,80 @@ def test_translate_histogram(self):
896950
actual = self.exporter._translate_data(self.metrics["histogram"])
897951
self.assertEqual(expected, actual)
898952

953+
def test_translate_exponential_histogram(self):
954+
expected = ExportMetricsServiceRequest(
955+
resource_metrics=[
956+
pb2.ResourceMetrics(
957+
resource=OTLPResource(
958+
attributes=[
959+
KeyValue(key="a", value=AnyValue(int_value=1)),
960+
KeyValue(
961+
key="b", value=AnyValue(bool_value=False)
962+
),
963+
]
964+
),
965+
scope_metrics=[
966+
pb2.ScopeMetrics(
967+
scope=InstrumentationScope(
968+
name="first_name", version="first_version"
969+
),
970+
metrics=[
971+
pb2.Metric(
972+
name="exponential_histogram",
973+
unit="unit",
974+
description="description",
975+
exponential_histogram=pb2.ExponentialHistogram(
976+
data_points=[
977+
pb2.ExponentialHistogramDataPoint(
978+
attributes=[
979+
KeyValue(
980+
key="a",
981+
value=AnyValue(
982+
int_value=1
983+
),
984+
),
985+
KeyValue(
986+
key="b",
987+
value=AnyValue(
988+
bool_value=True
989+
),
990+
),
991+
],
992+
start_time_unix_nano=0,
993+
time_unix_nano=1,
994+
count=2,
995+
sum=3,
996+
scale=4,
997+
zero_count=5,
998+
positive=pb2.ExponentialHistogramDataPoint.Buckets(
999+
offset=6,
1000+
bucket_counts=[7, 8],
1001+
),
1002+
negative=pb2.ExponentialHistogramDataPoint.Buckets(
1003+
offset=9,
1004+
bucket_counts=[10, 11],
1005+
),
1006+
flags=12,
1007+
exemplars=[],
1008+
min=13.0,
1009+
max=14.0,
1010+
)
1011+
],
1012+
aggregation_temporality=AggregationTemporality.DELTA,
1013+
),
1014+
)
1015+
],
1016+
)
1017+
],
1018+
)
1019+
]
1020+
)
1021+
# pylint: disable=protected-access
1022+
actual = self.exporter._translate_data(
1023+
self.metrics["exponential_histogram"]
1024+
)
1025+
self.assertEqual(expected, actual)
1026+
8991027
def test_translate_multiple_scope_histogram(self):
9001028
expected = ExportMetricsServiceRequest(
9011029
resource_metrics=[

0 commit comments

Comments
 (0)