Skip to content

Commit 45c94e7

Browse files
authored
Update datadog exporter error tagging (#459)
1 parent b1d6c90 commit 45c94e7

File tree

4 files changed

+38
-6
lines changed

4 files changed

+38
-6
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
4040
([#415](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/415))
4141
- `opentelemetry-instrumentation-tornado` Add request/response hooks.
4242
([#426](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/426))
43+
- `opentelemetry-exporter-datadog` Add parsing exception events for error tags.
44+
([#459](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/459))
4345
- `opentelemetry-instrumenation-django` now supports trace response headers.
4446
([#436](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/436))
4547
- `opentelemetry-instrumenation-tornado` now supports trace response headers.

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

+7
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,10 @@
77
ENV_KEY = "env"
88
VERSION_KEY = "version"
99
SERVICE_NAME_TAG = "service.name"
10+
EVENT_NAME_EXCEPTION = "exception"
11+
EXCEPTION_TYPE_ATTR_KEY = "exception.type"
12+
EXCEPTION_MSG_ATTR_KEY = "exception.message"
13+
EXCEPTION_STACK_ATTR_KEY = "exception.stacktrace"
14+
DD_ERROR_TYPE_TAG_KEY = "error.type"
15+
DD_ERROR_MSG_TAG_KEY = "error.msg"
16+
DD_ERROR_STACK_TAG_KEY = "error.stack"

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

+28-6
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,15 @@
2222

2323
import opentelemetry.trace as trace_api
2424
from opentelemetry.exporter.datadog.constants import (
25+
DD_ERROR_MSG_TAG_KEY,
26+
DD_ERROR_STACK_TAG_KEY,
27+
DD_ERROR_TYPE_TAG_KEY,
2528
DD_ORIGIN,
2629
ENV_KEY,
30+
EVENT_NAME_EXCEPTION,
31+
EXCEPTION_MSG_ATTR_KEY,
32+
EXCEPTION_STACK_ATTR_KEY,
33+
EXCEPTION_TYPE_ATTR_KEY,
2734
SAMPLE_RATE_METRIC_KEY,
2835
SERVICE_NAME_TAG,
2936
VERSION_KEY,
@@ -145,11 +152,12 @@ def _translate_to_datadog(self, spans):
145152

146153
if not span.status.is_ok:
147154
datadog_span.error = 1
148-
if span.status.description:
149-
exc_type, exc_val = _get_exc_info(span)
150-
# no mapping for error.stack since traceback not recorded
151-
datadog_span.set_tag("error.msg", exc_val)
152-
datadog_span.set_tag("error.type", exc_type)
155+
# loop over events and look for exception events, extract info.
156+
# https://github.com/open-telemetry/opentelemetry-python/blob/71e3a7a192c0fc8a7503fac967ada36a74b79e58/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py#L810-L819
157+
if span.events:
158+
_extract_tags_from_exception_events(
159+
span.events, datadog_span
160+
)
153161

154162
# combine resource attributes and span attributes, don't modify existing span attributes
155163
combined_span_tags = {}
@@ -178,7 +186,7 @@ def _translate_to_datadog(self, spans):
178186
if sampling_rate is not None:
179187
datadog_span.set_metric(SAMPLE_RATE_METRIC_KEY, sampling_rate)
180188

181-
# span events and span links are not supported
189+
# span events and span links are not supported except for extracting exception event context
182190

183191
datadog_spans.append(datadog_span)
184192

@@ -318,3 +326,17 @@ def _extract_tags_from_resource(resource):
318326
else:
319327
tags[attribute_key] = attribute_value
320328
return [tags, service_name]
329+
330+
331+
def _extract_tags_from_exception_events(events, datadog_span):
332+
"""Parse error tags from exception events, error.msg error.type
333+
and error.stack have special significance within datadog"""
334+
for event in events:
335+
if event.name is not None and event.name == EVENT_NAME_EXCEPTION:
336+
for key, value in event.attributes.items():
337+
if key == EXCEPTION_TYPE_ATTR_KEY:
338+
datadog_span.set_tag(DD_ERROR_TYPE_TAG_KEY, value)
339+
elif key == EXCEPTION_MSG_ATTR_KEY:
340+
datadog_span.set_tag(DD_ERROR_MSG_TAG_KEY, value)
341+
elif key == EXCEPTION_STACK_ATTR_KEY:
342+
datadog_span.set_tag(DD_ERROR_STACK_TAG_KEY, value)

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

+1
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,7 @@ def test_errors(self):
388388
self.assertEqual(span["error"], 1)
389389
self.assertEqual(span["meta"]["error.msg"], "bar")
390390
self.assertEqual(span["meta"]["error.type"], "ValueError")
391+
self.assertTrue(span["meta"]["error.stack"] is not None)
391392

392393
def test_shutdown(self):
393394
span_names = ["xxx", "bar", "foo"]

0 commit comments

Comments
 (0)