Skip to content

Commit 3cdbbd6

Browse files
ericmustinMichael Stella
authored andcommitted
exporter/datadog: add support for resource labels and service.name (open-telemetry#1074)
* exporter/datadog: add support for resource labels and service.name
1 parent 326f45a commit 3cdbbd6

File tree

5 files changed

+80
-10
lines changed

5 files changed

+80
-10
lines changed

docs/examples/datadog_exporter/client.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,19 @@
2121
DatadogExportSpanProcessor,
2222
DatadogSpanExporter,
2323
)
24+
from opentelemetry.sdk import resources
2425
from opentelemetry.sdk.trace import TracerProvider
2526

26-
trace.set_tracer_provider(TracerProvider())
27+
service_name = "example-client"
28+
29+
resource = resources.Resource.create({"service.name": service_name})
30+
31+
trace.set_tracer_provider(TracerProvider(resource=resource))
2732

2833
trace.get_tracer_provider().add_span_processor(
2934
DatadogExportSpanProcessor(
3035
DatadogSpanExporter(
31-
agent_url="http://localhost:8126", service="example-client"
36+
agent_url="http://localhost:8126", service=service_name
3237
)
3338
)
3439
)

exporter/opentelemetry-exporter-datadog/CHANGELOG.md

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

33
## Unreleased
44

5+
- Add support for span resource labels and service name
6+
57
## Version 0.12b0
68

79
Released 2020-08-14

exporter/opentelemetry-exporter-datadog/src/opentelemetry/exporter/datadog/constants.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@
66
SAMPLING_PRIORITY_KEY = "_sampling_priority_v1"
77
ENV_KEY = "env"
88
VERSION_KEY = "version"
9+
SERVICE_NAME_TAG = "service.name"

exporter/opentelemetry-exporter-datadog/src/opentelemetry/exporter/datadog/exporter.py

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,13 @@
2626
from opentelemetry.trace.status import StatusCanonicalCode
2727

2828
# pylint:disable=relative-beyond-top-level
29-
from .constants import DD_ORIGIN, ENV_KEY, SAMPLE_RATE_METRIC_KEY, VERSION_KEY
29+
from .constants import (
30+
DD_ORIGIN,
31+
ENV_KEY,
32+
SAMPLE_RATE_METRIC_KEY,
33+
SERVICE_NAME_TAG,
34+
VERSION_KEY,
35+
)
3036

3137
logger = logging.getLogger(__name__)
3238

@@ -107,6 +113,7 @@ def shutdown(self):
107113
self.agent_writer.stop()
108114
self.agent_writer.join(self.agent_writer.exit_timeout)
109115

116+
# pylint: disable=too-many-locals
110117
def _translate_to_datadog(self, spans):
111118
datadog_spans = []
112119

@@ -119,10 +126,16 @@ def _translate_to_datadog(self, spans):
119126
# duration.
120127
tracer = None
121128

129+
# extract resource attributes to be used as tags as well as potential service name
130+
[
131+
resource_tags,
132+
resource_service_name,
133+
] = _extract_tags_from_resource(span.resource)
134+
122135
datadog_span = DatadogSpan(
123136
tracer,
124137
_get_span_name(span),
125-
service=self.service,
138+
service=resource_service_name or self.service,
126139
resource=_get_resource(span),
127140
span_type=_get_span_type(span),
128141
trace_id=trace_id,
@@ -140,7 +153,12 @@ def _translate_to_datadog(self, spans):
140153
datadog_span.set_tag("error.msg", exc_val)
141154
datadog_span.set_tag("error.type", exc_type)
142155

143-
datadog_span.set_tags(span.attributes)
156+
# combine resource attributes and span attributes, don't modify existing span attributes
157+
combined_span_tags = {}
158+
combined_span_tags.update(resource_tags)
159+
combined_span_tags.update(span.attributes)
160+
161+
datadog_span.set_tags(combined_span_tags)
144162

145163
# add configured env tag
146164
if self.env is not None:
@@ -282,3 +300,19 @@ def _parse_tags_str(tags_str):
282300
parsed_tags[key] = value
283301

284302
return parsed_tags
303+
304+
305+
def _extract_tags_from_resource(resource):
306+
"""Parse tags from resource.attributes, except service.name which
307+
has special significance within datadog"""
308+
tags = {}
309+
service_name = None
310+
if not (resource and getattr(resource, "attributes", None)):
311+
return [tags, service_name]
312+
313+
for attribute_key, attribute_value in resource.attributes.items():
314+
if attribute_key == SERVICE_NAME_TAG:
315+
service_name = attribute_value
316+
else:
317+
tags[attribute_key] = attribute_value
318+
return [tags, service_name]

exporter/opentelemetry-exporter-datadog/tests/test_datadog_exporter.py

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
from opentelemetry import trace as trace_api
2424
from opentelemetry.exporter import datadog
2525
from opentelemetry.sdk import trace
26-
from opentelemetry.sdk.trace import sampling
26+
from opentelemetry.sdk.trace import Resource, sampling
2727
from opentelemetry.sdk.util.instrumentation import InstrumentationInfo
2828

2929

@@ -144,6 +144,17 @@ def test_translate_to_datadog(self):
144144
# pylint: disable=invalid-name
145145
self.maxDiff = None
146146

147+
resource = Resource(
148+
attributes={
149+
"key_resource": "some_resource",
150+
"service.name": "resource_service_name",
151+
}
152+
)
153+
154+
resource_without_service = Resource(
155+
attributes={"conflicting_key": "conflicting_value"}
156+
)
157+
147158
span_names = ("test1", "test2", "test3")
148159
trace_id = 0x6E0C63257DE34C926F9EFCD03927272E
149160
trace_id_low = 0x6F9EFCD03927272E
@@ -183,18 +194,25 @@ def test_translate_to_datadog(self):
183194
parent=parent_context,
184195
kind=trace_api.SpanKind.CLIENT,
185196
instrumentation_info=instrumentation_info,
197+
resource=Resource({}),
186198
),
187199
trace.Span(
188200
name=span_names[1],
189201
context=parent_context,
190202
parent=None,
191203
instrumentation_info=instrumentation_info,
204+
resource=resource_without_service,
192205
),
193206
trace.Span(
194-
name=span_names[2], context=other_context, parent=None,
207+
name=span_names[2],
208+
context=other_context,
209+
parent=None,
210+
resource=resource,
195211
),
196212
]
197213

214+
otel_spans[1].set_attribute("conflicting_key", "original_value")
215+
198216
otel_spans[0].start(start_time=start_times[0])
199217
otel_spans[0].end(end_time=end_times[0])
200218

@@ -234,7 +252,12 @@ def test_translate_to_datadog(self):
234252
duration=durations[1],
235253
error=0,
236254
service="test-service",
237-
meta={"env": "test", "team": "testers", "version": "0.0.1"},
255+
meta={
256+
"env": "test",
257+
"team": "testers",
258+
"version": "0.0.1",
259+
"conflicting_key": "original_value",
260+
},
238261
),
239262
dict(
240263
trace_id=trace_id_low,
@@ -245,8 +268,13 @@ def test_translate_to_datadog(self):
245268
start=start_times[2],
246269
duration=durations[2],
247270
error=0,
248-
service="test-service",
249-
meta={"env": "test", "team": "testers", "version": "0.0.1"},
271+
service="resource_service_name",
272+
meta={
273+
"env": "test",
274+
"team": "testers",
275+
"version": "0.0.1",
276+
"key_resource": "some_resource",
277+
},
250278
),
251279
]
252280

0 commit comments

Comments
 (0)