Skip to content
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

(1) Move add_breadcrumb and session function from Hub to Scope #2578

Merged
merged 9 commits into from
Dec 11, 2023
19 changes: 19 additions & 0 deletions sentry_sdk/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,10 @@
from typing import Dict
from typing import Optional
from typing import Sequence
from typing import Type
from typing import Union

Check warning on line 47 in sentry_sdk/client.py

View check run for this annotation

Codecov / codecov/patch

sentry_sdk/client.py#L46-L47

Added lines #L46 - L47 were not covered by tests

from sentry_sdk.integrations import Integration

Check warning on line 49 in sentry_sdk/client.py

View check run for this annotation

Codecov / codecov/patch

sentry_sdk/client.py#L49

Added line #L49 was not covered by tests
from sentry_sdk.scope import Scope
from sentry_sdk._types import Event, Hint
from sentry_sdk.session import Session
Expand Down Expand Up @@ -653,6 +656,22 @@
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

Check warning on line 667 in sentry_sdk/client.py

View check run for this annotation

Codecov / codecov/patch

sentry_sdk/client.py#L667

Added line #L667 was not covered by tests
elif name_or_class.identifier is not None:
integration_name = name_or_class.identifier
else:
raise ValueError("Integration has no name")

Check warning on line 671 in sentry_sdk/client.py

View check run for this annotation

Codecov / codecov/patch

sentry_sdk/client.py#L671

Added line #L671 was not covered by tests

return self.integrations.get(integration_name)

def close(
self,
timeout=None, # type: Optional[float]
Expand Down
62 changes: 10 additions & 52 deletions sentry_sdk/hub.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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,
Expand Down Expand Up @@ -294,18 +293,9 @@
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):
Expand Down Expand Up @@ -430,31 +420,9 @@
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["client"] = client

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
Expand Down Expand Up @@ -712,26 +680,17 @@
):
# 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,
)

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
Expand All @@ -740,18 +699,17 @@
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)

Check warning on line 703 in sentry_sdk/hub.py

View check run for this annotation

Codecov / codecov/patch

sentry_sdk/hub.py#L703

Added line #L703 was not covered by tests

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.
"""
client, scope = self._stack[-1]
scope._force_auto_session_tracking = None
scope = self._stack[-1][1]
scope.resume_auto_session_tracking()

Check warning on line 712 in sentry_sdk/hub.py

View check run for this annotation

Codecov / codecov/patch

sentry_sdk/hub.py#L711-L712

Added lines #L711 - L712 were not covered by tests

def flush(
self,
Expand Down
99 changes: 95 additions & 4 deletions sentry_sdk/scope.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
import uuid

from sentry_sdk.attachments import Attachment
from sentry_sdk._compat import datetime_utcnow
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 (
Baggage,
extract_sentrytrace_data,
Expand All @@ -20,9 +23,6 @@
from sentry_sdk._types import TYPE_CHECKING
from sentry_sdk.utils import logger, capture_internal_exceptions

from sentry_sdk.consts import FALSE_VALUES


if TYPE_CHECKING:
from typing import Any
from typing import Dict
Expand All @@ -36,6 +36,7 @@

from sentry_sdk._types import (
Breadcrumb,
BreadcrumbHint,
Event,
EventProcessor,
ErrorProcessor,
Expand All @@ -46,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")
Expand Down Expand Up @@ -517,6 +517,97 @@
)
)

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.
"""
client = kwargs.pop("client", None)
if client is None:
return

Check warning on line 532 in sentry_sdk/scope.py

View check run for this annotation

Codecov / codecov/patch

sentry_sdk/scope.py#L532

Added line #L532 was not covered by tests

before_breadcrumb = client.options.get("before_breadcrumb")
max_breadcrumbs = client.options.get("max_breadcrumbs")

crumb = dict(crumb or ()) # type: Breadcrumb
crumb.update(kwargs)
if not crumb:
return

Check warning on line 540 in sentry_sdk/scope.py

View check run for this annotation

Codecov / codecov/patch

sentry_sdk/scope.py#L540

Added line #L540 was not covered by tests

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)

Check warning on line 550 in sentry_sdk/scope.py

View check run for this annotation

Codecov / codecov/patch

sentry_sdk/scope.py#L550

Added line #L550 was not covered by tests
else:
new_crumb = crumb

if new_crumb is not None:
self._breadcrumbs.append(new_crumb)
else:
logger.info("before breadcrumb dropped breadcrumb (%s)", crumb)

Check warning on line 557 in sentry_sdk/scope.py

View check run for this annotation

Codecov / codecov/patch

sentry_sdk/scope.py#L557

Added line #L557 was not covered by tests

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)

Check warning on line 597 in sentry_sdk/scope.py

View check run for this annotation

Codecov / codecov/patch

sentry_sdk/scope.py#L597

Added line #L597 was not covered by tests

self.end_session(client=client)

Check warning on line 599 in sentry_sdk/scope.py

View check run for this annotation

Codecov / codecov/patch

sentry_sdk/scope.py#L599

Added line #L599 was not covered by tests

self._force_auto_session_tracking = False

Check warning on line 601 in sentry_sdk/scope.py

View check run for this annotation

Codecov / codecov/patch

sentry_sdk/scope.py#L601

Added line #L601 was not covered by tests

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

Check warning on line 609 in sentry_sdk/scope.py

View check run for this annotation

Codecov / codecov/patch

sentry_sdk/scope.py#L609

Added line #L609 was not covered by tests

def add_event_processor(
self, func # type: EventProcessor
):
Expand Down
Loading