Skip to content

Commit bcf7a2f

Browse files
authored
Change temporality for Counter and UpDownCounter to CUMULATIVE (#1384)
Fixes #1383
1 parent a085c10 commit bcf7a2f

File tree

4 files changed

+61
-29
lines changed

4 files changed

+61
-29
lines changed

exporter/opentelemetry-exporter-otlp/CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
## Unreleased
44

5+
- Change temporality for Counter and UpDownCounter
6+
([#1384](https://github.com/open-telemetry/opentelemetry-python/pull/1384))
57
- Add Gzip compression for exporter
68
([#1141](https://github.com/open-telemetry/opentelemetry-python/pull/1141))
79
- OTLP exporter: Handle error case when no credentials supplied

exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/metrics_exporter/__init__.py

+53-23
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,7 @@
1515
"""OTLP Metrics Exporter"""
1616

1717
import logging
18-
import os
19-
from typing import List, Optional, Sequence, Type, TypeVar, Union
18+
from typing import List, Optional, Sequence, Type, TypeVar
2019

2120
from grpc import ChannelCredentials
2221

@@ -71,7 +70,9 @@
7170

7271

7372
def _get_data_points(
74-
export_record: ExportRecord, data_point_class: Type[DataPointT]
73+
export_record: ExportRecord,
74+
data_point_class: Type[DataPointT],
75+
aggregation_temporality: int,
7576
) -> List[DataPointT]:
7677

7778
if isinstance(export_record.aggregator, SumAggregator):
@@ -91,16 +92,23 @@ def _get_data_points(
9192
elif isinstance(export_record.aggregator, ValueObserverAggregator):
9293
value = export_record.aggregator.checkpoint.last
9394

95+
if aggregation_temporality == (
96+
AggregationTemporality.AGGREGATION_TEMPORALITY_CUMULATIVE
97+
):
98+
start_time_unix_nano = export_record.aggregator.first_timestamp
99+
else:
100+
start_time_unix_nano = (
101+
export_record.aggregator.initial_checkpoint_timestamp
102+
)
103+
94104
return [
95105
data_point_class(
96106
labels=[
97107
StringKeyValue(key=str(label_key), value=str(label_value))
98108
for label_key, label_value in export_record.labels
99109
],
100110
value=value,
101-
start_time_unix_nano=(
102-
export_record.aggregator.initial_checkpoint_timestamp
103-
),
111+
start_time_unix_nano=start_time_unix_nano,
104112
time_unix_nano=(export_record.aggregator.last_update_timestamp),
105113
)
106114
]
@@ -215,25 +223,35 @@ def _translate_data(
215223
data_point_class = type_class[value_type]["data_point_class"]
216224

217225
if isinstance(export_record.instrument, Counter):
226+
227+
aggregation_temporality = (
228+
AggregationTemporality.AGGREGATION_TEMPORALITY_CUMULATIVE
229+
)
230+
218231
otlp_metric_data = sum_class(
219232
data_points=_get_data_points(
220-
export_record, data_point_class
221-
),
222-
aggregation_temporality=(
223-
AggregationTemporality.AGGREGATION_TEMPORALITY_DELTA
233+
export_record,
234+
data_point_class,
235+
aggregation_temporality,
224236
),
237+
aggregation_temporality=aggregation_temporality,
225238
is_monotonic=True,
226239
)
227240
argument = type_class[value_type]["sum"]["argument"]
228241

229242
elif isinstance(export_record.instrument, UpDownCounter):
243+
244+
aggregation_temporality = (
245+
AggregationTemporality.AGGREGATION_TEMPORALITY_CUMULATIVE
246+
)
247+
230248
otlp_metric_data = sum_class(
231249
data_points=_get_data_points(
232-
export_record, data_point_class
233-
),
234-
aggregation_temporality=(
235-
AggregationTemporality.AGGREGATION_TEMPORALITY_DELTA
250+
export_record,
251+
data_point_class,
252+
aggregation_temporality,
236253
),
254+
aggregation_temporality=aggregation_temporality,
237255
is_monotonic=False,
238256
)
239257
argument = type_class[value_type]["sum"]["argument"]
@@ -243,33 +261,45 @@ def _translate_data(
243261
continue
244262

245263
elif isinstance(export_record.instrument, SumObserver):
264+
265+
aggregation_temporality = (
266+
AggregationTemporality.AGGREGATION_TEMPORALITY_CUMULATIVE
267+
)
268+
246269
otlp_metric_data = sum_class(
247270
data_points=_get_data_points(
248-
export_record, data_point_class
249-
),
250-
aggregation_temporality=(
251-
AggregationTemporality.AGGREGATION_TEMPORALITY_CUMULATIVE
271+
export_record,
272+
data_point_class,
273+
aggregation_temporality,
252274
),
275+
aggregation_temporality=aggregation_temporality,
253276
is_monotonic=True,
254277
)
255278
argument = type_class[value_type]["sum"]["argument"]
256279

257280
elif isinstance(export_record.instrument, UpDownSumObserver):
281+
282+
aggregation_temporality = (
283+
AggregationTemporality.AGGREGATION_TEMPORALITY_CUMULATIVE
284+
)
285+
258286
otlp_metric_data = sum_class(
259287
data_points=_get_data_points(
260-
export_record, data_point_class
261-
),
262-
aggregation_temporality=(
263-
AggregationTemporality.AGGREGATION_TEMPORALITY_CUMULATIVE
288+
export_record,
289+
data_point_class,
290+
aggregation_temporality,
264291
),
292+
aggregation_temporality=aggregation_temporality,
265293
is_monotonic=False,
266294
)
267295
argument = type_class[value_type]["sum"]["argument"]
268296

269297
elif isinstance(export_record.instrument, (ValueObserver)):
270298
otlp_metric_data = gauge_class(
271299
data_points=_get_data_points(
272-
export_record, data_point_class
300+
export_record,
301+
data_point_class,
302+
AggregationTemporality.AGGREGATION_TEMPORALITY_DELTA,
273303
)
274304
)
275305
argument = type_class[value_type]["gauge"]["argument"]

exporter/opentelemetry-exporter-otlp/tests/test_otlp_metric_exporter.py

+5-6
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,9 @@
4646

4747

4848
class TestOTLPMetricExporter(TestCase):
49-
def setUp(self):
49+
@patch("opentelemetry.sdk.metrics.export.aggregate.time_ns")
50+
def setUp(self, mock_time_ns): # pylint: disable=arguments-differ
51+
mock_time_ns.configure_mock(**{"return_value": 1})
5052
self.exporter = OTLPMetricsExporter(insecure=True)
5153
resource = SDKResource(OrderedDict([("a", 1), ("b", False)]))
5254

@@ -95,12 +97,9 @@ def test_no_credentials_error(self):
9597
with self.assertRaises(ValueError):
9698
OTLPMetricsExporter()
9799

98-
@patch("opentelemetry.sdk.metrics.export.aggregate.time_ns")
99-
def test_translate_metrics(self, mock_time_ns):
100+
def test_translate_metrics(self):
100101
# pylint: disable=no-member
101102

102-
mock_time_ns.configure_mock(**{"return_value": 1})
103-
104103
self.counter_export_record.aggregator.checkpoint = 1
105104
self.counter_export_record.aggregator.initial_checkpoint_timestamp = 1
106105
self.counter_export_record.aggregator.last_update_timestamp = 1
@@ -137,7 +136,7 @@ def test_translate_metrics(self, mock_time_ns):
137136
)
138137
],
139138
aggregation_temporality=(
140-
AggregationTemporality.AGGREGATION_TEMPORALITY_DELTA
139+
AggregationTemporality.AGGREGATION_TEMPORALITY_CUMULATIVE
141140
),
142141
is_monotonic=True,
143142
),

opentelemetry-sdk/src/opentelemetry/sdk/metrics/export/aggregate.py

+1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ def __init__(self, config=None):
3434
self._lock = threading.Lock()
3535
self.last_update_timestamp = 0
3636
self.initial_checkpoint_timestamp = 0
37+
self.first_timestamp = time_ns()
3738
self.checkpointed = True
3839
if config is not None:
3940
self.config = config

0 commit comments

Comments
 (0)