8000 Add sentry_meta object to Span and pass it through to ReadableSpan (#… · getsentry/sentry-python@7cd4c8d · GitHub
[go: up one dir, main page]

Skip to content

Commit 7cd4c8d

Browse files
authored
Add sentry_meta object to Span and pass it through to ReadableSpan (#3676)
1 parent 6e3778d commit 7cd4c8d

File tree

3 files changed

+42
-8
lines changed

3 files changed

+42
-8
lines changed

sentry_sdk/integrations/opentelemetry/integration.py

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@
1818
try:
1919
from opentelemetry import trace
2020
from opentelemetry.propagate import set_global_textmap
21-
from opentelemetry.sdk.trace import TracerProvider
21+
from opentelemetry.trace import Span as AbstractSpan
22+
from opentelemetry.sdk.trace import TracerProvider, Span, ReadableSpan
2223
except ImportError:
2324
raise DidNotEnable("opentelemetry not installed")
2425

@@ -27,6 +28,11 @@
2728
except ImportError:
2829
DjangoInstrumentor = None
2930

31+
from sentry_sdk._types import TYPE_CHECKING
32+
33+
if TYPE_CHECKING:
34+
from typing import Union, Any
35+
3036

3137
CONFIGURABLE_INSTRUMENTATIONS = {
3238
DjangoInstrumentor: {"is_sql_commentor_enabled": True},
@@ -45,11 +51,40 @@ def setup_once():
4551
)
4652

4753
_setup_sentry_tracing()
54+
_patch_readable_span()
4855
# _setup_instrumentors()
4956

5057
logger.debug("[OTel] Finished setting up OpenTelemetry integration")
5158

5259

60+
def _patch_readable_span():
61+
# type: () -> None
62+
"""
63+
We need to pass through sentry specific metadata/objects from Span to ReadableSpan
64+
to work with them consistently in the SpanProcessor.
65+
"""
66+
67+
@property
68+
def sentry_meta(self):
69+
# type: (Union[AbstractSpan, Span, ReadableSpan]) -> dict[str, Any]
70+
if not getattr(self, "_sentry_meta", None):
71+
self._sentry_meta = {}
72+
return self._sentry_meta
73+
74+
AbstractSpan.sentry_meta = sentry_meta
75+
ReadableSpan.sentry_meta = sentry_meta
76+
77+
old_readable_span = Span._readable_span
78+
79+
def sentry_patched_readable_span(self):
80+
# type: (Span) -> ReadableSpan
81+
readable_span = old_readable_span(self)
82+
readable_span._sentry_meta = self._sentry_meta
83+
return readable_span
84+
85+
Span._readable_span = sentry_patched_readable_span
86+
87+
5388
def _setup_sentry_tracing():
5489
# type: () -> None
5590
import opentelemetry.context

sentry_sdk/integrations/opentelemetry/potel_span_processor.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
format_span_id,
77
get_current_span,
88
INVALID_SPAN,
9-
Span as TraceApiSpan,
9+
Span as AbstractSpan,
1010
)
1111
from opentelemetry.context import Context
1212
from opentelemetry.sdk.trace import Span, ReadableSpan, SpanProcessor
@@ -78,19 +78,19 @@ def force_flush(self, timeout_millis=30000):
7878
return True
7979

8080
def _add_root_span(self, span, parent_span):
81-
# type: (Span, TraceApiSpan) -> None
81+
# type: (Span, AbstractSpan) -> None
8282
"""
8383
This is required to make POTelSpan.root_span work
8484
since we can't traverse back to the root purely with otel efficiently.
8585
"""
8686
if parent_span != INVALID_SPAN and not parent_span.get_span_context().is_remote:
8787
# child span points to parent's root or parent
88-
span._sentry_root_otel_span = getattr(
89-
parent_span, "_sentry_root_otel_span", parent_span
88+
span.sentry_meta["root_span"] = parent_span.sentry_meta.get(
89+
"root_span", parent_span
9090
)
9191
else:
9292
# root span points to itself
93-
span._sentry_root_otel_span = span
93+
span.sentry_meta["root_span"] = span
9494

9595
def _flush_root_span(self, span):
9696
# type: (ReadableSpan) -> None

sentry_sdk/tracing.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1327,8 +1327,7 @@ def containing_transaction(self):
13271327
def root_span(self):
13281328
# type: () -> Optional[POTelSpan]
13291329
root_otel_span = cast(
1330-
"Optional[OtelSpan]",
1331-
getattr(self._otel_span, "_sentry_root_otel_span", None),
1330+
"Optional[OtelSpan]", self._otel_span.sentry_meta.get("root_span", None)
13321331
)
13331332
return POTelSpan(otel_span=root_otel_span) if root_otel_span else None
13341333

0 commit comments

Comments
 (0)
0