import logging import sys from pathlib import Path class StreamToLogger: """ Fake file-like stream object that redirects writes to a logger instance. """ def __init__(self, logger, log_level=logging.INFO): self.logger = logger self.log_level = log_level self.linebuf = '' self.enabled = True def write(self, buf): if self.enabled: for line in buf.rstrip().splitlines(): self.logger.log(self.log_level, line.rstrip()) def flush(self): pass def enable(self): self.enabled = True def isatty(self): return False def disable(self): self.enabled = False def setup_logger(config: dict, name: str = None) -> logging.Logger: """Set up logger with configuration from config file.""" logger = logging.getLogger(name or __name__) # Set level from config level = getattr(logging, config["logging"]["level"].upper()) logger.setLevel(level) # Create logs directory if it doesn't exist log_path = Path(config["folders"]["logs"]) log_path.mkdir(exist_ok=True) # Create handlers file_handler = logging.FileHandler(log_path / config["logging"]["file"]) console_handler = logging.StreamHandler() # Create formatter formatter = logging.Formatter(config["logging"]["format"]) file_handler.setFormatter(formatter) console_handler.setFormatter(formatter) # Add handlers logger.addHandler(file_handler) logger.addHandler(console_handler) # Redirect stdout to logger stream_to_logger = StreamToLogger(logger, logging.INFO) sys.stdout = stream_to_logger # Add methods to enable/disable StreamToLogger logger.enable_stream_to_logger = stream_to_logger.enable logger.disable_stream_to_logger = stream_to_logger.disable return logger