Skip to content

Commit e50e3a8

Browse files
author
alrex
authored
Add support for OTLP v0.5.0 (open-telemetry#1143)
1 parent 5eb0598 commit e50e3a8

File tree

18 files changed

+2700
-588
lines changed

18 files changed

+2700
-588
lines changed

exporter/opentelemetry-exporter-otlp/CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
## Unreleased
44

5+
- Update OpenTelemetry protos to v0.5.0
6+
([#1143](https://github.com/open-telemetry/opentelemetry-python/pull/1143))
7+
58
## Version 0.13b0
69

710
Released 2020-09-17

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

Lines changed: 100 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,13 @@
1515
"""OTLP Metrics Exporter"""
1616

1717
import logging
18-
from typing import List, Sequence, Type, TypeVar, Union
18+
from typing import List, Sequence, Type, TypeVar
1919

2020
# pylint: disable=duplicate-code
2121
from opentelemetry.exporter.otlp.exporter import (
2222
OTLPExporterMixin,
2323
_get_resource_data,
2424
)
25-
from opentelemetry.metrics import InstrumentT
2625
from opentelemetry.proto.collector.metrics.v1.metrics_service_pb2 import (
2726
ExportMetricsServiceRequest,
2827
)
@@ -31,17 +30,17 @@
3130
)
3231
from opentelemetry.proto.common.v1.common_pb2 import StringKeyValue
3332
from opentelemetry.proto.metrics.v1.metrics_pb2 import (
33+
AggregationTemporality,
3434
DoubleDataPoint,
35+
DoubleGauge,
36+
DoubleSum,
3537
InstrumentationLibraryMetrics,
36-
Int64DataPoint,
37-
)
38-
from opentelemetry.proto.metrics.v1.metrics_pb2 import (
39-
Metric as CollectorMetric,
40-
)
41-
from opentelemetry.proto.metrics.v1.metrics_pb2 import (
42-
MetricDescriptor,
43-
ResourceMetrics,
38+
IntDataPoint,
39+
IntGauge,
40+
IntSum,
4441
)
42+
from opentelemetry.proto.metrics.v1.metrics_pb2 import Metric as OTLPMetric
43+
from opentelemetry.proto.metrics.v1.metrics_pb2 import ResourceMetrics
4544
from opentelemetry.sdk.metrics import (
4645
Counter,
4746
SumObserver,
@@ -57,7 +56,7 @@
5756
)
5857

5958
logger = logging.getLogger(__name__)
60-
DataPointT = TypeVar("DataPointT", Int64DataPoint, DoubleDataPoint)
59+
DataPointT = TypeVar("DataPointT", IntDataPoint, DoubleDataPoint)
6160

6261

6362
def _get_data_points(
@@ -93,45 +92,6 @@ def _get_data_points(
9392
return data_points
9493

9594

96-
def _get_temporality(
97-
instrument: InstrumentT,
98-
) -> "MetricDescriptor.TemporalityValue":
99-
# pylint: disable=no-member
100-
if isinstance(instrument, (Counter, UpDownCounter)):
101-
temporality = MetricDescriptor.Temporality.DELTA
102-
elif isinstance(instrument, (ValueRecorder, ValueObserver)):
103-
temporality = MetricDescriptor.Temporality.INSTANTANEOUS
104-
elif isinstance(instrument, (SumObserver, UpDownSumObserver)):
105-
temporality = MetricDescriptor.Temporality.CUMULATIVE
106-
else:
107-
raise Exception(
108-
"No temporality defined for instrument type {}".format(
109-
type(instrument)
110-
)
111-
)
112-
113-
return temporality
114-
115-
116-
def _get_type(value_type: Union[int, float]) -> "MetricDescriptor.TypeValue":
117-
# pylint: disable=no-member
118-
if value_type is int: # type: ignore[comparison-overlap]
119-
type_ = MetricDescriptor.Type.INT64
120-
121-
elif value_type is float: # type: ignore[comparison-overlap]
122-
type_ = MetricDescriptor.Type.DOUBLE
123-
124-
# FIXME What are the types that correspond with
125-
# MetricDescriptor.Type.HISTOGRAM and
126-
# MetricDescriptor.Type.SUMMARY?
127-
else:
128-
raise Exception(
129-
"No type defined for valie type {}".format(type(value_type))
130-
)
131-
132-
return type_
133-
134-
13595
class OTLPMetricsExporter(
13696
MetricsExporter,
13797
OTLPExporterMixin[
@@ -150,6 +110,7 @@ class OTLPMetricsExporter(
150110
_stub = MetricsServiceStub
151111
_result = MetricsExportResult
152112

113+
# pylint: disable=no-self-use
153114
def _translate_data(
154115
self, data: Sequence[MetricRecord]
155116
) -> ExportMetricsServiceRequest:
@@ -158,6 +119,22 @@ def _translate_data(
158119

159120
sdk_resource_instrumentation_library_metrics = {}
160121

122+
# The criteria to decide how to translate data is based on this table
123+
# taken directly from OpenTelemetry Proto v0.5.0:
124+
125+
# TODO: Update table after the decision on:
126+
# https://github.com/open-telemetry/opentelemetry-specification/issues/731.
127+
# By default, metrics recording using the OpenTelemetry API are exported as
128+
# (the table does not include MeasurementValueType to avoid extra rows):
129+
#
130+
# Instrument Type
131+
# ----------------------------------------------
132+
# Counter Sum(aggregation_temporality=delta;is_monotonic=true)
133+
# UpDownCounter Sum(aggregation_temporality=delta;is_monotonic=false)
134+
# ValueRecorder TBD
135+
# SumObserver Sum(aggregation_temporality=cumulative;is_monotonic=true)
136+
# UpDownSumObserver Sum(aggregation_temporality=cumulative;is_monotonic=false)
137+
# ValueObserver Gauge()
161138
for sdk_metric in data:
162139

163140
if sdk_metric.instrument.meter.resource not in (
@@ -167,37 +144,90 @@ def _translate_data(
167144
sdk_metric.instrument.meter.resource
168145
] = InstrumentationLibraryMetrics()
169146

170-
self._metric_descriptor_kwargs = {}
147+
type_class = {
148+
int: {
149+
"sum": {"class": IntSum, "argument": "int_sum"},
150+
"gauge": {"class": IntGauge, "argument": "int_gauge"},
151+
"data_point_class": IntDataPoint,
152+
},
153+
float: {
154+
"sum": {"class": DoubleSum, "argument": "double_sum"},
155+
"gauge": {
156+
"class": DoubleGauge,
157+
"argument": "double_gauge",
158+
},
159+
"data_point_class": DoubleDataPoint,
160+
},
161+
}
162+
163+
value_type = sdk_metric.instrument.value_type
164+
165+
sum_class = type_class[value_type]["sum"]["class"]
166+
gauge_class = type_class[value_type]["gauge"]["class"]
167+
data_point_class = type_class[value_type]["data_point_class"]
168+
169+
if isinstance(sdk_metric.instrument, Counter):
170+
otlp_metric_data = sum_class(
171+
data_points=_get_data_points(sdk_metric, data_point_class),
172+
aggregation_temporality=(
173+
AggregationTemporality.AGGREGATION_TEMPORALITY_DELTA
174+
),
175+
is_monotonic=True,
176+
)
177+
argument = type_class[value_type]["sum"]["argument"]
171178

172-
metric_descriptor = MetricDescriptor(
173-
name=sdk_metric.instrument.name,
174-
description=sdk_metric.instrument.description,
175-
unit=sdk_metric.instrument.unit,
176-
type=_get_type(sdk_metric.instrument.value_type),
177-
temporality=_get_temporality(sdk_metric.instrument),
178-
)
179+
elif isinstance(sdk_metric.instrument, UpDownCounter):
180+
otlp_metric_data = sum_class(
181+
data_points=_get_data_points(sdk_metric, data_point_class),
182+
aggregation_temporality=(
183+
AggregationTemporality.AGGREGATION_TEMPORALITY_DELTA
184+
),
185+
is_monotonic=False,
186+
)
187+
argument = type_class[value_type]["sum"]["argument"]
179188

180-
if metric_descriptor.type == MetricDescriptor.Type.INT64:
189+
elif isinstance(sdk_metric.instrument, (ValueRecorder)):
190+
logger.warning("Skipping exporting of ValueRecorder metric")
191+
continue
181192

182-
collector_metric = CollectorMetric(
183-
metric_descriptor=metric_descriptor,
184-
int64_data_points=_get_data_points(
185-
sdk_metric, Int64DataPoint
193+
elif isinstance(sdk_metric.instrument, SumObserver):
194+
otlp_metric_data = sum_class(
195+
data_points=_get_data_points(sdk_metric, data_point_class),
196+
aggregation_temporality=(
197+
AggregationTemporality.AGGREGATION_TEMPORALITY_CUMULATIVE
186198
),
199+
is_monotonic=True,
187200
)
201+
argument = type_class[value_type]["sum"]["argument"]
188202

189-
elif metric_descriptor.type == MetricDescriptor.Type.DOUBLE:
190-
191-
collector_metric = CollectorMetric(
192-
metric_descriptor=metric_descriptor,
193-
double_data_points=_get_data_points(
194-
sdk_metric, DoubleDataPoint
203+
elif isinstance(sdk_metric.instrument, UpDownSumObserver):
204+
otlp_metric_data = sum_class(
205+
data_points=_get_data_points(sdk_metric, data_point_class),
206+
aggregation_temporality=(
207+
AggregationTemporality.AGGREGATION_TEMPORALITY_CUMULATIVE
195208
),
209+
is_monotonic=False,
210+
)
211+
argument = type_class[value_type]["sum"]["argument"]
212+
213+
elif isinstance(sdk_metric.instrument, (ValueObserver)):
214+
otlp_metric_data = gauge_class(
215+
data_points=_get_data_points(sdk_metric, data_point_class)
196216
)
217+
argument = type_class[value_type]["gauge"]["argument"]
197218

198219
sdk_resource_instrumentation_library_metrics[
199220
sdk_metric.instrument.meter.resource
200-
].metrics.append(collector_metric)
221+
].metrics.append(
222+
OTLPMetric(
223+
**{
224+
"name": sdk_metric.instrument.name,
225+
"description": sdk_metric.instrument.description,
226+
"unit": sdk_metric.instrument.unit,
227+
argument: otlp_metric_data,
228+
}
229+
)
230+
)
201231

202232
return ExportMetricsServiceRequest(
203233
resource_metrics=_get_resource_data(

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,8 @@ def _translate_data(
208208
self._translate_status(sdk_span)
209209

210210
self._collector_span_kwargs["kind"] = getattr(
211-
CollectorSpan.SpanKind, sdk_span.kind.name
211+
CollectorSpan.SpanKind,
212+
"SPAN_KIND_{}".format(sdk_span.kind.name),
212213
)
213214

214215
sdk_resource_instrumentation_library_spans[

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

Lines changed: 25 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -25,18 +25,15 @@
2525
StringKeyValue,
2626
)
2727
from opentelemetry.proto.metrics.v1.metrics_pb2 import (
28+
AggregationTemporality,
2829
InstrumentationLibraryMetrics,
29-
Int64DataPoint,
30-
)
31-
from opentelemetry.proto.metrics.v1.metrics_pb2 import (
32-
Metric as CollectorMetric,
33-
)
34-
from opentelemetry.proto.metrics.v1.metrics_pb2 import (
35-
MetricDescriptor,
36-
ResourceMetrics,
30+
IntDataPoint,
31+
IntSum,
3732
)
33+
from opentelemetry.proto.metrics.v1.metrics_pb2 import Metric as OTLPMetric
34+
from opentelemetry.proto.metrics.v1.metrics_pb2 import ResourceMetrics
3835
from opentelemetry.proto.resource.v1.resource_pb2 import (
39-
Resource as CollectorResource,
36+
Resource as OTLPResource,
4037
)
4138
from opentelemetry.sdk.metrics import Counter, MeterProvider
4239
from opentelemetry.sdk.metrics.export import MetricRecord
@@ -71,7 +68,7 @@ def test_translate_metrics(self):
7168
expected = ExportMetricsServiceRequest(
7269
resource_metrics=[
7370
ResourceMetrics(
74-
resource=CollectorResource(
71+
resource=OTLPResource(
7572
attributes=[
7673
KeyValue(key="a", value=AnyValue(int_value=1)),
7774
KeyValue(
@@ -82,26 +79,26 @@ def test_translate_metrics(self):
8279
instrumentation_library_metrics=[
8380
InstrumentationLibraryMetrics(
8481
metrics=[
85-
CollectorMetric(
86-
metric_descriptor=MetricDescriptor(
87-
name="a",
88-
description="b",
89-
unit="c",
90-
type=MetricDescriptor.Type.INT64,
91-
temporality=(
92-
MetricDescriptor.Temporality.DELTA
82+
OTLPMetric(
83+
name="a",
84+
description="b",
85+
unit="c",
86+
int_sum=IntSum(
87+
data_points=[
88+
IntDataPoint(
89+
labels=[
90+
StringKeyValue(
91+
key="a", value="b"
92+
)
93+
],
94+
value=1,
95+
)
96+
],
97+
aggregation_temporality=(
98+
AggregationTemporality.AGGREGATION_TEMPORALITY_DELTA
9399
),
100+
is_monotonic=True,
94101
),
95-
int64_data_points=[
96-
Int64DataPoint(
97-
labels=[
98-
StringKeyValue(
99-
key="a", value="b"
100-
)
101-
],
102-
value=1,
103-
)
104-
],
105102
)
106103
]
107104
)

0 commit comments

Comments
 (0)