Skip to content

Commit 710ed97

Browse files
authored
chore(profiling): ddup.upload() optionally gets tracer object (#11695)
profiling tests that check for span ids are flaky. I wonder whether sharing tracer instance across tests causes that problem. ## 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)
1 parent 30a8c6d commit 710ed97

File tree

7 files changed

+32
-28
lines changed

7 files changed

+32
-28
lines changed

ddtrace/internal/datadog/profiling/ddup/_ddup.pyi

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ from typing import Optional
33
from typing import Union
44
from .._types import StringType
55
from ddtrace._trace.span import Span
6+
from ddtrace._trace.tracer import Tracer
67

78
def config(
89
env: StringType,
@@ -16,7 +17,7 @@ def config(
1617
enable_code_provenance: Optional[bool],
1718
) -> None: ...
1819
def start() -> None: ...
19-
def upload() -> None: ...
20+
def upload(tracer: Optional[Tracer]) -> None: ...
2021

2122
class SampleHandle:
2223
def push_cputime(self, value: int, count: int) -> None: ...

ddtrace/internal/datadog/profiling/ddup/_ddup.pyx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ from ddtrace.internal.constants import DEFAULT_SERVICE_NAME
2020
from ddtrace.internal.packages import get_distributions
2121
from ddtrace.internal.runtime import get_runtime_id
2222
from ddtrace._trace.span import Span
23+
from ddtrace._trace.tracer import Tracer
2324

2425

2526
ctypedef void (*func_ptr_t)(string_view)
@@ -396,16 +397,16 @@ def _get_endpoint(tracer)-> str:
396397
return endpoint
397398

398399

399-
def upload() -> None:
400+
def upload(tracer: Optional[Tracer] = ddtrace.tracer) -> None:
400401
call_func_with_str(ddup_set_runtime_id, get_runtime_id())
401402

402-
processor = ddtrace.tracer._endpoint_call_counter_span_processor
403+
processor = tracer._endpoint_call_counter_span_processor
403404
endpoint_counts, endpoint_to_span_ids = processor.reset()
404405

405406
call_ddup_profile_set_endpoints(endpoint_to_span_ids)
406407
call_ddup_profile_add_endpoint_counts(endpoint_counts)
407408

408-
endpoint = _get_endpoint(ddtrace.tracer)
409+
endpoint = _get_endpoint(tracer)
409410
call_func_with_str(ddup_config_url, endpoint)
410411

411412
with nogil:

ddtrace/profiling/profiler.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,7 @@ def start_collector(collector_class: Type) -> None:
311311
recorder=r,
312312
exporters=exporters,
313313
before_flush=self._collectors_snapshot,
314+
tracer=self.tracer,
314315
)
315316

316317
def _collectors_snapshot(self):

ddtrace/profiling/scheduler.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
from typing import Optional
88
from typing import Sequence # noqa F401
99

10+
import ddtrace
11+
from ddtrace._trace.tracer import Tracer
1012
from ddtrace.internal import compat
1113
from ddtrace.internal import periodic
1214
from ddtrace.internal.datadog.profiling import ddup
@@ -30,6 +32,7 @@ def __init__(
3032
recorder: Optional[Recorder] = None,
3133
exporters: Optional[List[Exporter]] = None,
3234
before_flush: Optional[Callable] = None,
35+
tracer: Optional[Tracer] = ddtrace.tracer,
3336
interval: float = config.upload_interval,
3437
):
3538
super(Scheduler, self).__init__(interval=interval)
@@ -38,6 +41,7 @@ def __init__(
3841
self.before_flush: Optional[Callable] = before_flush
3942
self._configured_interval: float = self.interval
4043
self._last_export: int = 0 # Overridden in _start_service
44+
self._tracer = tracer
4145
self._export_libdd_enabled: bool = config.export.libdd_enabled
4246

4347
def _start_service(self):
@@ -59,7 +63,7 @@ def flush(self):
5963
LOG.error("Scheduler before_flush hook failed", exc_info=True)
6064

6165
if self._export_libdd_enabled:
62-
ddup.upload()
66+
ddup.upload(self._tracer)
6367

6468
# These are only used by the Python uploader, but set them here to keep logs/etc
6569
# consistent for now

tests/profiling_v2/collector/test_asyncio.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
import pytest
88

99
from ddtrace import ext
10-
from ddtrace import tracer
1110
from ddtrace.internal.datadog.profiling import ddup
1211
from ddtrace.profiling.collector import asyncio as collector_asyncio
1312
from tests.profiling.collector import pprof_utils
@@ -85,7 +84,7 @@ async def test_asyncio_lock_events(self):
8584
],
8685
)
8786

88-
async def test_asyncio_lock_events_tracer(self):
87+
async def test_asyncio_lock_events_tracer(self, tracer):
8988
tracer._endpoint_call_counter_span_processor.enable()
9089
resource = str(uuid.uuid4())
9190
span_type = ext.SpanTypes.WEB
@@ -103,7 +102,7 @@ async def test_asyncio_lock_events_tracer(self):
103102
lock_ctx = asyncio.Lock() # !CREATE! test_asyncio_lock_events_tracer_3
104103
async with lock_ctx: # !ACQUIRE! !RELEASE! test_asyncio_lock_events_tracer_3
105104
pass
106-
ddup.upload()
105+
ddup.upload(tracer=tracer)
107106

108107
linenos_1 = get_lock_linenos("test_asyncio_lock_events_tracer_1")
109108
linenos_2 = get_lock_linenos("test_asyncio_lock_events_tracer_2")

tests/profiling_v2/collector/test_stack.py

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
import pytest
1010

1111
from ddtrace import ext
12-
from ddtrace import tracer
1312
from ddtrace.internal.datadog.profiling import ddup
1413
from ddtrace.profiling.collector import stack
1514
from ddtrace.settings.profiling import config
@@ -82,7 +81,7 @@ def foo():
8281

8382

8483
@pytest.mark.parametrize("stack_v2_enabled", [True, False])
85-
def test_push_span(stack_v2_enabled, tmp_path):
84+
def test_push_span(stack_v2_enabled, tmp_path, tracer):
8685
if sys.version_info[:2] == (3, 7) and stack_v2_enabled:
8786
pytest.skip("stack_v2 is not supported on Python 3.7")
8887

@@ -111,7 +110,7 @@ def test_push_span(stack_v2_enabled, tmp_path):
111110
local_root_span_id = span._local_root.span_id
112111
for _ in range(10):
113112
time.sleep(0.1)
114-
ddup.upload()
113+
ddup.upload(tracer=tracer)
115114

116115
profile = pprof_utils.parse_profile(output_filename)
117116
samples = pprof_utils.get_samples_with_label_key(profile, "span id")
@@ -129,7 +128,7 @@ def test_push_span(stack_v2_enabled, tmp_path):
129128
)
130129

131130

132-
def test_push_span_unregister_thread(tmp_path, monkeypatch):
131+
def test_push_span_unregister_thread(tmp_path, monkeypatch, tracer):
133132
if sys.version_info[:2] == (3, 7):
134133
pytest.skip("stack_v2 is not supported on Python 3.7")
135134

@@ -166,7 +165,7 @@ def target_fun():
166165
t.start()
167166
t.join()
168167
thread_id = t.ident
169-
ddup.upload()
168+
ddup.upload(tracer=tracer)
170169

171170
profile = pprof_utils.parse_profile(output_filename)
172171
samples = pprof_utils.get_samples_with_label_key(profile, "span id")
@@ -187,7 +186,7 @@ def target_fun():
187186

188187

189188
@pytest.mark.parametrize("stack_v2_enabled", [True, False])
190-
def test_push_non_web_span(stack_v2_enabled, tmp_path):
189+
def test_push_non_web_span(stack_v2_enabled, tmp_path, tracer):
191190
if sys.version_info[:2] == (3, 7) and stack_v2_enabled:
192191
pytest.skip("stack_v2 is not supported on Python 3.7")
193192

@@ -216,7 +215,7 @@ def test_push_non_web_span(stack_v2_enabled, tmp_path):
216215
local_root_span_id = span._local_root.span_id
217216
for _ in range(10):
218217
time.sleep(0.1)
219-
ddup.upload()
218+
ddup.upload(tracer=tracer)
220219

221220
profile = pprof_utils.parse_profile(output_filename)
222221
samples = pprof_utils.get_samples_with_label_key(profile, "span id")
@@ -235,7 +234,7 @@ def test_push_non_web_span(stack_v2_enabled, tmp_path):
235234

236235

237236
@pytest.mark.parametrize("stack_v2_enabled", [True, False])
238-
def test_push_span_none_span_type(stack_v2_enabled, tmp_path):
237+
def test_push_span_none_span_type(stack_v2_enabled, tmp_path, tracer):
239238
# Test for https://github.com/DataDog/dd-trace-py/issues/11141
240239
if sys.version_info[:2] == (3, 7) and stack_v2_enabled:
241240
pytest.skip("stack_v2 is not supported on Python 3.7")
@@ -266,7 +265,7 @@ def test_push_span_none_span_type(stack_v2_enabled, tmp_path):
266265
local_root_span_id = span._local_root.span_id
267266
for _ in range(10):
268267
time.sleep(0.1)
269-
ddup.upload()
268+
ddup.upload(tracer=tracer)
270269

271270
profile = pprof_utils.parse_profile(output_filename)
272271
samples = pprof_utils.get_samples_with_label_key(profile, "span id")
@@ -398,7 +397,7 @@ def target_fun():
398397

399398
@pytest.mark.skipif(not stack.FEATURES["stack-exceptions"], reason="Stack exceptions are not supported")
400399
@pytest.mark.parametrize("stack_v2_enabled", [True, False])
401-
def test_exception_collection_trace(stack_v2_enabled, tmp_path):
400+
def test_exception_collection_trace(stack_v2_enabled, tmp_path, tracer):
402401
if sys.version_info[:2] == (3, 7) and stack_v2_enabled:
403402
pytest.skip("stack_v2 is not supported on Python 3.7")
404403

@@ -419,7 +418,7 @@ def test_exception_collection_trace(stack_v2_enabled, tmp_path):
419418
except Exception:
420419
time.sleep(1)
421420

422-
ddup.upload()
421+
ddup.upload(tracer=tracer)
423422

424423
profile = pprof_utils.parse_profile(output_filename)
425424
samples = pprof_utils.get_samples_with_label_key(profile, "exception type")

tests/profiling_v2/collector/test_threading.py

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
import pytest
99

1010
from ddtrace import ext
11-
from ddtrace import tracer
1211
from ddtrace.internal.datadog.profiling import ddup
1312
from ddtrace.profiling.collector import threading as collector_threading
1413
from tests.profiling.collector import pprof_utils
@@ -356,7 +355,7 @@ def lockfunc(self):
356355
],
357356
)
358357

359-
def test_lock_events_tracer(self):
358+
def test_lock_events_tracer(self, tracer):
360359
tracer._endpoint_call_counter_span_processor.enable()
361360
resource = str(uuid.uuid4())
362361
span_type = ext.SpanTypes.WEB
@@ -375,7 +374,7 @@ def test_lock_events_tracer(self):
375374
span_id = t.span_id
376375

377376
lock2.release() # !RELEASE! test_lock_events_tracer_2
378-
ddup.upload()
377+
ddup.upload(tracer=tracer)
379378

380379
linenos1 = get_lock_linenos("test_lock_events_tracer_1")
381380
linenos2 = get_lock_linenos("test_lock_events_tracer_2")
@@ -419,7 +418,7 @@ def test_lock_events_tracer(self):
419418
],
420419
)
421420

422-
def test_lock_events_tracer_non_web(self):
421+
def test_lock_events_tracer_non_web(self, tracer):
423422
tracer._endpoint_call_counter_span_processor.enable()
424423
resource = str(uuid.uuid4())
425424
span_type = ext.SpanTypes.SQL
@@ -435,7 +434,7 @@ def test_lock_events_tracer_non_web(self):
435434
span_id = t.span_id
436435

437436
lock2.release() # !RELEASE! test_lock_events_tracer_non_web
438-
ddup.upload()
437+
ddup.upload(tracer=tracer)
439438

440439
linenos2 = get_lock_linenos("test_lock_events_tracer_non_web")
441440

@@ -463,7 +462,7 @@ def test_lock_events_tracer_non_web(self):
463462
],
464463
)
465464

466-
def test_lock_events_tracer_late_finish(self):
465+
def test_lock_events_tracer_late_finish(self, tracer):
467466
tracer._endpoint_call_counter_span_processor.enable()
468467
resource = str(uuid.uuid4())
469468
span_type = ext.SpanTypes.WEB
@@ -482,7 +481,7 @@ def test_lock_events_tracer_late_finish(self):
482481
lock2.release() # !RELEASE! test_lock_events_tracer_late_finish_2
483482
span.resource = resource
484483
span.finish()
485-
ddup.upload()
484+
ddup.upload(tracer=tracer)
486485

487486
linenos1 = get_lock_linenos("test_lock_events_tracer_late_finish_1")
488487
linenos2 = get_lock_linenos("test_lock_events_tracer_late_finish_2")
@@ -520,7 +519,7 @@ def test_lock_events_tracer_late_finish(self):
520519
],
521520
)
522521

523-
def test_resource_not_collected(self):
522+
def test_resource_not_collected(self, tracer):
524523
tracer._endpoint_call_counter_span_processor.enable()
525524
resource = str(uuid.uuid4())
526525
span_type = ext.SpanTypes.WEB
@@ -539,7 +538,7 @@ def test_resource_not_collected(self):
539538
lock1.release() # !RELEASE! test_resource_not_collected_1
540539
span_id = t.span_id
541540
lock2.release() # !RELEASE! test_resource_not_collected_2
542-
ddup.upload()
541+
ddup.upload(tracer=tracer)
543542

544543
linenos1 = get_lock_linenos("test_resource_not_collected_1")
545544
linenos2 = get_lock_linenos("test_resource_not_collected_2")

0 commit comments

Comments
 (0)