Module pyboiler.logger

Wrap pyboiler.logging in a Singleton for more concrete logging structures

Example Usage:

from pyboiler.logger import Logger, Level

Logger("MyProject", Level().WARN)
Logger().trace("This is a trace")
subm = Logger().Child("Submodule")
subm.trace("And another!")  # Or Logger().subm.trace("And another!")

Classes

class Logger (*args, **kwargs)

Project root logger

Expand source code
class Logger(storage):
    """Project root logger"""

    __slots__ = ["_internal", "_parent", "_str_name", "_logger"]

    __instance = None

    def __new__(cls, name=None, level: Level = None):  # type: ignore
        if cls.__instance is None:
            inst = object.__new__(cls)
            if name is None:
                name = "Logger"
            if level is None:
                level = Level.TRACE

            inst._internal = {}
            inst._parent = None
            inst._str_name = name
            inst._logger = logging(name, Level.get(level))
            inst._addHandlers()
            cls.__instance = inst

        return cls.__instance

    def __init__(self, *args, **kwargs):
        return

    def Child(self, name: str, level=None):
        """Create a child logger"""
        if level is None:
            level = self.get_level()
        if self._internal.get(name, None) is None:
            log_inst = _Logger(self, name, level)
            self._internal[name] = log_inst
        return self._internal[name]

    def get_level(self) -> Level:
        """Get log level"""
        return self._logger.level

    def set_level(self, level):
        """Set log level"""
        self._logger.level = level

    def name(self) -> str:
        """Return structured name"""
        if self._parent is None:
            return self._str_name
        return f"{self._parent.name()}.{self._str_name}"

    def trace(self, msg):
        """log.trace"""
        self._logger.trace(msg)

    def debug(self, msg):
        """log.debug"""
        self._logger.debug(msg)

    def info(self, msg):
        """log.info"""
        self._logger.info(msg)

    def warn(self, msg):
        """log.warn"""
        self._logger.warn(msg)

    def error(self, msg):
        """log.error"""
        self._logger.error(msg)

    def exception(self, msg):
        """log.exception"""
        self._logger.exception(msg)


    def _addHandlers(self, lvl: Level = config().SENTINEL):  # type: ignore
        if lvl is config().SENTINEL:
            lvl: Level = self.get_level()
        self._logger.mk_handler("stdout", lvl)
        self._logger.mk_handler("file", self._log_path(), lvl)

    def _log_path(self) -> pathlib.Path:
        path_sep = self.name().split(".")
        if len(path_sep) > 1:
            path_sep = path_sep[1:]
        log_path = config().PATH_LOGS
        for idx, item in enumerate(path_sep):
            if idx == len(path_sep) - 1:
                log_path.mkdir(exist_ok=True, parents=True)
                item = f"{item}.log"
            log_path /= item
            # print(f"{log_path = }")
        return log_path

Ancestors

Subclasses

  • pyboiler.logger._Logger

Methods

def Child(self, name: str, level=None)

Create a child logger

def debug(self, msg)

log.debug

def error(self, msg)

log.error

def exception(self, msg)

log.exception

def get_level(self) ‑> Level

Get log level

def info(self, msg)

log.info

def name(self) ‑> str

Return structured name

def set_level(self, level)

Set log level

def trace(self, msg)

log.trace

def warn(self, msg)

log.warn

Inherited members