5454#
5555# Note: Ignoring by logger name here is better than mucking with thread-locals.
5656# We do not necessarily know whether thread-locals work 100% correctly in the user's environment.
57+ #
58+ # Events/breadcrumbs and Sentry Logs have separate ignore lists so that
59+ # framework loggers silenced for events (e.g. django.server) can still be
60+ # captured as Sentry Logs.
5761_IGNORED_LOGGERS = set (
5862 ["sentry_sdk.errors" , "urllib3.connectionpool" , "urllib3.connection" ]
5963)
6064
65+ _IGNORED_LOGGERS_SENTRY_LOGS = set (
66+ ["sentry_sdk.errors" , "urllib3.connectionpool" , "urllib3.connection" ]
67+ )
68+
6169
6270def ignore_logger (
6371 name : str ,
@@ -67,11 +75,47 @@ def ignore_logger(
6775 use this to prevent their actions being recorded as breadcrumbs. Exposed
6876 to users as a way to quiet spammy loggers.
6977
78+ This does **not** affect Sentry Logs — use
79+ :py:func:`ignore_logger_for_sentry_logs` for that.
80+
7081 :param name: The name of the logger to ignore (same string you would pass to ``logging.getLogger``).
7182 """
7283 _IGNORED_LOGGERS .add (name )
7384
7485
86+ def ignore_logger_for_sentry_logs (
87+ name : str ,
88+ ) -> None :
89+ """This disables recording as Sentry Logs calls to a logger of a
90+ specific name.
91+
92+ :param name: The name of the logger to ignore (same string you would pass to ``logging.getLogger``).
93+ """
94+ _IGNORED_LOGGERS_SENTRY_LOGS .add (name )
95+
96+
97+ def unignore_logger (
98+ name : str ,
99+ ) -> None :
100+ """Reverts a previous :py:func:`ignore_logger` call, re-enabling
101+ recording of breadcrumbs and events for the named logger.
102+
103+ :param name: The name of the logger to unignore.
104+ """
105+ _IGNORED_LOGGERS .discard (name )
106+
107+
108+ def unignore_logger_for_sentry_logs (
109+ name : str ,
110+ ) -> None :
111+ """Reverts a previous :py:func:`ignore_logger_for_sentry_logs` call,
112+ re-enabling recording of Sentry Logs for the named logger.
113+
114+ :param name: The name of the logger to unignore.
115+ """
116+ _IGNORED_LOGGERS_SENTRY_LOGS .discard (name )
117+
118+
75119class LoggingIntegration (Integration ):
76120 identifier = "logging"
77121
@@ -104,6 +148,7 @@ def _handle_record(self, record: "LogRecord") -> None:
104148 ):
105149 self ._breadcrumb_handler .handle (record )
106150
151+ def _handle_sentry_logs_record (self , record : "LogRecord" ) -> None :
107152 if (
108153 self ._sentry_logs_handler is not None
109154 and record .levelno >= self ._sentry_logs_handler .level
@@ -118,6 +163,7 @@ def sentry_patched_callhandlers(self: "Any", record: "LogRecord") -> "Any":
118163 # keeping a local reference because the
119164 # global might be discarded on shutdown
120165 ignored_loggers = _IGNORED_LOGGERS
166+ ignored_loggers_sentry_logs = _IGNORED_LOGGERS_SENTRY_LOGS
121167
122168 try :
123169 return old_callhandlers (self , record )
@@ -126,15 +172,25 @@ def sentry_patched_callhandlers(self: "Any", record: "LogRecord") -> "Any":
126172 # the integration. Otherwise we have a high chance of getting
127173 # into a recursion error when the integration is resolved
128174 # (this also is slower).
129- if (
130- ignored_loggers is not None
131- and record .name .strip () not in ignored_loggers
132- ):
175+ name = record .name .strip ()
176+
177+ handle_events = (
178+ ignored_loggers is not None and name not in ignored_loggers
179+ )
180+ handle_sentry_logs = (
181+ ignored_loggers_sentry_logs is not None
182+ and name not in ignored_loggers_sentry_logs
183+ )
184+
185+ if handle_events or handle_sentry_logs :
133186 integration = sentry_sdk .get_client ().get_integration (
134187 LoggingIntegration
135188 )
136189 if integration is not None :
137- integration ._handle_record (record )
190+ if handle_events :
191+ integration ._handle_record (record )
192+ if handle_sentry_logs :
193+ integration ._handle_sentry_logs_record (record )
138194
139195 logging .Logger .callHandlers = sentry_patched_callhandlers # type: ignore
140196
@@ -170,13 +226,6 @@ class _BaseHandler(logging.Handler):
170226 )
171227 )
172228
173- def _can_record (self , record : "LogRecord" ) -> bool :
174- """Prevents ignored loggers from recording"""
175- for logger in _IGNORED_LOGGERS :
176- if fnmatch (record .name .strip (), logger ):
177- return False
178- return True
179-
180229 def _logging_to_event_level (self , record : "LogRecord" ) -> str :
181230 return LOGGING_TO_EVENT_LEVEL .get (
182231 record .levelno , record .levelname .lower () if record .levelname else ""
@@ -198,6 +247,13 @@ class EventHandler(_BaseHandler):
198247 Note that you do not have to use this class if the logging integration is enabled, which it is by default.
199248 """
200249
250+ def _can_record (self , record : "LogRecord" ) -> bool :
251+ """Prevents ignored loggers from recording"""
252+ for logger in _IGNORED_LOGGERS :
253+ if fnmatch (record .name .strip (), logger ):
254+ return False
255+ return True
256+
201257 def emit (self , record : "LogRecord" ) -> "Any" :
202258 with capture_internal_exceptions ():
203259 self .format (record )
@@ -290,6 +346,13 @@ class BreadcrumbHandler(_BaseHandler):
290346 Note that you do not have to use this class if the logging integration is enabled, which it is by default.
291347 """
292348
349+ def _can_record (self , record : "LogRecord" ) -> bool :
350+ """Prevents ignored loggers from recording"""
351+ for logger in _IGNORED_LOGGERS :
352+ if fnmatch (record .name .strip (), logger ):
353+ return False
354+ return True
355+
293356 def emit (self , record : "LogRecord" ) -> "Any" :
294357 with capture_internal_exceptions ():
295358 self .format (record )
@@ -321,6 +384,13 @@ class SentryLogsHandler(_BaseHandler):
321384 Note that you do not have to use this class if the logging integration is enabled, which it is by default.
322385 """
323386
387+ def _can_record (self , record : "LogRecord" ) -> bool :
388+ """Prevents ignored loggers from recording"""
389+ for logger in _IGNORED_LOGGERS_SENTRY_LOGS :
390+ if fnmatch (record .name .strip (), logger ):
391+ return False
392+ return True
393+
324394 def emit (self , record : "LogRecord" ) -> "Any" :
325395 with capture_internal_exceptions ():
326396 self .format (record )
0 commit comments