9
9
from sentry_sdk ._types import MYPY
10
10
11
11
if MYPY :
12
- from typing import Iterator
12
+ from typing import Callable
13
13
from typing import Dict
14
+ from typing import Iterator
14
15
from typing import List
15
16
from typing import Set
17
+ from typing import Tuple
16
18
from typing import Type
17
- from typing import Callable
18
19
19
20
20
21
_installer_lock = Lock ()
21
22
_installed_integrations = set () # type: Set[str]
22
23
23
24
24
- def _generate_default_integrations_iterator (* import_strings ):
25
- # type: (*str) -> Callable[[], Iterator[Type[Integration]]]
26
- def iter_default_integrations ():
27
- # type: () -> Iterator[Type[Integration]]
25
+ def _generate_default_integrations_iterator (integrations , auto_enabling_integrations ):
26
+ # type: (Tuple[str, ...], Tuple[str, ...]) -> Callable[[bool], Iterator[Type[Integration]]]
27
+
28
+ def iter_default_integrations (with_auto_enabling_integrations ):
29
+ # type: (bool) -> Iterator[Type[Integration]]
28
30
"""Returns an iterator of the default integration classes:
29
31
"""
30
32
from importlib import import_module
31
33
32
- for import_string in import_strings :
33
- module , cls = import_string .rsplit ("." , 1 )
34
- yield getattr (import_module (module ), cls )
34
+ if with_auto_enabling_integrations :
35
+ all_import_strings = integrations + auto_enabling_integrations
36
+ else :
37
+ all_import_strings = integrations
38
+
39
+ for import_string in all_import_strings :
40
+ try :
41
+ module , cls = import_string .rsplit ("." , 1 )
42
+ yield getattr (import_module (module ), cls )
43
+ except (DidNotEnable , SyntaxError ) as e :
44
+ logger .debug (
45
+ "Did not import default integration %s: %s" , import_string , e
46
+ )
35
47
36
48
if isinstance (iter_default_integrations .__doc__ , str ):
37
- for import_string in import_strings :
49
+ for import_string in integrations :
38
50
iter_default_integrations .__doc__ += "\n - `{}`" .format (import_string )
39
51
40
52
return iter_default_integrations
41
53
42
54
55
+ _AUTO_ENABLING_INTEGRATIONS = (
56
+ "sentry_sdk.integrations.django.DjangoIntegration" ,
57
+ "sentry_sdk.integrations.flask.FlaskIntegration" ,
58
+ "sentry_sdk.integrations.bottle.BottleIntegration" ,
59
+ "sentry_sdk.integrations.falcon.FalconIntegration" ,
60
+ "sentry_sdk.integrations.sanic.SanicIntegration" ,
61
+ "sentry_sdk.integrations.celery.CeleryIntegration" ,
62
+ "sentry_sdk.integrations.rq.RqIntegration" ,
63
+ "sentry_sdk.integrations.aiohttp.AioHttpIntegration" ,
64
+ "sentry_sdk.integrations.tornado.TornadoIntegration" ,
65
+ "sentry_sdk.integrations.sqlalchemy.SqlalchemyIntegration" ,
66
+ )
67
+
68
+
43
69
iter_default_integrations = _generate_default_integrations_iterator (
44
- "sentry_sdk.integrations.logging.LoggingIntegration" ,
45
- "sentry_sdk.integrations.stdlib.StdlibIntegration" ,
46
- "sentry_sdk.integrations.excepthook.ExcepthookIntegration" ,
47
- "sentry_sdk.integrations.dedupe.DedupeIntegration" ,
48
- "sentry_sdk.integrations.atexit.AtexitIntegration" ,
49
- "sentry_sdk.integrations.modules.ModulesIntegration" ,
50
- "sentry_sdk.integrations.argv.ArgvIntegration" ,
51
- "sentry_sdk.integrations.threading.ThreadingIntegration" ,
70
+ integrations = (
71
+ # stdlib/base runtime integrations
72
+ "sentry_sdk.integrations.logging.LoggingIntegration" ,
73
+ "sentry_sdk.integrations.stdlib.StdlibIntegration" ,
74
+ "sentry_sdk.integrations.excepthook.ExcepthookIntegration" ,
75
+ "sentry_sdk.integrations.dedupe.DedupeIntegration" ,
76
+ "sentry_sdk.integrations.atexit.AtexitIntegration" ,
77
+ "sentry_sdk.integrations.modules.ModulesIntegration" ,
78
+ "sentry_sdk.integrations.argv.ArgvIntegration" ,
79
+ "sentry_sdk.integrations.threading.ThreadingIntegration" ,
80
+ ),
81
+ auto_enabling_integrations = _AUTO_ENABLING_INTEGRATIONS ,
52
82
)
53
83
54
84
del _generate_default_integrations_iterator
55
85
56
86
57
- def setup_integrations (integrations , with_defaults = True ):
58
- # type: (List[Integration], bool) -> Dict[str, Integration]
87
+ def setup_integrations (
88
+ integrations , with_defaults = True , with_auto_enabling_integrations = False
89
+ ):
90
+ # type: (List[Integration], bool, bool) -> Dict[str, Integration]
59
91
"""Given a list of integration instances this installs them all. When
60
92
`with_defaults` is set to `True` then all default integrations are added
61
93
unless they were already provided before.
@@ -66,11 +98,17 @@ def setup_integrations(integrations, with_defaults=True):
66
98
67
99
logger .debug ("Setting up integrations (with default = %s)" , with_defaults )
68
100
101
+ # Integrations that are not explicitly set up by the user.
102
+ used_as_default_integration = set ()
103
+
69
104
if with_defaults :
70
- for integration_cls in iter_default_integrations ():
105
+ for integration_cls in iter_default_integrations (
106
+ with_auto_enabling_integrations
107
+ ):
71
108
if integration_cls .identifier not in integrations :
72
109
instance = integration_cls ()
73
110
integrations [instance .identifier ] = instance
111
+ used_as_default_integration .add (instance .identifier )
74
112
75
113
for identifier , integration in iteritems (integrations ):
76
114
with _installer_lock :
@@ -90,6 +128,14 @@ def setup_integrations(integrations, with_defaults=True):
90
128
integration .install ()
91
129
else :
92
130
raise
131
+ except DidNotEnable as e :
132
+ if identifier not in used_as_default_integration :
133
+ raise
134
+
135
+ logger .debug (
136
+ "Did not enable default integration %s: %s" , identifier , e
137
+ )
138
+
93
139
_installed_integrations .add (identifier )
94
140
95
141
for identifier in integrations :
@@ -98,6 +144,16 @@ def setup_integrations(integrations, with_defaults=True):
98
144
return integrations
99
145
100
146
147
+ class DidNotEnable (Exception ):
148
+ """
149
+ The integration could not be enabled due to a trivial user error like
150
+ `flask` not being installed for the `FlaskIntegration`.
151
+
152
+ This exception is silently swallowed for default integrations, but reraised
153
+ for explicitly enabled integrations.
154
+ """
155
+
156
+
101
157
class Integration (object ):
102
158
"""Baseclass for all integrations.
103
159
0 commit comments