11import os
22import sys
3- import uuid
43from copy import copy
54from collections import deque
65from contextlib import contextmanager
1514from sentry_sdk .session import Session
1615from sentry_sdk .tracing_utils import (
1716 Baggage ,
18- extract_sentrytrace_data ,
1917 has_tracing_enabled ,
2018 normalize_incoming_data ,
19+ PropagationContext ,
2120)
2221from sentry_sdk .tracing import (
2322 BAGGAGE_HEADER_NAME ,
@@ -196,7 +195,7 @@ def __init__(self, ty=None, client=None):
196195 self ._error_processors = [] # type: List[ErrorProcessor]
197196
198197 self ._name = None # type: Optional[str]
199- self ._propagation_context = None # type: Optional[Dict[str, Any] ]
198+ self ._propagation_context = None # type: Optional[PropagationContext ]
200199
201200 self .client = NonRecordingClient () # type: sentry_sdk.client.BaseClient
202201
@@ -431,77 +430,28 @@ def _load_trace_data_from_env(self):
431430
432431 return incoming_trace_information or None
433432
434- def _extract_propagation_context (self , data ):
435- # type: (Dict[str, Any]) -> Optional[Dict[str, Any]]
436- context = {} # type: Dict[str, Any]
437- normalized_data = normalize_incoming_data (data )
438-
439- baggage_header = normalized_data .get (BAGGAGE_HEADER_NAME )
440- if baggage_header :
441- context ["dynamic_sampling_context" ] = Baggage .from_incoming_header (
442- baggage_header
443- ).dynamic_sampling_context ()
444-
445- sentry_trace_header = normalized_data .get (SENTRY_TRACE_HEADER_NAME )
446- if sentry_trace_header :
447- sentrytrace_data = extract_sentrytrace_data (sentry_trace_header )
448- if sentrytrace_data is not None :
449- context .update (sentrytrace_data )
450-
451- only_baggage_no_sentry_trace = (
452- "dynamic_sampling_context" in context and "trace_id" not in context
453- )
454- if only_baggage_no_sentry_trace :
455- context .update (self ._create_new_propagation_context ())
456-
457- if context :
458- if not context .get ("span_id" ):
459- context ["span_id" ] = uuid .uuid4 ().hex [16 :]
460-
461- return context
462-
463- return None
464-
465- def _create_new_propagation_context (self ):
466- # type: () -> Dict[str, Any]
467- return {
468- "trace_id" : uuid .uuid4 ().hex ,
469- "span_id" : uuid .uuid4 ().hex [16 :],
470- "parent_span_id" : None ,
471- "dynamic_sampling_context" : None ,
472- }
473-
474433 def set_new_propagation_context (self ):
475434 # type: () -> None
476435 """
477436 Creates a new propagation context and sets it as `_propagation_context`. Overwriting existing one.
478437 """
479- self ._propagation_context = self ._create_new_propagation_context ()
480- logger .debug (
481- "[Tracing] Create new propagation context: %s" ,
482- self ._propagation_context ,
483- )
438+ self ._propagation_context = PropagationContext ()
484439
485440 def generate_propagation_context (self , incoming_data = None ):
486441 # type: (Optional[Dict[str, str]]) -> None
487442 """
488- Makes sure the propagation context (`_propagation_context`) is set.
489- The propagation context only lives on the current scope.
490- If there is `incoming_data` overwrite existing `_propagation_context`.
491- if there is no `incoming_data` create new `_propagation_context`, but do NOT overwrite if already existing.
443+ Makes sure the propagation context is set on the scope.
444+ If there is `incoming_data` overwrite existing propagation context.
445+ If there is no `incoming_data` create new propagation context, but do NOT overwrite if already existing.
492446 """
493447 if incoming_data :
494- context = self ._extract_propagation_context (incoming_data )
495-
496- if context is not None :
497- self ._propagation_context = context
498- logger .debug (
499- "[Tracing] Extracted propagation context from incoming data: %s" ,
500- self ._propagation_context ,
501- )
448+ propagation_context = PropagationContext .from_incoming_data (incoming_data )
449+ if propagation_context is not None :
450+ self ._propagation_context = propagation_context
502451
503- if self ._propagation_context is None and self ._type != ScopeType .CURRENT :
504- self .set_new_propagation_context ()
452+ if self ._type != ScopeType .CURRENT :
453+ if self ._propagation_context is None :
454+ self .set_new_propagation_context ()
505455
506456 def get_dynamic_sampling_context (self ):
507457 # type: () -> Optional[Dict[str, str]]
@@ -514,11 +464,11 @@ def get_dynamic_sampling_context(self):
514464
515465 baggage = self .get_baggage ()
516466 if baggage is not None :
517- self ._propagation_context [ " dynamic_sampling_context" ] = (
467+ self ._propagation_context . dynamic_sampling_context = (
518468 baggage .dynamic_sampling_context ()
519469 )
520470
521- return self ._propagation_context [ " dynamic_sampling_context" ]
471+ return self ._propagation_context . dynamic_sampling_context
522472
523473 def get_traceparent (self , * args , ** kwargs ):
524474 # type: (Any, Any) -> Optional[str]
@@ -535,8 +485,8 @@ def get_traceparent(self, *args, **kwargs):
535485 # If this scope has a propagation context, return traceparent from there
536486 if self ._propagation_context is not None :
537487 traceparent = "%s-%s" % (
538- self ._propagation_context [ " trace_id" ] ,
539- self ._propagation_context [ " span_id" ] ,
488+ self ._propagation_context . trace_id ,
489+ self ._propagation_context . span_id ,
540490 )
541491 return traceparent
542492
@@ -557,8 +507,8 @@ def get_baggage(self, *args, **kwargs):
557507
558508 # If this scope has a propagation context, return baggage from there
559509 if self ._propagation_context is not None :
560- dynamic_sampling_context = self . _propagation_context . get (
561- " dynamic_sampling_context"
510+ dynamic_sampling_context = (
511+ self . _propagation_context . dynamic_sampling_context
562512 )
563513 if dynamic_sampling_context is None :
564514 return Baggage .from_options (self )
@@ -577,9 +527,9 @@ def get_trace_context(self):
577527 return None
578528
579529 trace_context = {
580- "trace_id" : self ._propagation_context [ " trace_id" ] ,
581- "span_id" : self ._propagation_context [ " span_id" ] ,
582- "parent_span_id" : self ._propagation_context [ " parent_span_id" ] ,
530+ "trace_id" : self ._propagation_context . trace_id ,
531+ "span_id" : self ._propagation_context . span_id ,
532+ "parent_span_id" : self ._propagation_context . parent_span_id ,
583533 "dynamic_sampling_context" : self .get_dynamic_sampling_context (),
584534 } # type: Dict[str, Any]
585535
@@ -667,7 +617,7 @@ def iter_trace_propagation_headers(self, *args, **kwargs):
667617 yield header
668618
669619 def get_active_propagation_context (self ):
670- # type: () -> Dict[str, Any ]
620+ # type: () -> Optional[PropagationContext ]
671621 if self ._propagation_context is not None :
672622 return self ._propagation_context
673623
@@ -679,7 +629,7 @@ def get_active_propagation_context(self):
679629 if isolation_scope ._propagation_context is not None :
680630 return isolation_scope ._propagation_context
681631
682- return {}
632+ return None
683633
684634 def clear (self ):
685635 # type: () -> None
@@ -1069,12 +1019,11 @@ def start_span(self, instrumenter=INSTRUMENTER.SENTRY, **kwargs):
10691019 span = self .span or Scope .get_isolation_scope ().span
10701020
10711021 if span is None :
1072- # New spans get the `trace_id`` from the scope
1022+ # New spans get the `trace_id` from the scope
10731023 if "trace_id" not in kwargs :
1074-
1075- trace_id = self .get_active_propagation_context ().get ("trace_id" )
1076- if trace_id is not None :
1077- kwargs ["trace_id" ] = trace_id
1024+ propagation_context = self .get_active_propagation_context ()
1025+ if propagation_context is not None :
1026+ kwargs ["trace_id" ] = propagation_context .trace_id
10781027
10791028 span = Span (** kwargs )
10801029 else :
0 commit comments