exporter/datadog: add support for resource labels and service.name (#1074)

* exporter/datadog: add support for resource labels and service.name
This commit is contained in:
Eric Mustin
2020-09-18 17:51:49 +02:00
committed by alrex
parent c4cf919204
commit 746c734a0c
4 changed files with 73 additions and 8 deletions

View File

@ -2,6 +2,8 @@
## Unreleased
- Add support for span resource labels and service name
## Version 0.12b0
Released 2020-08-14

View File

@ -6,3 +6,4 @@ SAMPLE_RATE_METRIC_KEY = "_sample_rate"
SAMPLING_PRIORITY_KEY = "_sampling_priority_v1"
ENV_KEY = "env"
VERSION_KEY = "version"
SERVICE_NAME_TAG = "service.name"

View File

@ -26,7 +26,13 @@ from opentelemetry.sdk.trace.export import SpanExporter, SpanExportResult
from opentelemetry.trace.status import StatusCanonicalCode
# pylint:disable=relative-beyond-top-level
from .constants import DD_ORIGIN, ENV_KEY, SAMPLE_RATE_METRIC_KEY, VERSION_KEY
from .constants import (
DD_ORIGIN,
ENV_KEY,
SAMPLE_RATE_METRIC_KEY,
SERVICE_NAME_TAG,
VERSION_KEY,
)
logger = logging.getLogger(__name__)
@ -107,6 +113,7 @@ class DatadogSpanExporter(SpanExporter):
self.agent_writer.stop()
self.agent_writer.join(self.agent_writer.exit_timeout)
# pylint: disable=too-many-locals
def _translate_to_datadog(self, spans):
datadog_spans = []
@ -119,10 +126,16 @@ class DatadogSpanExporter(SpanExporter):
# duration.
tracer = None
# extract resource attributes to be used as tags as well as potential service name
[
resource_tags,
resource_service_name,
] = _extract_tags_from_resource(span.resource)
datadog_span = DatadogSpan(
tracer,
_get_span_name(span),
service=self.service,
service=resource_service_name or self.service,
resource=_get_resource(span),
span_type=_get_span_type(span),
trace_id=trace_id,
@ -140,7 +153,12 @@ class DatadogSpanExporter(SpanExporter):
datadog_span.set_tag("error.msg", exc_val)
datadog_span.set_tag("error.type", exc_type)
datadog_span.set_tags(span.attributes)
# combine resource attributes and span attributes, don't modify existing span attributes
combined_span_tags = {}
combined_span_tags.update(resource_tags)
combined_span_tags.update(span.attributes)
datadog_span.set_tags(combined_span_tags)
# add configured env tag
if self.env is not None:
@ -282,3 +300,19 @@ def _parse_tags_str(tags_str):
parsed_tags[key] = value
return parsed_tags
def _extract_tags_from_resource(resource):
"""Parse tags from resource.attributes, except service.name which
has special significance within datadog"""
tags = {}
service_name = None
if not (resource and getattr(resource, "attributes", None)):
return [tags, service_name]
for attribute_key, attribute_value in resource.attributes.items():
if attribute_key == SERVICE_NAME_TAG:
service_name = attribute_value
else:
tags[attribute_key] = attribute_value
return [tags, service_name]

View File

@ -23,7 +23,7 @@ from ddtrace.internal.writer import AgentWriter
from opentelemetry import trace as trace_api
from opentelemetry.exporter import datadog
from opentelemetry.sdk import trace
from opentelemetry.sdk.trace import sampling
from opentelemetry.sdk.trace import Resource, sampling
from opentelemetry.sdk.util.instrumentation import InstrumentationInfo
@ -144,6 +144,17 @@ class TestDatadogSpanExporter(unittest.TestCase):
# pylint: disable=invalid-name
self.maxDiff = None
resource = Resource(
attributes={
"key_resource": "some_resource",
"service.name": "resource_service_name",
}
)
resource_without_service = Resource(
attributes={"conflicting_key": "conflicting_value"}
)
span_names = ("test1", "test2", "test3")
trace_id = 0x6E0C63257DE34C926F9EFCD03927272E
trace_id_low = 0x6F9EFCD03927272E
@ -183,18 +194,25 @@ class TestDatadogSpanExporter(unittest.TestCase):
parent=parent_context,
kind=trace_api.SpanKind.CLIENT,
instrumentation_info=instrumentation_info,
resource=Resource({}),
),
trace.Span(
name=span_names[1],
context=parent_context,
parent=None,
instrumentation_info=instrumentation_info,
resource=resource_without_service,
),
trace.Span(
name=span_names[2], context=other_context, parent=None,
name=span_names[2],
context=other_context,
parent=None,
resource=resource,
),
]
otel_spans[1].set_attribute("conflicting_key", "original_value")
otel_spans[0].start(start_time=start_times[0])
otel_spans[0].end(end_time=end_times[0])
@ -234,7 +252,12 @@ class TestDatadogSpanExporter(unittest.TestCase):
duration=durations[1],
error=0,
service="test-service",
meta={"env": "test", "team": "testers", "version": "0.0.1"},
meta={
"env": "test",
"team": "testers",
"version": "0.0.1",
"conflicting_key": "original_value",
},
),
dict(
trace_id=trace_id_low,
@ -245,8 +268,13 @@ class TestDatadogSpanExporter(unittest.TestCase):
start=start_times[2],
duration=durations[2],
error=0,
service="test-service",
meta={"env": "test", "team": "testers", "version": "0.0.1"},
service="resource_service_name",
meta={
"env": "test",
"team": "testers",
"version": "0.0.1",
"key_resource": "some_resource",
},
),
]