Source code for conflog

"""Python logging setup via configuration files and environment variables."""

from typing import Union
import logging
from .handlers.file_handler import init as init_file_handler
from .handlers.stream_handler import init as init_stream_handler
from .config import Config


[docs] class Conflog: """Configures Python logging from files, environment variables, and a config dict.""" def __init__( self, conf_files: Union[None, str, list] = None, conf_dict: Union[None, dict] = None, ): """Initialise Python logging with configuration from files and an optional dict. Configuration is loaded in order: files first, then environment variables, then ``conf_dict`` (which takes highest precedence). :param conf_files: Path or list of paths to configuration files. Supported formats: ``.ini``, ``.json``, ``.xml``, ``.yaml``. :type conf_files: str or list[str] or None :param conf_dict: Optional dict of configuration values that override all other sources. :type conf_dict: dict or None """ if isinstance(conf_files, str): conf_files = [conf_files] self.config = Config(conf_files=conf_files, conf_dict=conf_dict) handlers = self.config.get_handlers() datefmt = self.config.get_datefmt() level = self.config.get_level() self.extras = self.config.get_extras() self.handlers = [] if "stream" in handlers: self.handlers.append(init_stream_handler(self.config)) if "file" in handlers: self.handlers.append(init_file_handler(self.config)) logging.basicConfig(datefmt=datefmt, level=level)
[docs] def get_logger(self, name: str) -> logging.Logger: """Return a named logger with all configured handlers attached. :param name: Logger name, typically ``__name__`` of the calling module. :type name: str :returns: Configured :class:`logging.LoggerAdapter` wrapping the named logger. :rtype: logging.LoggerAdapter """ logger = logging.getLogger(name) logger.propagate = False # prevent duplicate logging from parent propagation for handler in self.handlers: logger.addHandler(handler) logger = logging.LoggerAdapter(logger, self.extras) logger.setLevel(self.config.get_level()) return logger
[docs] def close_logger_handlers(self, name: str) -> None: """Close and remove all handlers from the named logger. :param name: Logger name whose handlers should be closed. :type name: str """ logger = logging.getLogger(name) for handler in logger.handlers: handler.close() logger.handlers.clear()
[docs] def get_config_properties(self) -> dict: """Return the merged configuration properties dictionary. :returns: All resolved configuration key-value pairs. :rtype: dict """ return self.config.conf