Skip to content

Commit d4539e1

Browse files
committed
feat: Access transaction in current scope
Specially when trying to add spans to automatically instrumented transactions, users need access to the current transaction. This gives direct access no matter how deep the code is in the transaction/span tree.
1 parent b539ecb commit d4539e1

File tree

2 files changed

+40
-3
lines changed

2 files changed

+40
-3
lines changed

sentry_sdk/scope.py

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,10 +134,33 @@ def fingerprint(self, value):
134134
"""When set this overrides the default fingerprint."""
135135
self._fingerprint = value
136136

137-
@_attr_setter
137+
@property
138+
def transaction(self):
139+
# type: () -> Any
140+
# would be type: () -> Optional[Span], see https://github.com/python/mypy/issues/3004
141+
# XXX: update return type to Optional[Transaction]
142+
"""Return the transaction (root span) in the scope."""
143+
if self._span is None or self._span._span_recorder is None:
144+
return None
145+
try:
146+
return self._span._span_recorder.spans[0]
147+
except (AttributeError, IndexError):
148+
return None
149+
150+
@transaction.setter
138151
def transaction(self, value):
139-
# type: (Optional[str]) -> None
152+
# type: (Any) -> None
153+
# would be type: (Optional[str]) -> None, see https://github.com/python/mypy/issues/3004
140154
"""When set this forces a specific transaction name to be set."""
155+
# XXX: the docstring above is misleading. The implementation of
156+
# apply_to_event prefers an existing value of event.transaction over
157+
# anything set in the scope.
158+
# XXX: note that with the introduction of the Scope.transaction getter,
159+
# there is a semantic and type mismatch between getter and setter. The
160+
# getter returns a transaction, the setter sets a transaction name.
161+
# Without breaking version compatibility, we could make the setter set a
162+
# transaction name or transaction (self._span) depending on the type of
163+
# the value argument.
141164
self._transaction = value
142165
span = self._span
143166
if span:

tests/test_tracing.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
import pytest
55

6-
from sentry_sdk import Hub, capture_message
6+
from sentry_sdk import Hub, capture_message, start_span
77
from sentry_sdk.tracing import Span
88

99

@@ -180,3 +180,17 @@ def before_send(event, hint):
180180
pass
181181

182182
assert len(events) == 1
183+
184+
185+
def test_get_transaction_from_scope(sentry_init, capture_events):
186+
sentry_init(traces_sample_rate=1.0)
187+
events = capture_events()
188+
189+
with start_span(transaction="/"):
190+
with start_span(op="child-span"):
191+
with start_span(op="child-child-span"):
192+
scope = Hub.current.scope
193+
assert scope.span.op == "child-child-span"
194+
assert scope.transaction.transaction == "/"
195+
196+
assert len(events) == 1

0 commit comments

Comments
 (0)