diff --git a/logging_config.py b/logging_config.py new file mode 100644 index 0000000..0ff15c9 --- /dev/null +++ b/logging_config.py @@ -0,0 +1,13 @@ +import logging + +DEFAULT_FORMAT = "%(asctime)s - %(name)s - %(levelname)s - %(message)s" + + +def configure_logging(level: int = logging.INFO) -> None: + root = logging.getLogger() + root.setLevel(level) + + if not root.handlers: + handler = logging.StreamHandler() + handler.setFormatter(logging.Formatter(DEFAULT_FORMAT)) + root.addHandler(handler) diff --git a/tests/test_logging_config.py b/tests/test_logging_config.py new file mode 100644 index 0000000..20de16d --- /dev/null +++ b/tests/test_logging_config.py @@ -0,0 +1,50 @@ +import logging + +import pytest + +from logging_config import configure_logging + + +class TestConfigureLogging: + def _clear_handlers(self): + root = logging.getLogger() + root.handlers.clear() + root.setLevel(logging.WARNING) + + def test_sets_root_logger_level(self): + self._clear_handlers() + configure_logging(level=logging.DEBUG) + root = logging.getLogger() + assert root.level == logging.DEBUG + + def test_default_level_is_info(self): + self._clear_handlers() + configure_logging() + root = logging.getLogger() + assert root.level == logging.INFO + + def test_handler_format_includes_name_and_level(self): + self._clear_handlers() + configure_logging() + root = logging.getLogger() + assert len(root.handlers) == 1 + handler = root.handlers[0] + formatter = handler.formatter + assert "%(name)s" in formatter._fmt + assert "%(levelname)s" in formatter._fmt + assert "%(asctime)s" in formatter._fmt + + def test_idempotent_second_call(self): + self._clear_handlers() + configure_logging() + initial_handlers = len(logging.getLogger().handlers) + configure_logging() + assert len(logging.getLogger().handlers) == initial_handlers + + def test_module_logger_inherits_level(self): + self._clear_handlers() + configure_logging(level=logging.WARNING) + logger = logging.getLogger("some.module") + assert logger.level == logging.NOTSET + assert logger.isEnabledFor(logging.WARNING) + assert not logger.isEnabledFor(logging.INFO)