Skip to content

Commit b15a23f

Browse files
emmettbutlerYun-Kimclauderithikanarayandubloom
authored
fix: avoid using svc_src: m when service is among active integration defaults (#17712)
This change fixes an issue reported via Support in which `svc_src` is set to `m` in cases where `service` matches the `_default_service` of an active integration config. In such cases, the intended behavior is that it `svc_src` is equal to `service`. The change also excludes the `svc_src` tag in cases where `service == base_service`. --------- Co-authored-by: Yun Kim <yun.kim@datadoghq.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Co-authored-by: Rithika Narayan <rithika.narayan@datadoghq.com> Co-authored-by: Louis Tricot <75956635+dubloom@users.noreply.github.com> Co-authored-by: louis.tricot <louis.tricot@datadoghq.com> Co-authored-by: Thomas Kowalski <thomas.kowalski@datadoghq.com> Co-authored-by: Yun Kim <35776586+Yun-Kim@users.noreply.github.com> Co-authored-by: Gabriele N. Tornetta <P403n1x87@users.noreply.github.com> Co-authored-by: gabriele.tornetta <gabriele.tornetta@datadoghq.com> Co-authored-by: Federico Mon <federico.mon@datadoghq.com> Co-authored-by: Alberto Vara <alberto.vara@datadoghq.com> Co-authored-by: kyle <kyle@verhoog.ca> Co-authored-by: ZStriker19 <32471391+ZStriker19@users.noreply.github.com> Co-authored-by: zach.groves <zach.groves@datadoghq.com> Co-authored-by: Munir Abdinur <munir.abdinur@datadoghq.com> Co-authored-by: Brett Langdon <brett.langdon@datadoghq.com> Co-authored-by: Gyuheon Oh <102937919+gyuheon0h@users.noreply.github.com> Co-authored-by: gyuheon.oh <gyuheon.oh@datadoghq.com> Co-authored-by: r1viollet <74836499+r1viollet@users.noreply.github.com> Co-authored-by: erwan.viollet <erwan.viollet@datadoghq.com>
1 parent e70dde0 commit b15a23f

566 files changed

Lines changed: 6082 additions & 10416 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

ddtrace/_trace/tracer.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -510,9 +510,12 @@ def start_span(
510510
service = parent.service
511511
service_source = parent.get_tag(_SERVICE_SOURCE) or ""
512512
else:
513-
service = service_source = config.service
513+
service = config.service
514514
else:
515-
service_source = "m"
515+
if service in config._integration_default_services:
516+
service_source = service
517+
else:
518+
service_source = "m"
516519

517520
# Update the service name based on any mapping
518521
if service is not None:

ddtrace/contrib/internal/trace_utils.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -400,14 +400,13 @@ def set_service_and_source(
400400
span.set_tag(_SERVICE_SOURCE, "opt.split_by_domain")
401401
# NB "not service" here makes svc_src make sense in cases of service inheritance
402402
elif not service or service == int_config.get(default_service_key):
403-
span.set_tag(
404-
_SERVICE_SOURCE,
405-
getattr(
406-
int_config,
407-
"integration_name",
408-
int_config.get("integration_name", "m") if hasattr(int_config, "get") else "m",
409-
),
403+
service_source = getattr(
404+
int_config,
405+
"integration_name",
406+
int_config.get("integration_name", "") if hasattr(int_config, "get") else "",
410407
)
408+
if service_source:
409+
span.set_tag(_SERVICE_SOURCE, service_source)
411410
if service:
412411
span.service = service
413412

ddtrace/internal/settings/_config.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
log = get_logger(__name__)
4949

5050
ENDPOINT_FETCHED_CONFIG = fetch_config_from_endpoint()
51+
DEFAULT_SERVICE_KEYS = frozenset(["_default_service", "_default_service_worker", "_default_service_producer"])
5152

5253
DD_TRACE_OBFUSCATION_QUERY_STRING_REGEXP_DEFAULT = (
5354
r"(?ix)"
@@ -209,6 +210,14 @@
209210
)
210211

211212

213+
def _integration_default_service_names_from_config(int_config: IntegrationConfig) -> set[str]:
214+
names: set[str] = set()
215+
for attribute in DEFAULT_SERVICE_KEYS:
216+
if value := int_config.get(attribute):
217+
names.add(value)
218+
return names
219+
220+
212221
def _parse_propagation_styles(styles_str: str) -> Optional[list[str]]:
213222
"""Helper to parse http propagation extract/inject styles via env variables.
214223
@@ -447,6 +456,8 @@ def __init__(self) -> None:
447456

448457
# Use a dict as underlying storing mechanism for integration configs
449458
self._integration_configs: dict[str, IntegrationConfig] = {}
459+
# Union of `_default_service*` string values from integrations registered via `_add`.
460+
self._integration_default_services: frozenset[str] = frozenset()
450461

451462
self._debug_mode = _get_config("DD_TRACE_DEBUG", False, asbool, "OTEL_LOG_LEVEL")
452463
self._startup_logs_enabled = _get_config("DD_TRACE_STARTUP_LOGS", False, asbool)
@@ -772,6 +783,12 @@ def _get_extra_services(self) -> set[str]:
772783
self._extra_services.pop()
773784
return self._extra_services
774785

786+
def _recompute_integration_default_services(self) -> None:
787+
names: set[str] = set()
788+
for int_conf in self._integration_configs.values():
789+
names.update(_integration_default_service_names_from_config(int_conf))
790+
self._integration_default_services = frozenset(names)
791+
775792
def _add(self, integration, settings, merge=True):
776793
"""Internal API that registers an integration with given default
777794
settings.
@@ -809,6 +826,8 @@ def _add(self, integration, settings, merge=True):
809826
else:
810827
self._integration_configs[integration] = IntegrationConfig(self, integration, settings)
811828

829+
self._recompute_integration_default_services()
830+
812831
@cachedmethod()
813832
def _header_tag_name(self, header_name: str) -> Optional[str]:
814833
return self._http._header_tag_name(header_name)
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
fixes:
3+
- |
4+
tracing: This change fixes an issue in which `svc_src` is set to `m` in cases where `service` matches the `_default_service` of an active integration config.
5+
In such cases, the intended behavior is that it `svc_src` is equal to `service`. #17712

tests/contrib/azure_cosmos/test_azure_cosmos_snapshot.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
CONNECTION_STRING = "AccountEndpoint=http://localhost:8081/;AccountKey=C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw==;"
1212
ERR_DB_NAME = "db.azure_cosmos_error"
1313
ERR_CONTAINER_NAME = "container.azure_cosmos_error"
14-
SNAPSHOT_IGNORES = ["meta.http.useragent", "meta.error.stack"]
14+
SNAPSHOT_IGNORES = ["meta.http.useragent", "meta.error.stack", "meta._dd.base_service"]
1515

1616
DEFAULT_HEADERS = {"User-Agent": "python-httpx/x.xx.x"}
1717

tests/contrib/azure_functions_cosmos/test_azure_functions_snapshot.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from tests.webclient import Client
1111

1212

13-
SNAPSHOT_IGNORES = ["meta.http.useragent", "meta.http.status_code"]
13+
SNAPSHOT_IGNORES = ["meta.http.useragent", "meta.http.status_code", "meta._dd.base_service"]
1414
DEFAULT_HEADERS = {"User-Agent": "python-httpx/x.xx.x"}
1515

1616
CONNECTION_STRING = "AccountEndpoint=http://localhost:8081/;AccountKey=C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw==;"

tests/contrib/django/test_django.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1636,7 +1636,7 @@ def test_cached_view():
16361636
assert span_header.error == 0
16371637

16381638
expected_meta_view = {
1639-
"_dd.svc_src": "m",
1639+
"_dd.svc_src": "django",
16401640
"component": "django",
16411641
"django.cache.backend": "django.core.cache.backends.locmem.LocMemCache",
16421642
"django.cache.key": (
@@ -1646,7 +1646,7 @@ def test_cached_view():
16461646
}
16471647

16481648
expected_meta_header = {
1649-
"_dd.svc_src": "m",
1649+
"_dd.svc_src": "django",
16501650
"component": "django",
16511651
"django.cache.backend": "django.core.cache.backends.locmem.LocMemCache",
16521652
"django.cache.key": "views.decorators.cache.cache_header..03cdc1cc4aab71b038a6764e5fcabb82.en-us",

tests/contrib/flask/test_blueprint.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,5 +47,5 @@ def test():
4747
self.assertEqual(span.resource, "/")
4848
self.assertNotEqual(span.parent_id, 0)
4949
self.assertEqual(
50-
span.get_tags(), {"component": "flask", "_dd.base_service": "tests.contrib.flask", "_dd.svc_src": "m"}
50+
span.get_tags(), {"component": "flask", "_dd.base_service": "tests.contrib.flask", "_dd.svc_src": "flask"}
5151
)

tests/contrib/flask/test_errorhandler.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from . import BaseFlaskTestCase
77

88

9-
EXPECTED_METADATA = {"component": "flask", "_dd.base_service": "tests.contrib.flask", "_dd.svc_src": "m"}
9+
EXPECTED_METADATA = {"component": "flask", "_dd.base_service": "tests.contrib.flask", "_dd.svc_src": "flask"}
1010

1111

1212
class FlaskErrorhandlerTestCase(BaseFlaskTestCase):

tests/contrib/flask/test_flask_helpers.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@ def test_jsonify(self):
5454
assert set(spans[0].get_tags().keys()) == {
5555
"runtime-id",
5656
"_dd.p.dm",
57-
"_dd.svc_src",
5857
"_dd.p.tid",
5958
"component",
6059
"language",

0 commit comments

Comments
 (0)