Skip to content

Commit 9487038

Browse files
authored
(1) Move add_breadcrumb and session function from Hub to Scope (#2578)
Moved some functionality from Hub to Scope or Client: - moved `add_breadcrumb` from Hub to Scope - moved session functions from Hub to Scope - moved `get_integration1` from Hub to Client. This is preparation work for refactoring how we deal with Hubs and Scopes in the future. Each commit is moving one function, so it should be easy to review commit by commit.
1 parent 4108662 commit 9487038

File tree

3 files changed

+124
-56
lines changed

3 files changed

+124
-56
lines changed

sentry_sdk/client.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,10 @@
4343
from typing import Dict
4444
from typing import Optional
4545
from typing import Sequence
46+
from typing import Type
47+
from typing import Union
4648

49+
from sentry_sdk.integrations import Integration
4750
from sentry_sdk.scope import Scope
4851
from sentry_sdk._types import Event, Hint
4952
from sentry_sdk.session import Session
@@ -653,6 +656,22 @@ def capture_session(
653656
else:
654657
self.session_flusher.add_session(session)
655658

659+
def get_integration(
660+
self, name_or_class # type: Union[str, Type[Integration]]
661+
):
662+
# type: (...) -> Any
663+
"""Returns the integration for this client by name or class.
664+
If the client does not have that integration then `None` is returned.
665+
"""
666+
if isinstance(name_or_class, str):
667+
integration_name = name_or_class
668+
elif name_or_class.identifier is not None:
669+
integration_name = name_or_class.identifier
670+
else:
671+
raise ValueError("Integration has no name")
672+
673+
return self.integrations.get(integration_name)
674+
656675
def close(
657676
self,
658677
timeout=None, # type: Optional[float]

sentry_sdk/hub.py

Lines changed: 10 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
from contextlib import contextmanager
55

6-
from sentry_sdk._compat import datetime_utcnow, with_metaclass
6+
from sentry_sdk._compat import with_metaclass
77
from sentry_sdk.consts import INSTRUMENTER
88
from sentry_sdk.scope import Scope
99
from sentry_sdk.client import Client
@@ -15,7 +15,6 @@
1515
BAGGAGE_HEADER_NAME,
1616
SENTRY_TRACE_HEADER_NAME,
1717
)
18-
from sentry_sdk.session import Session
1918
from sentry_sdk.tracing_utils import (
2019
has_tracing_enabled,
2120
normalize_incoming_data,
@@ -294,18 +293,9 @@ def get_integration(
294293
If the return value is not `None` the hub is guaranteed to have a
295294
client attached.
296295
"""
297-
if isinstance(name_or_class, str):
298-
integration_name = name_or_class
299-
elif name_or_class.identifier is not None:
300-
integration_name = name_or_class.identifier
301-
else:
302-
raise ValueError("Integration has no name")
303-
304296
client = self.client
305297
if client is not None:
306-
rv = client.integrations.get(integration_name)
307-
if rv is not None:
308-
return rv
298+
return client.get_integration(name_or_class)
309299

310300
@property
311301
def client(self):
@@ -430,31 +420,9 @@ def add_breadcrumb(self, crumb=None, hint=None, **kwargs):
430420
logger.info("Dropped breadcrumb because no client bound")
431421
return
432422

433-
crumb = dict(crumb or ()) # type: Breadcrumb
434-
crumb.update(kwargs)
435-
if not crumb:
436-
return
437-
438-
hint = dict(hint or ()) # type: Hint
439-
440-
if crumb.get("timestamp") is None:
441-
crumb["timestamp"] = datetime_utcnow()
442-
if crumb.get("type") is None:
443-
crumb["type"] = "default"
444-
445-
if client.options["before_breadcrumb"] is not None:
446-
new_crumb = client.options["before_breadcrumb"](crumb, hint)
447-
else:
448-
new_crumb = crumb
449-
450-
if new_crumb is not None:
451-
scope._breadcrumbs.append(new_crumb)
452-
else:
453-
logger.info("before breadcrumb dropped breadcrumb (%s)", crumb)
423+
kwargs["client"] = client
454424

455-
max_breadcrumbs = client.options["max_breadcrumbs"] # type: int
456-
while len(scope._breadcrumbs) > max_breadcrumbs:
457-
scope._breadcrumbs.popleft()
425+
scope.add_breadcrumb(crumb, hint, **kwargs)
458426

459427
def start_span(self, span=None, instrumenter=INSTRUMENTER.SENTRY, **kwargs):
460428
# type: (Optional[Span], str, Any) -> Span
@@ -712,26 +680,17 @@ def start_session(
712680
):
713681
# type: (...) -> None
714682
"""Starts a new session."""
715-
self.end_session()
716683
client, scope = self._stack[-1]
717-
scope._session = Session(
718-
release=client.options["release"] if client else None,
719-
environment=client.options["environment"] if client else None,
720-
user=scope._user,
684+
scope.start_session(
685+
client=client,
721686
session_mode=session_mode,
722687
)
723688

724689
def end_session(self):
725690
# type: (...) -> None
726691
"""Ends the current session if there is one."""
727692
client, scope = self._stack[-1]
728-
session = scope._session
729-
self.scope._session = None
730-
731-
if session is not None:
732-
session.close()
733-
if client is not None:
734-
client.capture_session(session)
693+
scope.end_session(client=client)
735694

736695
def stop_auto_session_tracking(self):
737696
# type: (...) -> None
@@ -740,18 +699,17 @@ def stop_auto_session_tracking(self):
740699
This temporarily session tracking for the current scope when called.
741700
To resume session tracking call `resume_auto_session_tracking`.
742701
"""
743-
self.end_session()
744702
client, scope = self._stack[-1]
745-
scope._force_auto_session_tracking = False
703+
scope.stop_auto_session_tracking(client=client)
746704

747705
def resume_auto_session_tracking(self):
748706
# type: (...) -> None
749707
"""Resumes automatic session tracking for the current scope if
750708
disabled earlier. This requires that generally automatic session
751709
tracking is enabled.
752710
"""
753-
client, scope = self._stack[-1]
754-
scope._force_auto_session_tracking = None
711+
scope = self._stack[-1][1]
712+
scope.resume_auto_session_tracking()
755713

756714
def flush(
757715
self,

sentry_sdk/scope.py

Lines changed: 95 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@
55
import uuid
66

77
from sentry_sdk.attachments import Attachment
8+
from sentry_sdk._compat import datetime_utcnow
9+
from sentry_sdk.consts import FALSE_VALUES
810
from sentry_sdk._functools import wraps
11+
from sentry_sdk.session import Session
912
from sentry_sdk.tracing_utils import (
1013
Baggage,
1114
extract_sentrytrace_data,
@@ -20,9 +23,6 @@
2023
from sentry_sdk._types import TYPE_CHECKING
2124
from sentry_sdk.utils import logger, capture_internal_exceptions
2225

23-
from sentry_sdk.consts import FALSE_VALUES
24-
25-
2626
if TYPE_CHECKING:
2727
from typing import Any
2828
from typing import Dict
@@ -36,6 +36,7 @@
3636

3737
from sentry_sdk._types import (
3838
Breadcrumb,
39+
BreadcrumbHint,
3940
Event,
4041
EventProcessor,
4142
ErrorProcessor,
@@ -46,7 +47,6 @@
4647

4748
from sentry_sdk.profiler import Profile
4849
from sentry_sdk.tracing import Span
49-
from sentry_sdk.session import Session
5050

5151
F = TypeVar("F", bound=Callable[..., Any])
5252
T = TypeVar("T")
@@ -517,6 +517,97 @@ def add_attachment(
517517
)
518518
)
519519

520+
def add_breadcrumb(self, crumb=None, hint=None, **kwargs):
521+
# type: (Optional[Breadcrumb], Optional[BreadcrumbHint], Any) -> None
522+
"""
523+
Adds a breadcrumb.
524+
525+
:param crumb: Dictionary with the data as the sentry v7/v8 protocol expects.
526+
527+
:param hint: An optional value that can be used by `before_breadcrumb`
528+
to customize the breadcrumbs that are emitted.
529+
"""
530+
client = kwargs.pop("client", None)
531+
if client is None:
532+
return
533+
534+
before_breadcrumb = client.options.get("before_breadcrumb")
535+
max_breadcrumbs = client.options.get("max_breadcrumbs")
536+
537+
crumb = dict(crumb or ()) # type: Breadcrumb
538+
crumb.update(kwargs)
539+
if not crumb:
540+
return
541+
542+
hint = dict(hint or ()) # type: Hint
543+
544+
if crumb.get("timestamp") is None:
545+
crumb["timestamp"] = datetime_utcnow()
546+
if crumb.get("type") is None:
547+
crumb["type"] = "default"
548+
549+
if before_breadcrumb is not None:
550+
new_crumb = before_breadcrumb(crumb, hint)
551+
else:
552+
new_crumb = crumb
553+
554+
if new_crumb is not None:
555+
self._breadcrumbs.append(new_crumb)
556+
else:
557+
logger.info("before breadcrumb dropped breadcrumb (%s)", crumb)
558+
559+
while len(self._breadcrumbs) > max_breadcrumbs:
560+
self._breadcrumbs.popleft()
561+
562+
def start_session(self, *args, **kwargs):
563+
# type: (*Any, **Any) -> None
564+
"""Starts a new session."""
565+
client = kwargs.pop("client", None)
566+
session_mode = kwargs.pop("session_mode", "application")
567+
568+
self.end_session(client=client)
569+
570+
self._session = Session(
571+
release=client.options["release"] if client else None,
572+
environment=client.options["environment"] if client else None,
573+
user=self._user,
574+
session_mode=session_mode,
575+
)
576+
577+
def end_session(self, *args, **kwargs):
578+
# type: (*Any, **Any) -> None
579+
"""Ends the current session if there is one."""
580+
client = kwargs.pop("client", None)
581+
582+
session = self._session
583+
self._session = None
584+
585+
if session is not None:
586+
session.close()
587+
if client is not None:
588+
client.capture_session(session)
589+
590+
def stop_auto_session_tracking(self, *args, **kwargs):
591+
# type: (*Any, **Any) -> None
592+
"""Stops automatic session tracking.
593+
594+
This temporarily session tracking for the current scope when called.
595+
To resume session tracking call `resume_auto_session_tracking`.
596+
"""
597+
client = kwargs.pop("client", None)
598+
599+
self.end_session(client=client)
600+
601+
self._force_auto_session_tracking = False
602+
603+
def resume_auto_session_tracking(self):
604+
# type: (...) -> None
605+
"""Resumes automatic session tracking for the current scope if
606+
disabled earlier. This requires that generally automatic session
607+
tracking is enabled.
608+
"""
609+
self._force_auto_session_tracking = None
610+
520611
def add_event_processor(
521612
self, func # type: EventProcessor
522613
):

0 commit comments

Comments
 (0)