import logging import sys from pathlib import Path from typing_extensions import TypeVar H = TypeVar('H', bound=logging.Handler) class RunLogger(logging.Logger): def __init__(self, name, level=logging.INFO, stream=sys.stdout): super().__init__(name, level) self.handlers.clear() self.handlers.append( self._configure_handler(logging.StreamHandler(stream), level) ) def set_output_file(self, outfile: Path, level=logging.INFO): for handler in list(self.handlers): if not isinstance(handler, logging.FileHandler): continue self.handlers.remove(handler) self.handlers.append( self._create_file_handler(outfile, level) ) @staticmethod def _create_file_handler(file: str|Path, level) -> logging.FileHandler: file = Path(file) if file.exists(): file.rename(file.with_suffix('.log.backup')) handler = logging.FileHandler(file) return RunLogger._configure_handler(handler, level) @staticmethod def _configure_handler(handler: H, level) -> H: handler.setLevel(level) formatter = logging.Formatter('%(message)s') handler.setFormatter(formatter) return handler