| 
107 | 107 | 
 
  | 
108 | 108 | global_event_processors = []  # type: List[EventProcessor]  | 
109 | 109 | 
 
  | 
 | 110 | +# A function returning a (trace_id, span_id) tuple  | 
 | 111 | +# from an external tracing source (such as otel)  | 
 | 112 | +_external_propagation_context_fn = None  # type: Optional[Callable[[], Optional[Tuple[str, str]]]]  | 
 | 113 | + | 
110 | 114 | 
 
  | 
111 | 115 | class ScopeType(Enum):  | 
112 | 116 |     CURRENT = "current"  | 
@@ -142,6 +146,19 @@ def add_global_event_processor(processor):  | 
142 | 146 |     global_event_processors.append(processor)  | 
143 | 147 | 
 
  | 
144 | 148 | 
 
  | 
 | 149 | +def register_external_propagation_context(fn):  | 
 | 150 | +    # type: (Callable[[], Optional[Tuple[str, str]]]) -> None  | 
 | 151 | +    global _external_propagation_context_fn  | 
 | 152 | +    _external_propagation_context_fn = fn  | 
 | 153 | + | 
 | 154 | + | 
 | 155 | +def get_external_propagation_context():  | 
 | 156 | +    # type: () -> Optional[Tuple[str, str]]  | 
 | 157 | +    return (  | 
 | 158 | +        _external_propagation_context_fn() if _external_propagation_context_fn else None  | 
 | 159 | +    )  | 
 | 160 | + | 
 | 161 | + | 
145 | 162 | def _attr_setter(fn):  | 
146 | 163 |     # type: (Any) -> Any  | 
147 | 164 |     return property(fset=fn, doc=fn.__doc__)  | 
@@ -562,22 +579,30 @@ def get_baggage(self, *args, **kwargs):  | 
562 | 579 |         return self.get_isolation_scope().get_baggage()  | 
563 | 580 | 
 
  | 
564 | 581 |     def get_trace_context(self):  | 
565 |  | -        # type: () -> Any  | 
 | 582 | +        # type: () -> Dict[str, Any]  | 
566 | 583 |         """  | 
567 | 584 |         Returns the Sentry "trace" context from the Propagation Context.  | 
568 | 585 |         """  | 
569 |  | -        if self._propagation_context is None:  | 
570 |  | -            return None  | 
 | 586 | +        if has_tracing_enabled(self.get_client().options) and self._span is not None:  | 
 | 587 | +            return self._span.get_trace_context()  | 
 | 588 | + | 
 | 589 | +        # if we are tracing externally (otel), those values take precedence  | 
 | 590 | +        external_propagation_context = get_external_propagation_context()  | 
 | 591 | +        if external_propagation_context:  | 
 | 592 | +            trace_id, span_id = external_propagation_context  | 
 | 593 | +            return {"trace_id": trace_id, "span_id": span_id}  | 
571 | 594 | 
 
  | 
572 |  | -        trace_context = {  | 
573 |  | -            "trace_id": self._propagation_context.trace_id,  | 
574 |  | -            "span_id": self._propagation_context.span_id,  | 
575 |  | -            "parent_span_id": self._propagation_context.parent_span_id,  | 
 | 595 | +        propagation_context = self.get_active_propagation_context()  | 
 | 596 | +        if propagation_context is None:  | 
 | 597 | +            return {}  | 
 | 598 | + | 
 | 599 | +        return {  | 
 | 600 | +            "trace_id": propagation_context.trace_id,  | 
 | 601 | +            "span_id": propagation_context.span_id,  | 
 | 602 | +            "parent_span_id": propagation_context.parent_span_id,  | 
576 | 603 |             "dynamic_sampling_context": self.get_dynamic_sampling_context(),  | 
577 | 604 |         }  # type: Dict[str, Any]  | 
578 | 605 | 
 
  | 
579 |  | -        return trace_context  | 
580 |  | - | 
581 | 606 |     def trace_propagation_meta(self, *args, **kwargs):  | 
582 | 607 |         # type: (*Any, **Any) -> str  | 
583 | 608 |         """  | 
@@ -1438,10 +1463,7 @@ def _apply_contexts_to_event(self, event, hint, options):  | 
1438 | 1463 | 
 
  | 
1439 | 1464 |         # Add "trace" context  | 
1440 | 1465 |         if contexts.get("trace") is None:  | 
1441 |  | -            if has_tracing_enabled(options) and self._span is not None:  | 
1442 |  | -                contexts["trace"] = self._span.get_trace_context()  | 
1443 |  | -            else:  | 
1444 |  | -                contexts["trace"] = self.get_trace_context()  | 
 | 1466 | +            contexts["trace"] = self.get_trace_context()  | 
1445 | 1467 | 
 
  | 
1446 | 1468 |     def _apply_flags_to_event(self, event, hint, options):  | 
1447 | 1469 |         # type: (Event, Hint, Optional[Dict[str, Any]]) -> None  | 
 | 
0 commit comments