Skip to content

Commit 644bfa8

Browse files
authored
fix(tracing): Make unsampled transactions findable on the scope (getsentry#872)
1 parent 5bb6ffc commit 644bfa8

File tree

2 files changed

+33
-7
lines changed

2 files changed

+33
-7
lines changed

sentry_sdk/scope.py

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -144,14 +144,26 @@ def fingerprint(self, value):
144144
def transaction(self):
145145
# type: () -> Any
146146
# would be type: () -> Optional[Transaction], see https://github.com/python/mypy/issues/3004
147-
"""Return the transaction (root span) in the scope."""
148-
if self._span is None or self._span._span_recorder is None:
149-
return None
150-
try:
151-
return self._span._span_recorder.spans[0]
152-
except (AttributeError, IndexError):
147+
"""Return the transaction (root span) in the scope, if any."""
148+
149+
# there is no span/transaction on the scope
150+
if self._span is None:
153151
return None
154152

153+
# the span on the scope is itself a transaction
154+
if isinstance(self._span, Transaction):
155+
return self._span
156+
157+
# the span on the scope isn't a transaction but belongs to one
158+
if self._span._containing_transaction:
159+
return self._span._containing_transaction
160+
161+
# there's a span (not a transaction) on the scope, but it was started on
162+
# its own, not as the descendant of a transaction (this is deprecated
163+
# behavior, but as long as the start_span function exists, it can still
164+
# happen)
165+
return None
166+
155167
@transaction.setter
156168
def transaction(self, value):
157169
# type: (Any) -> None

tests/tracing/test_sampling.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import pytest
22

3-
from sentry_sdk import start_span, start_transaction
3+
from sentry_sdk import Hub, start_span, start_transaction
44
from sentry_sdk.tracing import _is_valid_sample_rate
55
from sentry_sdk.utils import logger
66

@@ -73,3 +73,17 @@ def test_warns_on_invalid_sample_rate(rate, StringContaining): # noqa: N803
7373
result = _is_valid_sample_rate(rate)
7474
logger.warning.assert_any_call(StringContaining("Given sample rate is invalid"))
7575
assert result is False
76+
77+
78+
@pytest.mark.parametrize("sampling_decision", [True, False])
79+
def test_get_transaction_and_span_from_scope_regardless_of_sampling_decision(
80+
sentry_init, sampling_decision
81+
):
82+
sentry_init(traces_sample_rate=1.0)
83+
84+
with start_transaction(name="/", sampled=sampling_decision):
85+
with start_span(op="child-span"):
86+
with start_span(op="child-child-span"):
87+
scope = Hub.current.scope
88+
assert scope.span.op == "child-child-span"
89+
assert scope.transaction.name == "/"

0 commit comments

Comments
 (0)