From f2a4a3aedf53126e747149f05bf7e5eef2e6f761 Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Wed, 29 Nov 2023 16:08:06 +0100 Subject: [PATCH 1/6] Moved get_integration from Hub to Client --- sentry_sdk/client.py | 19 +++++++++++++++++++ sentry_sdk/hub.py | 11 +---------- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/sentry_sdk/client.py b/sentry_sdk/client.py index 8aad751470..846fc0a7b6 100644 --- a/sentry_sdk/client.py +++ b/sentry_sdk/client.py @@ -43,7 +43,10 @@ from typing import Dict from typing import Optional from typing import Sequence + from typing import Type + from typing import Union + from sentry_sdk.integrations import Integration from sentry_sdk.scope import Scope from sentry_sdk._types import Event, Hint from sentry_sdk.session import Session @@ -653,6 +656,22 @@ def capture_session( else: self.session_flusher.add_session(session) + def get_integration( + self, name_or_class # type: Union[str, Type[Integration]] + ): + # type: (...) -> Any + """Returns the integration for this client by name or class. + If the client does not have that integration then `None` is returned. + """ + if isinstance(name_or_class, str): + integration_name = name_or_class + elif name_or_class.identifier is not None: + integration_name = name_or_class.identifier + else: + raise ValueError("Integration has no name") + + return self.integrations.get(integration_name) + def close( self, timeout=None, # type: Optional[float] diff --git a/sentry_sdk/hub.py b/sentry_sdk/hub.py index 2525dc56f1..5777704bb0 100644 --- a/sentry_sdk/hub.py +++ b/sentry_sdk/hub.py @@ -294,18 +294,9 @@ def get_integration( If the return value is not `None` the hub is guaranteed to have a client attached. """ - if isinstance(name_or_class, str): - integration_name = name_or_class - elif name_or_class.identifier is not None: - integration_name = name_or_class.identifier - else: - raise ValueError("Integration has no name") - client = self.client if client is not None: - rv = client.integrations.get(integration_name) - if rv is not None: - return rv + return client.get_integration(name_or_class) @property def client(self): From 4869365e344711032b8b5bf9cf369fc9dcf47478 Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Wed, 29 Nov 2023 16:22:03 +0100 Subject: [PATCH 2/6] Moved add_breadcrumb from Hub to Scope --- sentry_sdk/hub.py | 29 ++++------------------------- sentry_sdk/scope.py | 42 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 45 insertions(+), 26 deletions(-) diff --git a/sentry_sdk/hub.py b/sentry_sdk/hub.py index 5777704bb0..2a4ad8041f 100644 --- a/sentry_sdk/hub.py +++ b/sentry_sdk/hub.py @@ -3,7 +3,7 @@ from contextlib import contextmanager -from sentry_sdk._compat import datetime_utcnow, with_metaclass +from sentry_sdk._compat import with_metaclass from sentry_sdk.consts import INSTRUMENTER from sentry_sdk.scope import Scope from sentry_sdk.client import Client @@ -421,31 +421,10 @@ def add_breadcrumb(self, crumb=None, hint=None, **kwargs): logger.info("Dropped breadcrumb because no client bound") return - crumb = dict(crumb or ()) # type: Breadcrumb - crumb.update(kwargs) - if not crumb: - return - - hint = dict(hint or ()) # type: Hint - - if crumb.get("timestamp") is None: - crumb["timestamp"] = datetime_utcnow() - if crumb.get("type") is None: - crumb["type"] = "default" - - if client.options["before_breadcrumb"] is not None: - new_crumb = client.options["before_breadcrumb"](crumb, hint) - else: - new_crumb = crumb - - if new_crumb is not None: - scope._breadcrumbs.append(new_crumb) - else: - logger.info("before breadcrumb dropped breadcrumb (%s)", crumb) + kwargs["before_breadcrumb"] = client.options.get("before_breadcrumb") + kwargs["max_breadcrumbs"] = client.options.get("max_breadcrumbs") - max_breadcrumbs = client.options["max_breadcrumbs"] # type: int - while len(scope._breadcrumbs) > max_breadcrumbs: - scope._breadcrumbs.popleft() + scope.add_breadcrumb(crumb, hint, **kwargs) def start_span(self, span=None, instrumenter=INSTRUMENTER.SENTRY, **kwargs): # type: (Optional[Span], str, Any) -> Span diff --git a/sentry_sdk/scope.py b/sentry_sdk/scope.py index 5096eccce0..f3e5eb1f22 100644 --- a/sentry_sdk/scope.py +++ b/sentry_sdk/scope.py @@ -5,6 +5,7 @@ import uuid from sentry_sdk.attachments import Attachment +from sentry_sdk._compat import datetime_utcnow from sentry_sdk._functools import wraps from sentry_sdk.tracing_utils import ( Baggage, @@ -20,7 +21,7 @@ from sentry_sdk._types import TYPE_CHECKING from sentry_sdk.utils import logger, capture_internal_exceptions -from sentry_sdk.consts import FALSE_VALUES +from sentry_sdk.consts import DEFAULT_MAX_BREADCRUMBS, FALSE_VALUES if TYPE_CHECKING: @@ -36,6 +37,7 @@ from sentry_sdk._types import ( Breadcrumb, + BreadcrumbHint, Event, EventProcessor, ErrorProcessor, @@ -517,6 +519,44 @@ def add_attachment( ) ) + def add_breadcrumb(self, crumb=None, hint=None, **kwargs): + # type: (Optional[Breadcrumb], Optional[BreadcrumbHint], Any) -> None + """ + Adds a breadcrumb. + + :param crumb: Dictionary with the data as the sentry v7/v8 protocol expects. + + :param hint: An optional value that can be used by `before_breadcrumb` + to customize the breadcrumbs that are emitted. + """ + before_breadcrumb = kwargs.pop("before_breadcrumb") + max_breadcrumbs = kwargs.pop("max_breadcrumbs", DEFAULT_MAX_BREADCRUMBS) + + crumb = dict(crumb or ()) # type: Breadcrumb + crumb.update(kwargs) + if not crumb: + return + + hint = dict(hint or ()) # type: Hint + + if crumb.get("timestamp") is None: + crumb["timestamp"] = datetime_utcnow() + if crumb.get("type") is None: + crumb["type"] = "default" + + if before_breadcrumb is not None: + new_crumb = before_breadcrumb(crumb, hint) + else: + new_crumb = crumb + + if new_crumb is not None: + self._breadcrumbs.append(new_crumb) + else: + logger.info("before breadcrumb dropped breadcrumb (%s)", crumb) + + while len(self._breadcrumbs) > max_breadcrumbs: + self._breadcrumbs.popleft() + def add_event_processor( self, func # type: EventProcessor ): From e5f9e9d829405884f108eb07ff08a338e31230f3 Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Wed, 29 Nov 2023 16:46:51 +0100 Subject: [PATCH 3/6] Moved session functions from Hub to Scope --- sentry_sdk/hub.py | 23 +++++--------------- sentry_sdk/scope.py | 53 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 17 deletions(-) diff --git a/sentry_sdk/hub.py b/sentry_sdk/hub.py index 2a4ad8041f..380686c013 100644 --- a/sentry_sdk/hub.py +++ b/sentry_sdk/hub.py @@ -15,7 +15,6 @@ BAGGAGE_HEADER_NAME, SENTRY_TRACE_HEADER_NAME, ) -from sentry_sdk.session import Session from sentry_sdk.tracing_utils import ( has_tracing_enabled, normalize_incoming_data, @@ -682,12 +681,9 @@ def start_session( ): # type: (...) -> None """Starts a new session.""" - self.end_session() client, scope = self._stack[-1] - scope._session = Session( - release=client.options["release"] if client else None, - environment=client.options["environment"] if client else None, - user=scope._user, + scope.start_session( + client=client, session_mode=session_mode, ) @@ -695,13 +691,7 @@ def end_session(self): # type: (...) -> None """Ends the current session if there is one.""" client, scope = self._stack[-1] - session = scope._session - self.scope._session = None - - if session is not None: - session.close() - if client is not None: - client.capture_session(session) + scope.end_session(client=client) def stop_auto_session_tracking(self): # type: (...) -> None @@ -710,9 +700,8 @@ def stop_auto_session_tracking(self): This temporarily session tracking for the current scope when called. To resume session tracking call `resume_auto_session_tracking`. """ - self.end_session() client, scope = self._stack[-1] - scope._force_auto_session_tracking = False + scope.stop_auto_session_tracking(client=client) def resume_auto_session_tracking(self): # type: (...) -> None @@ -720,8 +709,8 @@ def resume_auto_session_tracking(self): disabled earlier. This requires that generally automatic session tracking is enabled. """ - client, scope = self._stack[-1] - scope._force_auto_session_tracking = None + scope = self._stack[-1][1] + scope.resume_auto_session_tracking() def flush( self, diff --git a/sentry_sdk/scope.py b/sentry_sdk/scope.py index f3e5eb1f22..422a9cf633 100644 --- a/sentry_sdk/scope.py +++ b/sentry_sdk/scope.py @@ -557,6 +557,59 @@ def add_breadcrumb(self, crumb=None, hint=None, **kwargs): while len(self._breadcrumbs) > max_breadcrumbs: self._breadcrumbs.popleft() + def start_session( + self, + *args, + **kwargs, + ): + # type: (*Any, **Any) -> None + """Starts a new session.""" + client = kwargs.pop("client", None) + session_mode = kwargs.pop("session_mode", "application") + + self.end_session(client=client) + + self._session = Session( + release=client.options["release"] if client else None, + environment=client.options["environment"] if client else None, + user=self._user, + session_mode=session_mode, + ) + + def end_session(self, *args, **kwargs): + # type: (*Any, **Any) -> None + """Ends the current session if there is one.""" + client = kwargs.pop("client", None) + + session = self._session + self._session = None + + if session is not None: + session.close() + if client is not None: + client.capture_session(session) + + def stop_auto_session_tracking(self, *args, **kwargs): + # type: (*Any, **Any) -> None + """Stops automatic session tracking. + + This temporarily session tracking for the current scope when called. + To resume session tracking call `resume_auto_session_tracking`. + """ + client = kwargs.pop("client", None) + + self.end_session(client=client) + + self._force_auto_session_tracking = False + + def resume_auto_session_tracking(self): + # type: (...) -> None + """Resumes automatic session tracking for the current scope if + disabled earlier. This requires that generally automatic session + tracking is enabled. + """ + self._force_auto_session_tracking = None + def add_event_processor( self, func # type: EventProcessor ): From a338099466ddd9ea9a8146f7918888a1e9a66381 Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Wed, 29 Nov 2023 16:55:26 +0100 Subject: [PATCH 4/6] Fixed import --- sentry_sdk/scope.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/sentry_sdk/scope.py b/sentry_sdk/scope.py index 422a9cf633..d1e4c53b46 100644 --- a/sentry_sdk/scope.py +++ b/sentry_sdk/scope.py @@ -6,7 +6,9 @@ from sentry_sdk.attachments import Attachment from sentry_sdk._compat import datetime_utcnow +from sentry_sdk.consts import DEFAULT_MAX_BREADCRUMBS, FALSE_VALUES from sentry_sdk._functools import wraps +from sentry_sdk.session import Session from sentry_sdk.tracing_utils import ( Baggage, extract_sentrytrace_data, @@ -21,9 +23,6 @@ from sentry_sdk._types import TYPE_CHECKING from sentry_sdk.utils import logger, capture_internal_exceptions -from sentry_sdk.consts import DEFAULT_MAX_BREADCRUMBS, FALSE_VALUES - - if TYPE_CHECKING: from typing import Any from typing import Dict @@ -48,7 +47,6 @@ from sentry_sdk.profiler import Profile from sentry_sdk.tracing import Span - from sentry_sdk.session import Session F = TypeVar("F", bound=Callable[..., Any]) T = TypeVar("T") From d900a1bda9a800e4bd70cfb7b8f9572717bfe2f6 Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Wed, 29 Nov 2023 17:04:34 +0100 Subject: [PATCH 5/6] Fixed Python 2.7 syntax --- sentry_sdk/scope.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/sentry_sdk/scope.py b/sentry_sdk/scope.py index d1e4c53b46..0fc836774a 100644 --- a/sentry_sdk/scope.py +++ b/sentry_sdk/scope.py @@ -555,11 +555,7 @@ def add_breadcrumb(self, crumb=None, hint=None, **kwargs): while len(self._breadcrumbs) > max_breadcrumbs: self._breadcrumbs.popleft() - def start_session( - self, - *args, - **kwargs, - ): + def start_session(self, *args, **kwargs): # type: (*Any, **Any) -> None """Starts a new session.""" client = kwargs.pop("client", None) From fe77d0499ec10077875e60ba112c25db8b7d2459 Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Fri, 1 Dec 2023 09:12:24 +0100 Subject: [PATCH 6/6] Give the client to the scope function. Want to establish a pattern. --- sentry_sdk/hub.py | 3 +-- sentry_sdk/scope.py | 10 +++++++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/sentry_sdk/hub.py b/sentry_sdk/hub.py index 380686c013..032ccd09e7 100644 --- a/sentry_sdk/hub.py +++ b/sentry_sdk/hub.py @@ -420,8 +420,7 @@ def add_breadcrumb(self, crumb=None, hint=None, **kwargs): logger.info("Dropped breadcrumb because no client bound") return - kwargs["before_breadcrumb"] = client.options.get("before_breadcrumb") - kwargs["max_breadcrumbs"] = client.options.get("max_breadcrumbs") + kwargs["client"] = client scope.add_breadcrumb(crumb, hint, **kwargs) diff --git a/sentry_sdk/scope.py b/sentry_sdk/scope.py index 0fc836774a..8e9724b4c5 100644 --- a/sentry_sdk/scope.py +++ b/sentry_sdk/scope.py @@ -6,7 +6,7 @@ from sentry_sdk.attachments import Attachment from sentry_sdk._compat import datetime_utcnow -from sentry_sdk.consts import DEFAULT_MAX_BREADCRUMBS, FALSE_VALUES +from sentry_sdk.consts import FALSE_VALUES from sentry_sdk._functools import wraps from sentry_sdk.session import Session from sentry_sdk.tracing_utils import ( @@ -527,8 +527,12 @@ def add_breadcrumb(self, crumb=None, hint=None, **kwargs): :param hint: An optional value that can be used by `before_breadcrumb` to customize the breadcrumbs that are emitted. """ - before_breadcrumb = kwargs.pop("before_breadcrumb") - max_breadcrumbs = kwargs.pop("max_breadcrumbs", DEFAULT_MAX_BREADCRUMBS) + client = kwargs.pop("client", None) + if client is None: + return + + before_breadcrumb = client.options.get("before_breadcrumb") + max_breadcrumbs = client.options.get("max_breadcrumbs") crumb = dict(crumb or ()) # type: Breadcrumb crumb.update(kwargs)