Skip to content

Commit 0039af8

Browse files
chore(tracing): fix inferred base service for pytest command ran with --ddtrace optional argument [backport 2.17] (#11447)
Backport 7297779 from #11394 to 2.17. # Motiviation Add special case for `--ddtrace` pytest argument, that was causing CI tests to have a different service name than local testing. CI testing adds the `--ddtrace` arg to the command. Previously the code would skip any args that started with `-` as well as the following arg, but that should not be the case for this arg. ## Checklist - [x] PR author has checked that all the criteria below are met - The PR description includes an overview of the change - The PR description articulates the motivation for the change - The change includes tests OR the PR description describes a testing strategy - The PR description notes risks associated with the change, if any - Newly-added code is easy to change - The change follows the [library release note guidelines](https://ddtrace.readthedocs.io/en/stable/releasenotes.html) - The change includes or references documentation updates if necessary - Backport labels are set (if [applicable](https://ddtrace.readthedocs.io/en/latest/contributing.html#backporting)) ## Reviewer Checklist - [x] Reviewer has checked that all the criteria below are met - Title is accurate - All changes are related to the pull request's stated goal - Avoids breaking [API](https://ddtrace.readthedocs.io/en/stable/versioning.html#interfaces) changes - Testing strategy adequately addresses listed risks - Newly-added code is easy to change - Release note makes sense to a user of the library - If necessary, author has acknowledged and discussed the performance implications of this PR as reported in the benchmarks PR comment - Backport labels are set in a manner that is consistent with the [release branch maintenance policy](https://ddtrace.readthedocs.io/en/latest/contributing.html#backporting) Co-authored-by: William Conti <[email protected]>
1 parent 7256443 commit 0039af8

File tree

350 files changed

+1360
-1271
lines changed

Some content is hidden

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

350 files changed

+1360
-1271
lines changed

ddtrace/contrib/internal/mako/patch.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
from ddtrace import config
66
from ddtrace.constants import SPAN_MEASURED_KEY
7+
from ddtrace.contrib.trace_utils import int_service
78
from ddtrace.contrib.trace_utils import unwrap as _u
89
from ddtrace.contrib.trace_utils import wrap as _w
910
from ddtrace.ext import SpanTypes
@@ -26,7 +27,7 @@ def patch():
2627
return
2728
mako.__datadog_patch = True
2829

29-
Pin(service=config.service or schematize_service_name("mako")).onto(Template)
30+
Pin().onto(Template)
3031

3132
_w(mako, "template.Template.render", _wrap_render)
3233
_w(mako, "template.Template.render_unicode", _wrap_render)
@@ -57,7 +58,9 @@ def _wrap_render(wrapped, instance, args, kwargs):
5758
template_name = getattr(instance, "filename", None)
5859
template_name = template_name or DEFAULT_TEMPLATE_NAME
5960

60-
with pin.tracer.trace(func_name(wrapped), pin.service, span_type=SpanTypes.TEMPLATE) as span:
61+
with pin.tracer.trace(
62+
func_name(wrapped), int_service(pin, config.mako, schematize_service_name("mako")), span_type=SpanTypes.TEMPLATE
63+
) as span:
6164
span.set_tag_str(COMPONENT, "mako")
6265

6366
span.set_tag(SPAN_MEASURED_KEY)

ddtrace/sampler.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,10 +134,17 @@ def __init__(self, sample_rate=1.0):
134134
def set_sample_rate(
135135
self,
136136
sample_rate, # type: float
137-
service="", # type: str
138-
env="", # type: str
137+
service=None, # type: Optional[str]
138+
env=None, # type: Optional[str]
139139
):
140140
# type: (...) -> None
141+
142+
# if we have a blank service, we need to match it to the config.service
143+
if service is None:
144+
service = config.service
145+
if env is None:
146+
env = config.env
147+
141148
self._by_service_samplers[self._key(service, env)] = _AgentRateSampler(sample_rate)
142149

143150
def sample(self, span):

ddtrace/settings/_inferred_base_service.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,9 @@ def detect(self, args: List[str]) -> Optional[ServiceMetadata]:
5454
module_flag = False
5555

5656
for arg in args:
57-
has_flag_prefix = arg.startswith("-")
57+
# we support the --ddtrace option for pytest, and shouldn't skip the following arg
58+
# since it's usually the test location argument.
59+
has_flag_prefix = arg.startswith("-") and not arg.startswith("--ddtrace")
5860
is_env_variable = "=" in arg
5961

6062
should_skip_arg = prev_arg_is_flag or has_flag_prefix or is_env_variable

ddtrace/settings/config.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -474,15 +474,16 @@ def __init__(self):
474474
self._propagation_http_baggage_enabled = _get_config("DD_TRACE_PROPAGATION_HTTP_BAGGAGE_ENABLED", False, asbool)
475475

476476
self.env = _get_config("DD_ENV", self.tags.get("env"))
477-
self.service = _get_config("DD_SERVICE", self.tags.get("service", DEFAULT_SPAN_SERVICE_NAME))
477+
self.service = _get_config("DD_SERVICE", self.tags.get("service", None))
478+
478479
self._inferred_base_service = detect_service(sys.argv)
479480

480481
if self.service is None and in_gcp_function():
481482
self.service = _get_config(["K_SERVICE", "FUNCTION_NAME"], DEFAULT_SPAN_SERVICE_NAME)
482483
if self.service is None and in_azure_function():
483484
self.service = _get_config("WEBSITE_SITE_NAME", DEFAULT_SPAN_SERVICE_NAME)
484-
if self.service is None and self._inferred_base_service:
485-
self.service = self._inferred_base_service
485+
if self.service is None and DEFAULT_SPAN_SERVICE_NAME:
486+
self.service = _get_config("DD_SERVICE", DEFAULT_SPAN_SERVICE_NAME)
486487

487488
self._extra_services = set()
488489
self._extra_services_queue = None if in_aws_lambda() or not self._remote_config_enabled else File_Queue()
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
fixes:
3+
- |
4+
ci_visibility: Updates the inferred base service name algorithm to ensure that arguments following ``--ddtrace`` are no
5+
longer skipped when executing tests with pytest. Previously, the algorithm misinterpreted these arguments
6+
as standard flags, overlooking possible test paths that may contribute to the inferred service name.

tests/contrib/anthropic/test_anthropic_llmobs.py

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ def test_completion(self, anthropic, ddtrace_global_config, mock_llmobs_writer,
6868
output_messages=[{"content": 'THE BEST-SELLING BOOK OF ALL TIME IS "DON', "role": "assistant"}],
6969
metadata={"temperature": 0.8, "max_tokens": 15.0},
7070
token_metrics={"input_tokens": 32, "output_tokens": 15, "total_tokens": 47},
71-
tags={"ml_app": "<ml-app-name>"},
71+
tags={"ml_app": "<ml-app-name>", "service": "tests.contrib.anthropic"},
7272
)
7373
)
7474

@@ -113,7 +113,7 @@ def test_error(self, anthropic, ddtrace_global_config, mock_llmobs_writer, mock_
113113
error_message=span.get_tag("error.message"),
114114
error_stack=span.get_tag("error.stack"),
115115
metadata={"temperature": 0.8, "max_tokens": 15.0},
116-
tags={"ml_app": "<ml-app-name>"},
116+
tags={"ml_app": "<ml-app-name>", "service": "tests.contrib.anthropic"},
117117
)
118118
)
119119

@@ -142,7 +142,7 @@ def test_error_unserializable_arg(
142142
error_message=span.get_tag("error.message"),
143143
error_stack=span.get_tag("error.stack"),
144144
metadata={"temperature": 0.8, "max_tokens": mock.ANY},
145-
tags={"ml_app": "<ml-app-name>"},
145+
tags={"ml_app": "<ml-app-name>", "service": "tests.contrib.anthropic"},
146146
)
147147
mock_llmobs_writer.enqueue.assert_called_with(expected_span)
148148
actual_span = mock_llmobs_writer.enqueue.call_args[0][0]
@@ -196,7 +196,7 @@ def test_stream(self, anthropic, ddtrace_global_config, mock_llmobs_writer, mock
196196
],
197197
metadata={"temperature": 0.8, "max_tokens": 15.0},
198198
token_metrics={"input_tokens": 27, "output_tokens": 15, "total_tokens": 42},
199-
tags={"ml_app": "<ml-app-name>"},
199+
tags={"ml_app": "<ml-app-name>", "service": "tests.contrib.anthropic"},
200200
)
201201
)
202202

@@ -253,7 +253,7 @@ def test_stream_helper(self, anthropic, ddtrace_global_config, mock_llmobs_write
253253
],
254254
metadata={"temperature": 0.8, "max_tokens": 15.0},
255255
token_metrics={"input_tokens": 27, "output_tokens": 15, "total_tokens": 42},
256-
tags={"ml_app": "<ml-app-name>"},
256+
tags={"ml_app": "<ml-app-name>", "service": "tests.contrib.anthropic"},
257257
)
258258
)
259259

@@ -308,7 +308,7 @@ def test_image(self, anthropic, ddtrace_global_config, mock_llmobs_writer, mock_
308308
],
309309
metadata={"temperature": 0.8, "max_tokens": 15.0},
310310
token_metrics={"input_tokens": 246, "output_tokens": 15, "total_tokens": 261},
311-
tags={"ml_app": "<ml-app-name>"},
311+
tags={"ml_app": "<ml-app-name>", "service": "tests.contrib.anthropic"},
312312
)
313313
)
314314

@@ -350,7 +350,7 @@ def test_tools_sync(self, anthropic, ddtrace_global_config, mock_llmobs_writer,
350350
],
351351
metadata={"max_tokens": 200.0},
352352
token_metrics={"input_tokens": 599, "output_tokens": 152, "total_tokens": 751},
353-
tags={"ml_app": "<ml-app-name>"},
353+
tags={"ml_app": "<ml-app-name>", "service": "tests.contrib.anthropic"},
354354
)
355355
)
356356

@@ -403,7 +403,7 @@ def test_tools_sync(self, anthropic, ddtrace_global_config, mock_llmobs_writer,
403403
],
404404
metadata={"max_tokens": 500.0},
405405
token_metrics={"input_tokens": 768, "output_tokens": 29, "total_tokens": 797},
406-
tags={"ml_app": "<ml-app-name>"},
406+
tags={"ml_app": "<ml-app-name>", "service": "tests.contrib.anthropic"},
407407
)
408408
)
409409

@@ -446,7 +446,7 @@ async def test_tools_async(self, anthropic, ddtrace_global_config, mock_llmobs_w
446446
],
447447
metadata={"max_tokens": 200.0},
448448
token_metrics={"input_tokens": 599, "output_tokens": 152, "total_tokens": 751},
449-
tags={"ml_app": "<ml-app-name>"},
449+
tags={"ml_app": "<ml-app-name>", "service": "tests.contrib.anthropic"},
450450
)
451451
)
452452

@@ -499,7 +499,7 @@ async def test_tools_async(self, anthropic, ddtrace_global_config, mock_llmobs_w
499499
],
500500
metadata={"max_tokens": 500.0},
501501
token_metrics={"input_tokens": 768, "output_tokens": 29, "total_tokens": 797},
502-
tags={"ml_app": "<ml-app-name>"},
502+
tags={"ml_app": "<ml-app-name>", "service": "tests.contrib.anthropic"},
503503
)
504504
)
505505

@@ -559,7 +559,7 @@ def test_tools_sync_stream(self, anthropic, ddtrace_global_config, mock_llmobs_w
559559
],
560560
metadata={"max_tokens": 200.0},
561561
token_metrics={"input_tokens": 599, "output_tokens": 135, "total_tokens": 734},
562-
tags={"ml_app": "<ml-app-name>"},
562+
tags={"ml_app": "<ml-app-name>", "service": "tests.contrib.anthropic"},
563563
)
564564
)
565565

@@ -609,7 +609,7 @@ def test_tools_sync_stream(self, anthropic, ddtrace_global_config, mock_llmobs_w
609609
],
610610
metadata={"max_tokens": 500.0},
611611
token_metrics={"input_tokens": 762, "output_tokens": 33, "total_tokens": 795},
612-
tags={"ml_app": "<ml-app-name>"},
612+
tags={"ml_app": "<ml-app-name>", "service": "tests.contrib.anthropic"},
613613
)
614614
)
615615

@@ -664,7 +664,7 @@ async def test_tools_async_stream_helper(
664664
],
665665
metadata={"max_tokens": 200.0},
666666
token_metrics={"input_tokens": 599, "output_tokens": 146, "total_tokens": 745},
667-
tags={"ml_app": "<ml-app-name>"},
667+
tags={"ml_app": "<ml-app-name>", "service": "tests.contrib.anthropic"},
668668
)
669669
)
670670

@@ -719,6 +719,6 @@ async def test_tools_async_stream_helper(
719719
],
720720
metadata={"max_tokens": 500.0},
721721
token_metrics={"input_tokens": 762, "output_tokens": 18, "total_tokens": 780},
722-
tags={"ml_app": "<ml-app-name>"},
722+
tags={"ml_app": "<ml-app-name>", "service": "tests.contrib.anthropic"},
723723
)
724724
)

tests/contrib/django/test_django.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1425,14 +1425,14 @@ def test_cached_view(client, test_spans):
14251425
"django.cache.key": (
14261426
"views.decorators.cache.cache_page..GET.03cdc1cc4aab71b038a6764e5fcabb82.d41d8cd98f00b204e9800998ecf8..."
14271427
),
1428-
"_dd.base_service": "",
1428+
"_dd.base_service": "tests.contrib.django",
14291429
}
14301430

14311431
expected_meta_header = {
14321432
"component": "django",
14331433
"django.cache.backend": "django.core.cache.backends.locmem.LocMemCache",
14341434
"django.cache.key": "views.decorators.cache.cache_header..03cdc1cc4aab71b038a6764e5fcabb82.en-us",
1435-
"_dd.base_service": "",
1435+
"_dd.base_service": "tests.contrib.django",
14361436
}
14371437

14381438
assert span_view.get_tags() == expected_meta_view

tests/contrib/flask/test_blueprint.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ def test():
104104
self.assertEqual(span.name, "bp.test")
105105
self.assertEqual(span.resource, "/")
106106
self.assertNotEqual(span.parent_id, 0)
107-
self.assertEqual(span.get_tags(), {"component": "flask", "_dd.base_service": ""})
107+
self.assertEqual(span.get_tags(), {"component": "flask", "_dd.base_service": "tests.contrib.flask"})
108108

109109
def test_blueprint_request_pin_override(self):
110110
"""
@@ -132,7 +132,7 @@ def test():
132132
self.assertEqual(span.name, "bp.test")
133133
self.assertEqual(span.resource, "/")
134134
self.assertNotEqual(span.parent_id, 0)
135-
self.assertEqual(span.get_tags(), {"component": "flask", "_dd.base_service": ""})
135+
self.assertEqual(span.get_tags(), {"component": "flask", "_dd.base_service": "tests.contrib.flask"})
136136

137137
def test_blueprint_request_pin_disabled(self):
138138
"""

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": ""}
9+
EXPECTED_METADATA = {"component": "flask", "_dd.base_service": "tests.contrib.flask"}
1010

1111

1212
class FlaskErrorhandlerTestCase(BaseFlaskTestCase):

tests/contrib/flask/test_flask_helpers.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ def test_jsonify(self):
4949
spans = self.get_spans()
5050
self.assertEqual(len(spans), 3)
5151

52-
self.assertIsNone(spans[0].service)
52+
self.assertEqual(spans[0].service, "tests.contrib.flask")
5353
self.assertEqual(spans[0].name, "flask.jsonify")
5454
self.assertEqual(spans[0].resource, "flask.jsonify")
5555
assert set(spans[0].get_tags().keys()) == {"runtime-id", "_dd.p.dm", "_dd.p.tid", "component", "language"}

0 commit comments

Comments
 (0)