diff --git a/CHANGELOG.md b/CHANGELOG.md index abf586680a..1becb99953 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -55,6 +55,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#581](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/581)) - `opentelemetry-instrumentation-botocore` Suppress botocore downstream instrumentation like urllib3 ([#563](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/563)) +- `opentelemetry-exporter-datadog` Datadog exporter should not use `unknown_service` as fallback resource service name. + ([#570](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/570)) ### Added - `opentelemetry-instrumentation-httpx` Add `httpx` instrumentation diff --git a/exporter/opentelemetry-exporter-datadog/src/opentelemetry/exporter/datadog/exporter.py b/exporter/opentelemetry-exporter-datadog/src/opentelemetry/exporter/datadog/exporter.py index d6aa7d478b..f0fcbcf2c8 100644 --- a/exporter/opentelemetry-exporter-datadog/src/opentelemetry/exporter/datadog/exporter.py +++ b/exporter/opentelemetry-exporter-datadog/src/opentelemetry/exporter/datadog/exporter.py @@ -135,12 +135,12 @@ def _translate_to_datadog(self, spans): [ resource_tags, resource_service_name, - ] = _extract_tags_from_resource(span.resource) + ] = _extract_tags_from_resource(span.resource, self.service) datadog_span = DatadogSpan( tracer, _get_span_name(span), - service=resource_service_name or self.service, + service=resource_service_name, resource=_get_resource(span), span_type=_get_span_type(span), trace_id=trace_id, @@ -312,19 +312,23 @@ def _parse_tags_str(tags_str): return parsed_tags -def _extract_tags_from_resource(resource): +def _extract_tags_from_resource(resource, fallback_service_name): """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] + return [tags, fallback_service_name] + service_name = None 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 + + if service_name is None or service_name == "unknown_service": + service_name = fallback_service_name + return [tags, service_name] diff --git a/exporter/opentelemetry-exporter-datadog/tests/test_datadog_exporter.py b/exporter/opentelemetry-exporter-datadog/tests/test_datadog_exporter.py index c366175f8c..c6fe2fc27a 100644 --- a/exporter/opentelemetry-exporter-datadog/tests/test_datadog_exporter.py +++ b/exporter/opentelemetry-exporter-datadog/tests/test_datadog_exporter.py @@ -612,3 +612,41 @@ def test_sampling_rate(self): ] expected = [0.5] self.assertListEqual(actual, expected) + + def test_service_name_fallback(self): + context = trace_api.SpanContext( + trace_id=0x000000000000000000000000DEADBEEF, + span_id=0x34BF92DEEFC58C92, + is_remote=False, + trace_flags=trace_api.TraceFlags(trace_api.TraceFlags.SAMPLED), + ) + trace_api.get_tracer_provider().sampler = sampling.TraceIdRatioBased( + 0.5 + ) + + resource_with_default_name = Resource( + attributes={ + "key_resource": "some_resource", + "service.name": "unknown_service", + } + ) + + span = trace._Span( + name="sampled", + context=context, + parent=None, + resource=resource_with_default_name, + ) + span.start() + span.end() + + # pylint: disable=protected-access + exporter = datadog.DatadogSpanExporter(service="fallback_service_name") + datadog_spans = [ + span.to_dict() for span in exporter._translate_to_datadog([span]) + ] + + self.assertEqual(len(datadog_spans), 1) + + span = datadog_spans[0] + self.assertEqual(span["service"], "fallback_service_name")