Skip to content

Commit 5f332e3

Browse files
authored
(3) Move tracing related functions from Hub to Scope (#2558)
Moved some functionality from Hub to Client: - sorted some typing imports - moved `get_traceparent` from Hub to Scope - moved `get_baggage` from Hub to Scope - moved `iter_trace_propagation_headers` from Hub to Scope - moved `trace_propagation_meta` from Hub to Scope This is preparation work for refactoring how we deal with Hubs and Scopes in the future.
1 parent 79e15f5 commit 5f332e3

File tree

2 files changed

+267
-152
lines changed

2 files changed

+267
-152
lines changed

sentry_sdk/hub.py

Lines changed: 28 additions & 141 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,10 @@
77
from sentry_sdk.consts import INSTRUMENTER
88
from sentry_sdk.scope import Scope
99
from sentry_sdk.client import Client
10-
from sentry_sdk.profiler import Profile
1110
from sentry_sdk.tracing import (
1211
NoOpSpan,
1312
Span,
1413
Transaction,
15-
BAGGAGE_HEADER_NAME,
16-
SENTRY_TRACE_HEADER_NAME,
17-
)
18-
from sentry_sdk.tracing_utils import (
19-
has_tracing_enabled,
20-
normalize_incoming_data,
2114
)
2215

2316
from sentry_sdk.utils import (
@@ -28,18 +21,18 @@
2821
from sentry_sdk._types import TYPE_CHECKING
2922

3023
if TYPE_CHECKING:
31-
from typing import Union
3224
from typing import Any
33-
from typing import Optional
34-
from typing import Tuple
35-
from typing import Dict
36-
from typing import List
3725
from typing import Callable
26+
from typing import ContextManager
27+
from typing import Dict
3828
from typing import Generator
29+
from typing import List
30+
from typing import Optional
31+
from typing import overload
32+
from typing import Tuple
3933
from typing import Type
4034
from typing import TypeVar
41-
from typing import overload
42-
from typing import ContextManager
35+
from typing import Union
4336

4437
from sentry_sdk.integrations import Integration
4538
from sentry_sdk._types import (
@@ -447,54 +440,12 @@ def start_span(self, span=None, instrumenter=INSTRUMENTER.SENTRY, **kwargs):
447440
448441
For supported `**kwargs` see :py:class:`sentry_sdk.tracing.Span`.
449442
"""
450-
configuration_instrumenter = self.client and self.client.options["instrumenter"]
451-
452-
if instrumenter != configuration_instrumenter:
453-
return NoOpSpan()
454-
455-
# THIS BLOCK IS DEPRECATED
456-
# TODO: consider removing this in a future release.
457-
# This is for backwards compatibility with releases before
458-
# start_transaction existed, to allow for a smoother transition.
459-
if isinstance(span, Transaction) or "transaction" in kwargs:
460-
deprecation_msg = (
461-
"Deprecated: use start_transaction to start transactions and "
462-
"Transaction.start_child to start spans."
463-
)
464-
465-
if isinstance(span, Transaction):
466-
logger.warning(deprecation_msg)
467-
return self.start_transaction(span)
468-
469-
if "transaction" in kwargs:
470-
logger.warning(deprecation_msg)
471-
name = kwargs.pop("transaction")
472-
return self.start_transaction(name=name, **kwargs)
473-
474-
# THIS BLOCK IS DEPRECATED
475-
# We do not pass a span into start_span in our code base, so I deprecate this.
476-
if span is not None:
477-
deprecation_msg = "Deprecated: passing a span into `start_span` is deprecated and will be removed in the future."
478-
logger.warning(deprecation_msg)
479-
return span
480-
481-
kwargs.setdefault("hub", self)
482-
483-
active_span = self.scope.span
484-
if active_span is not None:
485-
new_child_span = active_span.start_child(**kwargs)
486-
return new_child_span
443+
client, scope = self._stack[-1]
487444

488-
# If there is already a trace_id in the propagation context, use it.
489-
# This does not need to be done for `start_child` above because it takes
490-
# the trace_id from the parent span.
491-
if "trace_id" not in kwargs:
492-
traceparent = self.get_traceparent()
493-
trace_id = traceparent.split("-")[0] if traceparent else None
494-
if trace_id is not None:
495-
kwargs["trace_id"] = trace_id
445+
kwargs["hub"] = self
446+
kwargs["client"] = client
496447

497-
return Span(**kwargs)
448+
return scope.start_span(span=span, instrumenter=instrumenter, **kwargs)
498449

499450
def start_transaction(
500451
self, transaction=None, instrumenter=INSTRUMENTER.SENTRY, **kwargs
@@ -524,55 +475,25 @@ def start_transaction(
524475
525476
For supported `**kwargs` see :py:class:`sentry_sdk.tracing.Transaction`.
526477
"""
527-
configuration_instrumenter = self.client and self.client.options["instrumenter"]
528-
529-
if instrumenter != configuration_instrumenter:
530-
return NoOpSpan()
531-
532-
custom_sampling_context = kwargs.pop("custom_sampling_context", {})
533-
534-
# if we haven't been given a transaction, make one
535-
if transaction is None:
536-
kwargs.setdefault("hub", self)
537-
transaction = Transaction(**kwargs)
538-
539-
# use traces_sample_rate, traces_sampler, and/or inheritance to make a
540-
# sampling decision
541-
sampling_context = {
542-
"transaction_context": transaction.to_json(),
543-
"parent_sampled": transaction.parent_sampled,
544-
}
545-
sampling_context.update(custom_sampling_context)
546-
transaction._set_initial_sampling_decision(sampling_context=sampling_context)
547-
548-
profile = Profile(transaction, hub=self)
549-
profile._set_initial_sampling_decision(sampling_context=sampling_context)
478+
client, scope = self._stack[-1]
550479

551-
# we don't bother to keep spans if we already know we're not going to
552-
# send the transaction
553-
if transaction.sampled:
554-
max_spans = (
555-
self.client and self.client.options["_experiments"].get("max_spans")
556-
) or 1000
557-
transaction.init_span_recorder(maxlen=max_spans)
480+
kwargs["hub"] = self
481+
kwargs["client"] = client
558482

559-
return transaction
483+
return scope.start_transaction(
484+
transaction=transaction, instrumenter=instrumenter, **kwargs
485+
)
560486

561487
def continue_trace(self, environ_or_headers, op=None, name=None, source=None):
562488
# type: (Dict[str, Any], Optional[str], Optional[str], Optional[str]) -> Transaction
563489
"""
564490
Sets the propagation context from environment or headers and returns a transaction.
565491
"""
566-
with self.configure_scope() as scope:
567-
scope.generate_propagation_context(environ_or_headers)
492+
scope = self._stack[-1][1]
568493

569-
transaction = Transaction.continue_from_headers(
570-
normalize_incoming_data(environ_or_headers),
571-
op=op,
572-
name=name,
573-
source=source,
494+
return scope.continue_trace(
495+
environ_or_headers=environ_or_headers, op=op, name=name, source=source
574496
)
575-
return transaction
576497

577498
@overload
578499
def push_scope(
@@ -735,25 +656,16 @@ def get_traceparent(self):
735656
"""
736657
Returns the traceparent either from the active span or from the scope.
737658
"""
738-
if self.client is not None:
739-
if has_tracing_enabled(self.client.options) and self.scope.span is not None:
740-
return self.scope.span.to_traceparent()
741-
742-
return self.scope.get_traceparent()
659+
client, scope = self._stack[-1]
660+
return scope.get_traceparent(client=client)
743661

744662
def get_baggage(self):
745663
# type: () -> Optional[str]
746664
"""
747665
Returns Baggage either from the active span or from the scope.
748666
"""
749-
if (
750-
self.client is not None
751-
and has_tracing_enabled(self.client.options)
752-
and self.scope.span is not None
753-
):
754-
baggage = self.scope.span.to_baggage()
755-
else:
756-
baggage = self.scope.get_baggage()
667+
client, scope = self._stack[-1]
668+
baggage = scope.get_baggage(client=client)
757669

758670
if baggage is not None:
759671
return baggage.serialize()
@@ -767,19 +679,9 @@ def iter_trace_propagation_headers(self, span=None):
767679
from the span representing the request, if available, or the current
768680
span on the scope if not.
769681
"""
770-
client = self._stack[-1][0]
771-
propagate_traces = client and client.options["propagate_traces"]
772-
if not propagate_traces:
773-
return
774-
775-
span = span or self.scope.span
682+
client, scope = self._stack[-1]
776683

777-
if client and has_tracing_enabled(client.options) and span is not None:
778-
for header in span.iter_headers():
779-
yield header
780-
else:
781-
for header in self.scope.iter_headers():
782-
yield header
684+
return scope.iter_trace_propagation_headers(span=span, client=client)
783685

784686
def trace_propagation_meta(self, span=None):
785687
# type: (Optional[Span]) -> str
@@ -792,23 +694,8 @@ def trace_propagation_meta(self, span=None):
792694
"The parameter `span` in trace_propagation_meta() is deprecated and will be removed in the future."
793695
)
794696

795-
meta = ""
796-
797-
sentry_trace = self.get_traceparent()
798-
if sentry_trace is not None:
799-
meta += '<meta name="%s" content="%s">' % (
800-
SENTRY_TRACE_HEADER_NAME,
801-
sentry_trace,
802-
)
803-
804-
baggage = self.get_baggage()
805-
if baggage is not None:
806-
meta += '<meta name="%s" content="%s">' % (
807-
BAGGAGE_HEADER_NAME,
808-
baggage,
809-
)
810-
811-
return meta
697+
client, scope = self._stack[-1]
698+
return scope.trace_propagation_meta(span=span, client=client)
812699

813700

814701
GLOBAL_HUB = Hub()

0 commit comments

Comments
 (0)