Skip to content

Commit 0adee56

Browse files
authored
refactor: remove global tracer variable from core (#19083)
This change replaces `core.tracer` with a tracer instance stored on the root `ExecutionContext` object, increasing the separation of concerns between tracing and core. With this change, tracing becomes a user of the core API rather than being a part of it. This change also increases a missed microbenchmark by a small amount to account for slightly increased execution time during span creation as a result of the `ExecutionContext.get_item` call added here. Co-authored-by: emmett.butler <emmett.butler@datadoghq.com>
1 parent e322ef8 commit 0adee56

5 files changed

Lines changed: 10 additions & 9 deletions

File tree

.gitlab/benchmarks/bp-runner.microbenchmarks.fail-on-breach.template.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ experiments:
215215
- max_rss_usage < 62.50 MB
216216
- name: flasksqli-tracer-enabled
217217
thresholds:
218-
- execution_time < 2.25 ms
218+
- execution_time < 2.27 ms
219219
- max_rss_usage < 62.00 MB
220220

221221
# httppropagationextract

ddtrace/contrib/internal/trace_utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,7 @@ def wrapper(wrapped, instance, args, kwargs):
317317

318318

319319
def is_tracing_enabled() -> bool:
320-
tracer = core.tracer
320+
tracer = core.root.get_item("tracer")
321321
return tracer is not None and (tracer.enabled or asm_config._apm_opt_out)
322322

323323

ddtrace/internal/core/__init__.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -145,8 +145,6 @@ def done_callback(f):
145145

146146
_MISSING = object()
147147

148-
tracer = None
149-
150148
log = logging.getLogger(__name__)
151149

152150

@@ -332,7 +330,8 @@ def span(self) -> "Span":
332330
"Creating fallback 'default' span.",
333331
self,
334332
)
335-
self._inner_span = tracer.current_span() or tracer.trace("default") # type: ignore
333+
tracer = self.get_item("tracer")
334+
self._inner_span = tracer.current_span() or tracer.trace("default")
336335
return self._inner_span
337336

338337
@span.setter
@@ -439,6 +438,7 @@ def get_span() -> Optional["Span"]:
439438

440439
def get_root_span() -> Optional["Span"]:
441440
span = get_span()
441+
tracer = _CURRENT_CONTEXT.get().root().get_item("tracer")
442442
if span is None:
443443
return None if tracer is None else tracer.current_root_span()
444444
return span._local_root or span

ddtrace/propagation/http.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1132,13 +1132,14 @@ def _get_sampled_injection_context(
11321132
If sampling_priority is already set, returns immediately. Otherwise, finds the
11331133
appropriate span and triggers sampling before returning the injection context.
11341134
"""
1135+
core_tracer = core.root.get_item("tracer")
11351136
# Extract context for header injection (non_active_span takes precedence)
11361137
injection_context = trace_info.context if isinstance(trace_info, Span) else trace_info
11371138

11381139
# Find root span for sampling decisions
11391140
if injection_context.sampling_priority is not None:
11401141
return injection_context
1141-
elif core.tracer is None:
1142+
elif core_tracer is None:
11421143
# This should never happen, tracer should be initialized before headers can be injected.
11431144
log.error(
11441145
"No tracer found and injection context %s has no sampling priority, skipping sampling",
@@ -1153,13 +1154,13 @@ def _get_sampled_injection_context(
11531154
elif isinstance(trace_info, Span):
11541155
# Use span's root for sampling
11551156
sampling_span = trace_info._local_root
1156-
elif (current_root := core.tracer.current_root_span()) and current_root.trace_id == trace_info.trace_id:
1157+
elif (current_root := core_tracer.current_root_span()) and current_root.trace_id == trace_info.trace_id:
11571158
# Get the local root span for the current trace (if it is active, otherwise we can't sample)
11581159
sampling_span = current_root
11591160

11601161
# Sample the local root span before injecting headers.
11611162
if sampling_span:
1162-
core.tracer.sample(sampling_span)
1163+
core_tracer.sample(sampling_span)
11631164
log.debug("%s sampled before propagating trace: span_context=%s", sampling_span, injection_context)
11641165

11651166
return injection_context

ddtrace/trace/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
# a global tracer instance with integration settings
1010
tracer = Tracer()
11-
core.tracer = tracer # type: ignore
11+
core.root.set_item("tracer", tracer)
1212

1313

1414
__all__ = [

0 commit comments

Comments
 (0)