Skip to content

feat(scope): Add last_event_id to Scope #3064

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
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
1 change: 1 addition & 0 deletions sentry_sdk/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
"get_traceparent",
"is_initialized",
"isolation_scope",
"last_event_id",
"new_scope",
"push_scope",
"set_context",
Expand Down
11 changes: 11 additions & 0 deletions sentry_sdk/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ def overload(x):
"get_traceparent",
"is_initialized",
"isolation_scope",
"last_event_id",
"new_scope",
"push_scope",
"set_context",
Expand Down Expand Up @@ -332,6 +333,16 @@ def start_transaction(
)


@scopemethod
def last_event_id():
# type: () -> Optional[str]
"""
See :py:meth:`sentry_sdk.Scope.last_event_id` documentation regarding
this method's limitations.
"""
return Scope.last_event_id()


def set_measurement(name, value, unit=""):
# type: (str, float, MeasurementUnit) -> None
transaction = Scope.get_current_scope().transaction
Expand Down
28 changes: 27 additions & 1 deletion sentry_sdk/scope.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ class Scope(object):
"_propagation_context",
"client",
"_type",
"_last_event_id",
)

def __init__(self, ty=None, client=None):
Expand All @@ -207,6 +208,9 @@ def __init__(self, ty=None, client=None):
incoming_trace_information = self._load_trace_data_from_env()
self.generate_propagation_context(incoming_data=incoming_trace_information)

# self._last_event_id is only applicable to isolation scopes
self._last_event_id = None # type: Optional[str]

def __copy__(self):
# type: () -> Scope
"""
Expand Down Expand Up @@ -308,6 +312,23 @@ def get_global_scope(cls):

return _global_scope

@classmethod
def last_event_id(cls):
# type: () -> Optional[str]
"""
.. versionadded:: 2.2.0

Returns event ID of the event most recently captured by the isolation scope, or None if no event
has been captured. We do not consider events that are dropped, e.g. by a before_send hook.
Transactions also are not considered events in this context.

The event corresponding to the returned event ID is NOT guaranteed to actually be sent to Sentry;
whether the event is sent depends on the transport. The event could be sent later or not at all.
Even a sent event could fail to arrive in Sentry due to network issues, exhausted quotas, or
various other reasons.
"""
return cls.get_isolation_scope()._last_event_id

def _merge_scopes(self, additional_scope=None, additional_scope_kwargs=None):
# type: (Optional[Scope], Optional[Dict[str, Any]]) -> Scope
"""
Expand Down Expand Up @@ -1089,7 +1110,12 @@ def capture_event(self, event, hint=None, scope=None, **scope_kwargs):
"""
scope = self._merge_scopes(scope, scope_kwargs)

return Scope.get_client().capture_event(event=event, hint=hint, scope=scope)
event_id = Scope.get_client().capture_event(event=event, hint=hint, scope=scope)

if event_id is not None and event.get("type") != "transaction":
self.get_isolation_scope()._last_event_id = event_id

return event_id

def capture_message(self, message, level=None, scope=None, **scope_kwargs):
# type: (str, Optional[LogLevelStr], Optional[Scope], Any) -> Optional[str]
Expand Down
22 changes: 22 additions & 0 deletions tests/test_basics.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
capture_exception,
capture_message,
start_transaction,
last_event_id,
add_breadcrumb,
Hub,
Scope,
Expand Down Expand Up @@ -778,3 +779,24 @@ def test_classmethod_tracing(sentry_init):
with patch_start_tracing_child() as fake_start_child:
assert instance_or_class.class_(1) == (TracingTestClass, 1)
assert fake_start_child.call_count == 1


def test_last_event_id(sentry_init):
sentry_init(enable_tracing=True)

assert last_event_id() is None

capture_exception(Exception("test"))

assert last_event_id() is not None


def test_last_event_id_transaction(sentry_init):
sentry_init(enable_tracing=True)

assert last_event_id() is None

with start_transaction(name="test"):
pass

assert last_event_id() is None, "Transaction should not set last_event_id"
21 changes: 21 additions & 0 deletions tests/test_scope.py
Original file line number Diff line number Diff line change
Expand Up @@ -822,3 +822,24 @@ def test_set_tags():
"tag2": "updated",
"tag3": "new",
}, "Updating tags with empty dict changed tags"


def test_last_event_id(sentry_init):
sentry_init(enable_tracing=True)

assert Scope.last_event_id() is None

sentry_sdk.capture_exception(Exception("test"))

assert Scope.last_event_id() is not None


def test_last_event_id_transaction(sentry_init):
sentry_init(enable_tracing=True)

assert Scope.last_event_id() is None

with sentry_sdk.start_transaction(name="test"):
pass

assert Scope.last_event_id() is None, "Transaction should not set last_event_id"
Loading