Source code for ditk.logging.log

import logging
from typing import List, Optional, Tuple

from .base import _LogLevelType
from .file import _create_file_handler, LoggingFileHandler, _normpath
from .terminal import LoggingTerminalHandler

__all__ = [
    'try_init_root',
    'getLogger',
]


[docs]def try_init_root(level: Optional[_LogLevelType] = None) -> logging.Logger: root = logging.getLogger() if not root.handlers: root.addHandler(LoggingTerminalHandler()) if level is not None: root.setLevel(level) return root
# noinspection PyPep8Naming
[docs]def getLogger( name: Optional[str] = None, level: Optional[_LogLevelType] = None, with_files: Optional[List[str]] = None ) -> logging.Logger: """ Overview: Get :class:`logging.Logger` object, with terminal output and file output. :param name: Name of logger. :param level: Logging level of the loggers. :param with_files: The files going to output. :return logger: Logger created. """ logger = logging.getLogger(name) if level is not None: logger.setLevel(level) to_be_logged = [] with_files = with_files or [] if with_files: file_handlers: List[Tuple[LoggingFileHandler, logging.Logger]] = [] _current_logger = logger while _current_logger: for handler in _current_logger.handlers: if isinstance(handler, LoggingFileHandler): file_handlers.append((handler, _current_logger)) _current_logger = _current_logger.parent if _current_logger.propagate else None fps = {handler.file_path: _logger for handler, _logger in file_handlers} for file in with_files: nfile = _normpath(file) if nfile in fps: to_be_logged.append( ( logging.WARNING, f"File {repr(file)} has already been added to logger {repr(fps[nfile])}, " f"so this configuration will be ignored." ) ) else: handler = _create_file_handler(file) logger.addHandler(handler) fps[nfile] = logger for level_, msg in to_be_logged: logger.log(level_, msg) return logger