Skip to content

Commit 7f14b64

Browse files
feat(scope): Replace transaction with root_span
Closes #4235
1 parent 32369cb commit 7f14b64

File tree

12 files changed

+38
-23
lines changed

12 files changed

+38
-23
lines changed

MIGRATION_GUIDE.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ Looking to upgrade from Sentry SDK 2.x to 3.x? Here's a comprehensive list of wh
162162
- `same_process_as_parent`
163163
- `span_id`
164164
- `parent_span_id`: you can supply a `parent_span` instead
165-
- Setting `Scope.transaction` directly is no longer supported. Use `Scope.set_transaction_name()` instead.
165+
- The `Scope.transaction` property has been removed. To obtain the root span, use `Scope.root_span`. To set the root span's name, use `Scope.set_transaction_name()`.
166166
- Passing a list or `None` for `failed_request_status_codes` in the Starlette integration is no longer supported. Pass a set of integers instead.
167167
- The `span` argument of `Scope.trace_propagation_meta` is no longer supported.
168168
- Setting `Scope.user` directly is no longer supported. Use `Scope.set_user()` instead.

sentry_sdk/api.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@ def start_transaction(
299299

300300
def set_measurement(name, value, unit=""):
301301
# type: (str, float, MeasurementUnit) -> None
302-
transaction = get_current_scope().transaction
302+
transaction = get_current_scope().root_span
303303
if transaction is not None:
304304
transaction.set_measurement(name, value, unit)
305305

sentry_sdk/client.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -850,7 +850,7 @@ def _capture_experimental_log(self, current_scope, log):
850850
log["attributes"]["sentry.trace.parent_span_id"] = span.span_id
851851

852852
if log.get("trace_id") is None:
853-
transaction = current_scope.transaction
853+
transaction = current_scope.root_span
854854
propagation_context = isolation_scope.get_active_propagation_context()
855855
if transaction is not None:
856856
log["trace_id"] = transaction.trace_id

sentry_sdk/integrations/arq.py

+5-5
Original file line numberDiff line numberDiff line change
@@ -127,12 +127,12 @@ def _capture_exception(exc_info):
127127
# type: (ExcInfo) -> None
128128
scope = sentry_sdk.get_current_scope()
129129

130-
if scope.transaction is not None:
130+
if scope.root_span is not None:
131131
if exc_info[0] in ARQ_CONTROL_FLOW_EXCEPTIONS:
132-
scope.transaction.set_status(SPANSTATUS.ABORTED)
132+
scope.root_span.set_status(SPANSTATUS.ABORTED)
133133
return
134134

135-
scope.transaction.set_status(SPANSTATUS.INTERNAL_ERROR)
135+
scope.root_span.set_status(SPANSTATUS.INTERNAL_ERROR)
136136

137137
event, hint = event_from_exception(
138138
exc_info,
@@ -149,8 +149,8 @@ def event_processor(event, hint):
149149

150150
with capture_internal_exceptions():
151151
scope = sentry_sdk.get_current_scope()
152-
if scope.transaction is not None:
153-
scope.transaction.name = ctx["job_name"]
152+
if scope.root_span is not None:
153+
scope.root_span.name = ctx["job_name"]
154154
event["transaction"] = ctx["job_name"]
155155

156156
tags = event.setdefault("tags", {})

sentry_sdk/integrations/django/asgi.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -176,8 +176,8 @@ def wrap_async_view(callback):
176176
async def sentry_wrapped_callback(request, *args, **kwargs):
177177
# type: (Any, *Any, **Any) -> Any
178178
current_scope = sentry_sdk.get_current_scope()
179-
if current_scope.transaction is not None:
180-
current_scope.transaction.update_active_thread()
179+
if current_scope.root_span is not None:
180+
current_scope.root_span.update_active_thread()
181181

182182
sentry_scope = sentry_sdk.get_isolation_scope()
183183
if sentry_scope.profile is not None:

sentry_sdk/integrations/django/views.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,8 @@ def _wrap_sync_view(callback):
7979
def sentry_wrapped_callback(request, *args, **kwargs):
8080
# type: (Any, *Any, **Any) -> Any
8181
current_scope = sentry_sdk.get_current_scope()
82-
if current_scope.transaction is not None:
83-
current_scope.transaction.update_active_thread()
82+
if current_scope.root_span is not None:
83+
current_scope.root_span.update_active_thread()
8484

8585
sentry_scope = sentry_sdk.get_isolation_scope()
8686
# set the active thread id to the handler thread for sync views

sentry_sdk/integrations/fastapi.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,8 @@ def _sentry_get_request_handler(*args, **kwargs):
8989
def _sentry_call(*args, **kwargs):
9090
# type: (*Any, **Any) -> Any
9191
current_scope = sentry_sdk.get_current_scope()
92-
if current_scope.transaction is not None:
93-
current_scope.transaction.update_active_thread()
92+
if current_scope.root_span is not None:
93+
current_scope.root_span.update_active_thread()
9494

9595
sentry_scope = sentry_sdk.get_isolation_scope()
9696
if sentry_scope.profile is not None:

sentry_sdk/integrations/huey.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -111,10 +111,10 @@ def _capture_exception(exc_info):
111111
scope = sentry_sdk.get_current_scope()
112112

113113
if exc_info[0] in HUEY_CONTROL_FLOW_EXCEPTIONS:
114-
scope.transaction.set_status(SPANSTATUS.ABORTED)
114+
scope.root_span.set_status(SPANSTATUS.ABORTED)
115115
return
116116

117-
scope.transaction.set_status(SPANSTATUS.INTERNAL_ERROR)
117+
scope.root_span.set_status(SPANSTATUS.INTERNAL_ERROR)
118118
event, hint = event_from_exception(
119119
exc_info,
120120
client_options=sentry_sdk.get_client().options,
@@ -136,7 +136,7 @@ def _sentry_execute(*args, **kwargs):
136136
_capture_exception(exc_info)
137137
reraise(*exc_info)
138138
else:
139-
sentry_sdk.get_current_scope().transaction.set_status(SPANSTATUS.OK)
139+
sentry_sdk.get_current_scope().root_span.set_status(SPANSTATUS.OK)
140140

141141
return result
142142

sentry_sdk/integrations/quart.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,8 @@ def decorator(old_func):
122122
def _sentry_func(*args, **kwargs):
123123
# type: (*Any, **Any) -> Any
124124
current_scope = sentry_sdk.get_current_scope()
125-
if current_scope.transaction is not None:
126-
current_scope.transaction.update_active_thread()
125+
if current_scope.root_span is not None:
126+
current_scope.root_span.update_active_thread()
127127

128128
sentry_scope = sentry_sdk.get_isolation_scope()
129129
if sentry_scope.profile is not None:

sentry_sdk/integrations/starlette.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -477,8 +477,8 @@ def _sentry_sync_func(*args, **kwargs):
477477
return old_func(*args, **kwargs)
478478

479479
current_scope = sentry_sdk.get_current_scope()
480-
if current_scope.transaction is not None:
481-
current_scope.transaction.update_active_thread()
480+
if current_scope.root_span is not None:
481+
current_scope.root_span.update_active_thread()
482482

483483
sentry_scope = sentry_sdk.get_isolation_scope()
484484
if sentry_scope.profile is not None:

sentry_sdk/scope.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -688,10 +688,10 @@ def fingerprint(self, value):
688688
self._fingerprint = value
689689

690690
@property
691-
def transaction(self):
691+
def root_span(self):
692692
# type: () -> Any
693693
# would be type: () -> Optional[Span], see https://github.com/python/mypy/issues/3004
694-
"""Return the transaction (root span) in the scope, if any."""
694+
"""Return the root span in the scope, if any."""
695695

696696
# there is no span/transaction on the scope
697697
if self._span is None:

tests/test_scope.py

+15
Original file line numberDiff line numberDiff line change
@@ -915,3 +915,18 @@ def test_last_event_id_cleared(sentry_init):
915915
Scope.get_isolation_scope().clear()
916916

917917
assert Scope.last_event_id() is None, "last_event_id should be cleared"
918+
919+
920+
def test_root_span(sentry_init):
921+
sentry_init(traces_sample_rate=1.0)
922+
923+
assert sentry_sdk.get_current_scope().root_span is None
924+
925+
with sentry_sdk.start_span(name="test") as root_span:
926+
assert sentry_sdk.get_current_scope().root_span == root_span
927+
with sentry_sdk.start_span(name="child"):
928+
assert sentry_sdk.get_current_scope().root_span == root_span
929+
with sentry_sdk.start_span(name="grandchild"):
930+
assert sentry_sdk.get_current_scope().root_span == root_span
931+
932+
assert sentry_sdk.get_current_scope().root_span is None

0 commit comments

Comments
 (0)