From 7d6d298d1ece368569ed2cad8e16882692a98a43 Mon Sep 17 00:00:00 2001 From: Mathias Scheider Date: Sun, 18 Oct 2026 08:24:47 +0000 Subject: [PATCH] Log declutter (#5) Reviewed-on: https://gitea.schneiderserver.site/mathias2784/utils/pulls/5 Co-authored-by: Mathias Scheider --- pyproject.toml | 2 +- src/utils/logging_config.py | 4 ++++ test/test_logging_config.py | 15 +++++++++++++++ uv.lock | 4 ++-- 4 files changed, 22 insertions(+), 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index ece4321..e9fc7fa 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "utils" -version = "0.1.2" +version = "0.1.3" description = "Some hopefully useful utilities to use in everyday coding" readme = "README.md" authors = [ diff --git a/src/utils/logging_config.py b/src/utils/logging_config.py index ca1c78e..1695190 100644 --- a/src/utils/logging_config.py +++ b/src/utils/logging_config.py @@ -72,6 +72,10 @@ class LoggingSettings(BaseSettingsConfig): root_logger = logging.getLogger() root_logger.setLevel(level) + # Keep Uvicorn's own debug output from following the application's level. + for logger_name in ("uvicorn", "uvicorn.error", "uvicorn.access"): + logging.getLogger(logger_name).setLevel(logging.INFO) + # Replace and close existing handlers to avoid duplicate output and resource leaks. for handler in root_logger.handlers[:]: root_logger.removeHandler(handler) diff --git a/test/test_logging_config.py b/test/test_logging_config.py index d89abfb..98e807e 100644 --- a/test/test_logging_config.py +++ b/test/test_logging_config.py @@ -13,6 +13,7 @@ from uvicorn.logging import DefaultFormatter from utils.logging_config import LoggingSettings SECONDS_PER_DAY = 24 * 60 * 60 +UVICORN_LOGGER_NAMES = ("uvicorn", "uvicorn.error", "uvicorn.access") @pytest.fixture @@ -20,6 +21,8 @@ def restore_root_logger() -> Generator[None]: root = logging.getLogger() old_handlers = root.handlers[:] old_level = root.level + uvicorn_loggers = [logging.getLogger(name) for name in UVICORN_LOGGER_NAMES] + old_uvicorn_levels = [logger.level for logger in uvicorn_loggers] for handler in old_handlers: root.removeHandler(handler) @@ -32,6 +35,8 @@ def restore_root_logger() -> Generator[None]: for handler in old_handlers: root.addHandler(handler) root.setLevel(old_level) + for logger, level in zip(uvicorn_loggers, old_uvicorn_levels): + logger.setLevel(level) def test_sets_valid_log_level(restore_root_logger: None) -> None: @@ -40,6 +45,16 @@ def test_sets_valid_log_level(restore_root_logger: None) -> None: assert logging.getLogger().level == logging.DEBUG +def test_keeps_uvicorn_loggers_at_info_with_debug_root( + restore_root_logger: None, +) -> None: + LoggingSettings(LOG_LEVEL="DEBUG", LOG_TO_FILE=False) + + assert all( + logging.getLogger(name).level == logging.INFO for name in UVICORN_LOGGER_NAMES + ) + + def test_invalid_log_level_falls_back_to_info(restore_root_logger: None) -> None: with patch("utils.logging_config.logger.error") as log_error: LoggingSettings(LOG_LEVEL="NOT_A_LEVEL", LOG_TO_FILE=False) diff --git a/uv.lock b/uv.lock index 4f9b3f9..7aa1623 100644 --- a/uv.lock +++ b/uv.lock @@ -1,5 +1,5 @@ version = 1 -revision = 3 +revision = 5 requires-python = ">=3.14" [[package]] @@ -751,7 +751,7 @@ wheels = [ [[package]] name = "utils" -version = "0.1.1" +version = "0.1.3" source = { editable = "." } dependencies = [ { name = "black" },