Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion MIGRATION_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ Looking to upgrade from Sentry SDK 2.x to 3.x? Here's a comprehensive list of wh
- `same_process_as_parent`
- `span_id`
- `parent_span_id`: you can supply a `parent_span` instead
- Setting `Scope.transaction` directly is no longer supported. Use `Scope.set_transaction_name()` instead.
- 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()`.
- Passing a list or `None` for `failed_request_status_codes` in the Starlette integration is no longer supported. Pass a set of integers instead.
- The `span` argument of `Scope.trace_propagation_meta` is no longer supported.
- Setting `Scope.user` directly is no longer supported. Use `Scope.set_user()` instead.
Expand Down
2 changes: 1 addition & 1 deletion sentry_sdk/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ def start_transaction(

def set_measurement(name, value, unit=""):
# type: (str, float, MeasurementUnit) -> None
transaction = get_current_scope().transaction
transaction = get_current_scope().root_span
if transaction is not None:
transaction.set_measurement(name, value, unit)

Expand Down
2 changes: 1 addition & 1 deletion sentry_sdk/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -858,7 +858,7 @@ def _capture_experimental_log(self, current_scope, log):
log["attributes"]["sentry.trace.parent_span_id"] = span.span_id

if log.get("trace_id") is None:
transaction = current_scope.transaction
transaction = current_scope.root_span
propagation_context = isolation_scope.get_active_propagation_context()
if transaction is not None:
log["trace_id"] = transaction.trace_id
Expand Down
10 changes: 5 additions & 5 deletions sentry_sdk/integrations/arq.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,12 +127,12 @@ def _capture_exception(exc_info):
# type: (ExcInfo) -> None
scope = sentry_sdk.get_current_scope()

if scope.transaction is not None:
if scope.root_span is not None:
if exc_info[0] in ARQ_CONTROL_FLOW_EXCEPTIONS:
scope.transaction.set_status(SPANSTATUS.ABORTED)
scope.root_span.set_status(SPANSTATUS.ABORTED)
return

scope.transaction.set_status(SPANSTATUS.INTERNAL_ERROR)
scope.root_span.set_status(SPANSTATUS.INTERNAL_ERROR)

event, hint = event_from_exception(
exc_info,
Expand All @@ -149,8 +149,8 @@ def event_processor(event, hint):

with capture_internal_exceptions():
scope = sentry_sdk.get_current_scope()
if scope.transaction is not None:
scope.transaction.name = ctx["job_name"]
if scope.root_span is not None:
scope.root_span.name = ctx["job_name"]
event["transaction"] = ctx["job_name"]

tags = event.setdefault("tags", {})
Expand Down
4 changes: 2 additions & 2 deletions sentry_sdk/integrations/django/asgi.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,8 +176,8 @@ def wrap_async_view(callback):
async def sentry_wrapped_callback(request, *args, **kwargs):
# type: (Any, *Any, **Any) -> Any
current_scope = sentry_sdk.get_current_scope()
if current_scope.transaction is not None:
current_scope.transaction.update_active_thread()
if current_scope.root_span is not None:
current_scope.root_span.update_active_thread()

sentry_scope = sentry_sdk.get_isolation_scope()
if sentry_scope.profile is not None:
Expand Down
4 changes: 2 additions & 2 deletions sentry_sdk/integrations/django/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,8 @@ def _wrap_sync_view(callback):
def sentry_wrapped_callback(request, *args, **kwargs):
# type: (Any, *Any, **Any) -> Any
current_scope = sentry_sdk.get_current_scope()
if current_scope.transaction is not None:
current_scope.transaction.update_active_thread()
if current_scope.root_span is not None:
current_scope.root_span.update_active_thread()

sentry_scope = sentry_sdk.get_isolation_scope()
# set the active thread id to the handler thread for sync views
Expand Down
4 changes: 2 additions & 2 deletions sentry_sdk/integrations/fastapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,8 @@ def _sentry_get_request_handler(*args, **kwargs):
def _sentry_call(*args, **kwargs):
# type: (*Any, **Any) -> Any
current_scope = sentry_sdk.get_current_scope()
if current_scope.transaction is not None:
current_scope.transaction.update_active_thread()
if current_scope.root_span is not None:
current_scope.root_span.update_active_thread()

sentry_scope = sentry_sdk.get_isolation_scope()
if sentry_scope.profile is not None:
Expand Down
6 changes: 3 additions & 3 deletions sentry_sdk/integrations/huey.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,10 +111,10 @@ def _capture_exception(exc_info):
scope = sentry_sdk.get_current_scope()

if exc_info[0] in HUEY_CONTROL_FLOW_EXCEPTIONS:
scope.transaction.set_status(SPANSTATUS.ABORTED)
scope.root_span.set_status(SPANSTATUS.ABORTED)
return

scope.transaction.set_status(SPANSTATUS.INTERNAL_ERROR)
scope.root_span.set_status(SPANSTATUS.INTERNAL_ERROR)
event, hint = event_from_exception(
exc_info,
client_options=sentry_sdk.get_client().options,
Expand All @@ -136,7 +136,7 @@ def _sentry_execute(*args, **kwargs):
_capture_exception(exc_info)
reraise(*exc_info)
else:
sentry_sdk.get_current_scope().transaction.set_status(SPANSTATUS.OK)
sentry_sdk.get_current_scope().root_span.set_status(SPANSTATUS.OK)

return result

Expand Down
4 changes: 2 additions & 2 deletions sentry_sdk/integrations/quart.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,8 @@ def decorator(old_func):
def _sentry_func(*args, **kwargs):
# type: (*Any, **Any) -> Any
current_scope = sentry_sdk.get_current_scope()
if current_scope.transaction is not None:
current_scope.transaction.update_active_thread()
if current_scope.root_span is not None:
current_scope.root_span.update_active_thread()

sentry_scope = sentry_sdk.get_isolation_scope()
if sentry_scope.profile is not None:
Expand Down
4 changes: 2 additions & 2 deletions sentry_sdk/integrations/starlette.py
Original file line number Diff line number Diff line change
Expand Up @@ -477,8 +477,8 @@ def _sentry_sync_func(*args, **kwargs):
return old_func(*args, **kwargs)

current_scope = sentry_sdk.get_current_scope()
if current_scope.transaction is not None:
current_scope.transaction.update_active_thread()
if current_scope.root_span is not None:
current_scope.root_span.update_active_thread()

sentry_scope = sentry_sdk.get_isolation_scope()
if sentry_scope.profile is not None:
Expand Down
4 changes: 2 additions & 2 deletions sentry_sdk/scope.py
Original file line number Diff line number Diff line change
Expand Up @@ -688,10 +688,10 @@ def fingerprint(self, value):
self._fingerprint = value

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

# there is no span/transaction on the scope
if self._span is None:
Expand Down
15 changes: 15 additions & 0 deletions tests/test_scope.py
Original file line number Diff line number Diff line change
Expand Up @@ -915,3 +915,18 @@ def test_last_event_id_cleared(sentry_init):
Scope.get_isolation_scope().clear()

assert Scope.last_event_id() is None, "last_event_id should be cleared"


def test_root_span(sentry_init):
sentry_init(traces_sample_rate=1.0)

assert sentry_sdk.get_current_scope().root_span is None

with sentry_sdk.start_span(name="test") as root_span:
assert sentry_sdk.get_current_scope().root_span == root_span
with sentry_sdk.start_span(name="child"):
assert sentry_sdk.get_current_scope().root_span == root_span
with sentry_sdk.start_span(name="grandchild"):
assert sentry_sdk.get_current_scope().root_span == root_span

assert sentry_sdk.get_current_scope().root_span is None
Loading