From c9562b20049485c9acf4707a26d5a5d6e0a149ff Mon Sep 17 00:00:00 2001 From: Rich Rauenzahn Date: Fri, 20 May 2022 12:29:23 -0700 Subject: [PATCH 1/7] Use logging levelno instead of levelname. Levelnames can be overridden See https://github.com/getsentry/sentry-python/issues/1443 --- sentry_sdk/integrations/logging.py | 20 +++++++++++---- tests/integrations/logging/test_logging.py | 29 ++++++++++++++++++++++ 2 files changed, 44 insertions(+), 5 deletions(-) diff --git a/sentry_sdk/integrations/logging.py b/sentry_sdk/integrations/logging.py index e9f3fe9dbb..41929adef6 100644 --- a/sentry_sdk/integrations/logging.py +++ b/sentry_sdk/integrations/logging.py @@ -110,7 +110,7 @@ def _breadcrumb_from_record(record): # type: (LogRecord) -> Dict[str, Any] return { "type": "log", - "level": _logging_to_event_level(record.levelname), + "level": _logging_to_event_level(record), "category": record.name, "message": record.message, "timestamp": datetime.datetime.utcfromtimestamp(record.created), @@ -118,9 +118,19 @@ def _breadcrumb_from_record(record): } -def _logging_to_event_level(levelname): - # type: (str) -> str - return {"critical": "fatal"}.get(levelname.lower(), levelname.lower()) +def _logging_to_event_level(record): + # type: (LogRecord) -> str + default = 'error' + return { + logging.NOTSET: 'notset', + logging.DEBUG: 'debug', + logging.INFO: 'info', + logging.WARN: 'warning', # WARN is same a WARNING + logging.WARNING: 'warning', + logging.ERROR: 'error', + logging.FATAL: 'fatal', + logging.CRITICAL: 'fatal', # CRITICAL is same as FATAL + }.get(record.levelno, default) COMMON_RECORD_ATTRS = frozenset( @@ -220,7 +230,7 @@ def _emit(self, record): hint["log_record"] = record - event["level"] = _logging_to_event_level(record.levelname) + event["level"] = _logging_to_event_level(record) event["logger"] = record.name # Log records from `warnings` module as separate issues diff --git a/tests/integrations/logging/test_logging.py b/tests/integrations/logging/test_logging.py index 73843cc6eb..c63e089c7e 100644 --- a/tests/integrations/logging/test_logging.py +++ b/tests/integrations/logging/test_logging.py @@ -115,6 +115,35 @@ def test_logging_level(sentry_init, capture_events): assert not events +def test_all_logging_levels(sentry_init, capture_events): + + levels = { + # logging.NOTSET: 'notset', + logging.DEBUG: 'debug', + logging.INFO: 'info', + logging.WARN: 'warning', + logging.WARNING: 'warning', + logging.ERROR: 'error', + logging.CRITICAL: 'fatal', + logging.FATAL: 'fatal', + } + + for logging_level, sentry_level in levels.items(): + + logger.setLevel(logging_level) + sentry_init(integrations=[LoggingIntegration(event_level=logging_level)], + default_integrations=False) + events = capture_events() + + logger.log(logging_level, "Trying level %s", logging_level) + assert events + assert events[0]['level'] == sentry_level + assert events[0]['logentry']['message'] == "Trying level %s" + assert events[0]['logentry']['params'] == [logging_level] + + del events[:] + + def test_logging_filters(sentry_init, capture_events): sentry_init(integrations=[LoggingIntegration()], default_integrations=False) events = capture_events() From b36aa853a752648879a8b56dd7fa6c6f920b3042 Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Tue, 31 May 2022 11:39:28 +0200 Subject: [PATCH 2/7] Setting custom log level names (and some code formatting) --- tests/integrations/logging/test_logging.py | 42 +++++++++++++--------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/tests/integrations/logging/test_logging.py b/tests/integrations/logging/test_logging.py index c63e089c7e..10660ac8ae 100644 --- a/tests/integrations/logging/test_logging.py +++ b/tests/integrations/logging/test_logging.py @@ -115,31 +115,39 @@ def test_logging_level(sentry_init, capture_events): assert not events -def test_all_logging_levels(sentry_init, capture_events): - +def test_custom_log_level_names(sentry_init, capture_events): levels = { - # logging.NOTSET: 'notset', - logging.DEBUG: 'debug', - logging.INFO: 'info', - logging.WARN: 'warning', - logging.WARNING: 'warning', - logging.ERROR: 'error', - logging.CRITICAL: 'fatal', - logging.FATAL: 'fatal', - } + logging.DEBUG: "debug", + logging.INFO: "info", + logging.WARN: "warning", + logging.WARNING: "warning", + logging.ERROR: "error", + logging.CRITICAL: "fatal", + logging.FATAL: "fatal", + } + + # set custom log level names + logging.addLevelName(logging.DEBUG, "custom level debüg: ") + logging.addLevelName(logging.INFO, "") + logging.addLevelName(logging.WARN, "custom level warn: ") + logging.addLevelName(logging.WARNING, "custom level warning: ") + logging.addLevelName(logging.ERROR, None) + logging.addLevelName(logging.CRITICAL, "custom level critical: ") + logging.addLevelName(logging.FATAL, "custom level 🔥: ") for logging_level, sentry_level in levels.items(): - logger.setLevel(logging_level) - sentry_init(integrations=[LoggingIntegration(event_level=logging_level)], - default_integrations=False) + sentry_init( + integrations=[LoggingIntegration(event_level=logging_level)], + default_integrations=False, + ) events = capture_events() logger.log(logging_level, "Trying level %s", logging_level) assert events - assert events[0]['level'] == sentry_level - assert events[0]['logentry']['message'] == "Trying level %s" - assert events[0]['logentry']['params'] == [logging_level] + assert events[0]["level"] == sentry_level + assert events[0]["logentry"]["message"] == "Trying level %s" + assert events[0]["logentry"]["params"] == [logging_level] del events[:] From c6f82c299b68db759a1b8b5ce62851c19fc2a9e5 Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Tue, 31 May 2022 11:43:56 +0200 Subject: [PATCH 3/7] Using existing default value variable --- sentry_sdk/integrations/logging.py | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/sentry_sdk/integrations/logging.py b/sentry_sdk/integrations/logging.py index 41929adef6..b277deea11 100644 --- a/sentry_sdk/integrations/logging.py +++ b/sentry_sdk/integrations/logging.py @@ -120,17 +120,16 @@ def _breadcrumb_from_record(record): def _logging_to_event_level(record): # type: (LogRecord) -> str - default = 'error' return { - logging.NOTSET: 'notset', - logging.DEBUG: 'debug', - logging.INFO: 'info', - logging.WARN: 'warning', # WARN is same a WARNING - logging.WARNING: 'warning', - logging.ERROR: 'error', - logging.FATAL: 'fatal', - logging.CRITICAL: 'fatal', # CRITICAL is same as FATAL - }.get(record.levelno, default) + logging.NOTSET: "notset", + logging.DEBUG: "debug", + logging.INFO: "info", + logging.WARN: "warning", # WARN is same a WARNING + logging.WARNING: "warning", + logging.ERROR: "error", + logging.FATAL: "fatal", + logging.CRITICAL: "fatal", # CRITICAL is same as FATAL + }.get(record.levelno, DEFAULT_EVENT_LEVEL) COMMON_RECORD_ATTRS = frozenset( From 00b80986284e4b7011ab89f9ebbe3c940193b699 Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Tue, 31 May 2022 11:53:03 +0200 Subject: [PATCH 4/7] Fixed getting of default --- sentry_sdk/integrations/logging.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/sentry_sdk/integrations/logging.py b/sentry_sdk/integrations/logging.py index b277deea11..c38456435f 100644 --- a/sentry_sdk/integrations/logging.py +++ b/sentry_sdk/integrations/logging.py @@ -120,7 +120,7 @@ def _breadcrumb_from_record(record): def _logging_to_event_level(record): # type: (LogRecord) -> str - return { + to_event_level = { logging.NOTSET: "notset", logging.DEBUG: "debug", logging.INFO: "info", @@ -129,7 +129,13 @@ def _logging_to_event_level(record): logging.ERROR: "error", logging.FATAL: "fatal", logging.CRITICAL: "fatal", # CRITICAL is same as FATAL - }.get(record.levelno, DEFAULT_EVENT_LEVEL) + } + + event_level = to_event_level.get(record.levelno) or to_event_level.get( + DEFAULT_EVENT_LEVEL + ) + + return event_level COMMON_RECORD_ATTRS = frozenset( From 965968fd46c309036e2f7906caf7809680120a63 Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Tue, 31 May 2022 13:15:35 +0200 Subject: [PATCH 5/7] Preserving passt behaviour and made var a constant --- sentry_sdk/integrations/logging.py | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/sentry_sdk/integrations/logging.py b/sentry_sdk/integrations/logging.py index c38456435f..f4e5cfbf70 100644 --- a/sentry_sdk/integrations/logging.py +++ b/sentry_sdk/integrations/logging.py @@ -24,6 +24,16 @@ DEFAULT_LEVEL = logging.INFO DEFAULT_EVENT_LEVEL = logging.ERROR +LOGGING_TO_EVENT_LEVEL = { + logging.NOTSET: "notset", + logging.DEBUG: "debug", + logging.INFO: "info", + logging.WARN: "warning", # WARN is same a WARNING + logging.WARNING: "warning", + logging.ERROR: "error", + logging.FATAL: "fatal", + logging.CRITICAL: "fatal", # CRITICAL is same as FATAL +} # Capturing events from those loggers causes recursion errors. We cannot allow # the user to unconditionally create events from those loggers under any @@ -120,22 +130,7 @@ def _breadcrumb_from_record(record): def _logging_to_event_level(record): # type: (LogRecord) -> str - to_event_level = { - logging.NOTSET: "notset", - logging.DEBUG: "debug", - logging.INFO: "info", - logging.WARN: "warning", # WARN is same a WARNING - logging.WARNING: "warning", - logging.ERROR: "error", - logging.FATAL: "fatal", - logging.CRITICAL: "fatal", # CRITICAL is same as FATAL - } - - event_level = to_event_level.get(record.levelno) or to_event_level.get( - DEFAULT_EVENT_LEVEL - ) - - return event_level + return LOGGING_TO_EVENT_LEVEL.get(record.levelno, record.levelname.lower()) COMMON_RECORD_ATTRS = frozenset( From d26c87adb12d2fc4a80096d1e3e64bae97937a75 Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Tue, 31 May 2022 13:58:13 +0200 Subject: [PATCH 6/7] Fixing tests --- sentry_sdk/integrations/logging.py | 4 +++- tests/integrations/logging/test_logging.py | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/sentry_sdk/integrations/logging.py b/sentry_sdk/integrations/logging.py index f4e5cfbf70..86cea09bd8 100644 --- a/sentry_sdk/integrations/logging.py +++ b/sentry_sdk/integrations/logging.py @@ -130,7 +130,9 @@ def _breadcrumb_from_record(record): def _logging_to_event_level(record): # type: (LogRecord) -> str - return LOGGING_TO_EVENT_LEVEL.get(record.levelno, record.levelname.lower()) + return LOGGING_TO_EVENT_LEVEL.get( + record.levelno, record.levelname.lower() if record.levelname else "" + ) COMMON_RECORD_ATTRS = frozenset( diff --git a/tests/integrations/logging/test_logging.py b/tests/integrations/logging/test_logging.py index 10660ac8ae..124d0dad45 100644 --- a/tests/integrations/logging/test_logging.py +++ b/tests/integrations/logging/test_logging.py @@ -127,7 +127,9 @@ def test_custom_log_level_names(sentry_init, capture_events): } # set custom log level names - logging.addLevelName(logging.DEBUG, "custom level debüg: ") + # fmt: off + logging.addLevelName(logging.DEBUG, u"custom level debüg: ") + # fmt: on logging.addLevelName(logging.INFO, "") logging.addLevelName(logging.WARN, "custom level warn: ") logging.addLevelName(logging.WARNING, "custom level warning: ") From d0129ffa2ba1438ec83de8ddef6c0b5e2aa8c417 Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Wed, 1 Jun 2022 09:17:52 +0200 Subject: [PATCH 7/7] Added file encoding to satify Python 2.7 --- tests/integrations/logging/test_logging.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/integrations/logging/test_logging.py b/tests/integrations/logging/test_logging.py index 124d0dad45..de1c55e26f 100644 --- a/tests/integrations/logging/test_logging.py +++ b/tests/integrations/logging/test_logging.py @@ -1,3 +1,4 @@ +# coding: utf-8 import sys import pytest