From 3d3832966ec3c7087858d4524c9e367afa5df556 Mon Sep 17 00:00:00 2001 From: Rich Rauenzahn Date: Thu, 2 Jun 2022 01:11:35 -0700 Subject: [PATCH] Use logging levelno instead of levelname. Levelnames can be overridden (#1449) Use logging levelno instead of levelname. Levelnames can be overridden. Fixes #1449 --- sentry_sdk/integrations/logging.py | 22 +++++++++--- tests/integrations/logging/test_logging.py | 40 ++++++++++++++++++++++ 2 files changed, 57 insertions(+), 5 deletions(-) diff --git a/sentry_sdk/integrations/logging.py b/sentry_sdk/integrations/logging.py index e9f3fe9dbb..86cea09bd8 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 @@ -110,7 +120,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 +128,11 @@ 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 + return LOGGING_TO_EVENT_LEVEL.get( + record.levelno, record.levelname.lower() if record.levelname else "" + ) COMMON_RECORD_ATTRS = frozenset( @@ -220,7 +232,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..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 @@ -115,6 +116,45 @@ def test_logging_level(sentry_init, capture_events): assert not events +def test_custom_log_level_names(sentry_init, capture_events): + levels = { + 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 + # 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: ") + 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, + ) + 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()