55
66import sentry_sdk
77from sentry_sdk .client import BaseClient
8+ from sentry_sdk .logger import _log_level_to_otel
89from sentry_sdk .utils import (
910 safe_repr ,
1011 to_string ,
1415)
1516from sentry_sdk .integrations import Integration
1617
17- from typing import TYPE_CHECKING , Tuple
18+ from typing import TYPE_CHECKING
1819
1920if TYPE_CHECKING :
2021 from collections .abc import MutableMapping
3637 logging .CRITICAL : "fatal" , # CRITICAL is same as FATAL
3738}
3839
40+ # Map logging level numbers to corresponding OTel level numbers
41+ SEVERITY_TO_OTEL_SEVERITY = {
42+ logging .CRITICAL : 21 , # fatal
43+ logging .ERROR : 17 , # error
44+ logging .WARNING : 13 , # warn
45+ logging .INFO : 9 , # info
46+ logging .DEBUG : 5 , # debug
47+ }
48+
49+
3950# Capturing events from those loggers causes recursion errors. We cannot allow
4051# the user to unconditionally create events from those loggers under any
4152# circumstances.
@@ -119,7 +130,10 @@ def sentry_patched_callhandlers(self, record):
119130 # the integration. Otherwise we have a high chance of getting
120131 # into a recursion error when the integration is resolved
121132 # (this also is slower).
122- if ignored_loggers is not None and record .name not in ignored_loggers :
133+ if (
134+ ignored_loggers is not None
135+ and record .name .strip () not in ignored_loggers
136+ ):
123137 integration = sentry_sdk .get_client ().get_integration (
124138 LoggingIntegration
125139 )
@@ -164,7 +178,7 @@ def _can_record(self, record):
164178 # type: (LogRecord) -> bool
165179 """Prevents ignored loggers from recording"""
166180 for logger in _IGNORED_LOGGERS :
167- if fnmatch (record .name , logger ):
181+ if fnmatch (record .name . strip () , logger ):
168182 return False
169183 return True
170184
@@ -312,21 +326,6 @@ def _breadcrumb_from_record(self, record):
312326 }
313327
314328
315- def _python_level_to_otel (record_level ):
316- # type: (int) -> Tuple[int, str]
317- for py_level , otel_severity_number , otel_severity_text in [
318- (50 , 21 , "fatal" ),
319- (40 , 17 , "error" ),
320- (30 , 13 , "warn" ),
321- (20 , 9 , "info" ),
322- (10 , 5 , "debug" ),
323- (5 , 1 , "trace" ),
324- ]:
325- if record_level >= py_level :
326- return otel_severity_number , otel_severity_text
327- return 0 , "default"
328-
329-
330329class SentryLogsHandler (_BaseHandler ):
331330 """
332331 A logging handler that records Sentry logs for each Python log record.
@@ -352,8 +351,9 @@ def emit(self, record):
352351
353352 def _capture_log_from_record (self , client , record ):
354353 # type: (BaseClient, LogRecord) -> None
355- scope = sentry_sdk .get_current_scope ()
356- otel_severity_number , otel_severity_text = _python_level_to_otel (record .levelno )
354+ otel_severity_number , otel_severity_text = _log_level_to_otel (
355+ record .levelno , SEVERITY_TO_OTEL_SEVERITY
356+ )
357357 project_root = client .options ["project_root" ]
358358 attrs = self ._extra_from_record (record ) # type: Any
359359 attrs ["sentry.origin" ] = "auto.logger.log"
@@ -364,10 +364,7 @@ def _capture_log_from_record(self, client, record):
364364 for i , arg in enumerate (record .args ):
365365 attrs [f"sentry.message.parameter.{ i } " ] = (
366366 arg
367- if isinstance (arg , str )
368- or isinstance (arg , float )
369- or isinstance (arg , int )
370- or isinstance (arg , bool )
367+ if isinstance (arg , (str , float , int , bool ))
371368 else safe_repr (arg )
372369 )
373370 if record .lineno :
@@ -394,7 +391,6 @@ def _capture_log_from_record(self, client, record):
394391
395392 # noinspection PyProtectedMember
396393 client ._capture_experimental_log (
397- scope ,
398394 {
399395 "severity_text" : otel_severity_text ,
400396 "severity_number" : otel_severity_number ,
0 commit comments