Source code for biallelic.logging
"""Logging utilities for biallelic analysis pipeline.
Provides SimpleLogger and ExtendedLogger classes for hierarchical logging
to both files and console output. Supports creating sublogs for different
analysis stages.
"""
import os
import logging
from typing import Dict
[docs]
class ExtendedLogger:
"""Base logger with file and console output handlers.
Creates a logger that writes to both a log file and console output,
with consistent formatting and specified logging level.
Attributes:
__name__: Logger name
__path__: Directory where log files are written
log: Python logging.Logger instance
log_file: Path to the log file
"""
def __init__(self, name: str, path: str, level: int) -> None:
"""Initialize ExtendedLogger with file and stream handlers.
Args:
name: Logger name (used for log file name)
path: Directory path for log output
level: Logging level (logging.DEBUG, INFO, WARNING, etc.)
"""
self.__name__ = name
self.__path__ = os.path.join(path)
if not os.path.exists(self.__path__):
os.makedirs(self.__path__)
self.log = logging.getLogger(self.__name__)
self.log_file = os.path.join(self.__path__, "%s.log" % self.__name__)
formatter = logging.Formatter(
"%(levelname)s : %(asctime)s : %(message)s",
)
fileHandler = logging.FileHandler(self.log_file, mode="w")
fileHandler.setFormatter(formatter)
streamHandler = logging.StreamHandler()
streamHandler.setFormatter(formatter)
self.log.setLevel(level)
self.log.addHandler(fileHandler)
self.log.addHandler(streamHandler)
[docs]
class SimpleLogger(ExtendedLogger):
"""Hierarchical logger with support for child sublogs.
Extends ExtendedLogger to support creating child loggers for different
analysis stages. All logs are written to the same directory with
automatic file naming.
Attributes:
sublogs: Dictionary of child SimpleLogger instances
Example:
>>> from biallelic.logging import SimpleLogger
>>> logger = SimpleLogger("analysis", "/path/to/logs")
>>> ref_logger = logger.add_log("reference_loading")
>>> ref_logger.log.info("Loading gene annotations")
"""
def __init__(
self, name: str, path: str, level: int = logging.INFO
) -> None:
"""Initialize SimpleLogger with sublog support.
Args:
name: Logger name (used for log file name)
path: Directory path for log output
level: Logging level (default: logging.INFO)
"""
super().__init__(name, path, level=level)
self.log.info(
"Writing %(name)s logs to folder %(path)s",
{"path": self.__path__, "name": name},
)
self.sublogs: Dict[str, "SimpleLogger"] = {}
[docs]
def add_log(self, name: str, level: int = logging.INFO) -> "SimpleLogger":
"""Create a child logger for a specific analysis stage.
Args:
name: Name of the sublog (used for log file name)
level: Logging level for sublog (default: logging.INFO)
Returns:
SimpleLogger instance for the sublog
"""
self.sublogs[name] = SimpleLogger(name, self.__path__, level=level)
return self.sublogs[name]