diff --git a/src/dopt_basics/logging.py b/src/dopt_basics/logging.py new file mode 100644 index 0000000..6fb14d0 --- /dev/null +++ b/src/dopt_basics/logging.py @@ -0,0 +1,67 @@ +from __future__ import annotations + +import logging +import logging.handlers +from pathlib import Path +from time import gmtime +from typing import Final + +# ** config +LOG_FILENAME: Final[str] = "dopt.log" +BASE_NAME: Final[str] = "dopt_base" + +LOG_FMT: Final[str] = "%(asctime)s | lang_main:%(module)s:%(levelname)s | %(message)s" +LOG_DATE_FMT: Final[str] = "%Y-%m-%d %H:%M:%S +0000" +DEFAULT_LOGLEVEL_STDERR: Final[int] = logging.DEBUG +DEFAULT_LOGLEVEL_FILE: Final[int] = logging.DEBUG +# ** handlers +NULL_HANDLER = logging.NullHandler() + +# ** loggers and configuration +BASE_LOGGER = logging.getLogger("dopt_base") + + +def setup_logging( + enable_stderr: bool, + enable_file: bool = False, + logging_dir: Path | None = None, + log_filename: str = LOG_FILENAME, +) -> None: + # ** formatters + logging.Formatter.converter = gmtime + LOGGER_ALL_FORMATER = logging.Formatter(fmt=LOG_FMT, datefmt=LOG_DATE_FMT) + # ** handlers + if enable_stderr: + logger_all_handler_stderr = logging.StreamHandler() + logger_all_handler_stderr.setLevel(DEFAULT_LOGLEVEL_STDERR) + logger_all_handler_stderr.setFormatter(LOGGER_ALL_FORMATER) + else: # pragma: no cover + logger_all_handler_stderr = NULL_HANDLER + + if enable_file and logging_dir is None: + raise ValueError("Logging path must be provided to write to log file") + elif enable_file: + assert logging_dir + log_file_path = logging_dir / log_filename + logger_all_handler_file = logging.handlers.RotatingFileHandler( + log_file_path, + encoding="utf-8", + maxBytes=5_242_880, + backupCount=1, + delay=True, + ) + logger_all_handler_file.setLevel(DEFAULT_LOGLEVEL_FILE) + logger_all_handler_file.setFormatter(LOGGER_ALL_FORMATER) + else: # pragma: no cover + logger_all_handler_file = NULL_HANDLER + + BASE_LOGGER.addHandler(logger_all_handler_stderr) + BASE_LOGGER.addHandler(logger_all_handler_file) + + +def disable_logging() -> None: + handlers = tuple(BASE_LOGGER.handlers) + for handler in handlers: + BASE_LOGGER.removeHandler(handler) + + BASE_LOGGER.addHandler(NULL_HANDLER)