import logging def configure_logger(log_filename): logger = logging.getLogger(log_filename) logger.setLevel(logging.INFO) # Clear any existing handlers (in case of repeated calls) if logger.handlers: logger.handlers.clear() file_handler = logging.FileHandler(log_filename) file_handler.setLevel(logging.INFO) formatter = logging.Formatter("%(asctime)s - %(levelname)s - %(message)s") file_handler.setFormatter(formatter) logger.addHandler(file_handler) return logger def log_section_header(section_title, logger): separator = f"{'=' * 20} {section_title} {'=' * 20}" logger.info(f"\n\n{separator}\n") def log_section_footer(logger): separator = f"{'=' * 60}" logger.info(f"\n\n{separator}\n") class NullLogger: """A Logger implementation that does not output any logs""" def info(self, *args, **kwargs): pass def error(self, *args, **kwargs): pass def warning(self, *args, **kwargs): pass def debug(self, *args, **kwargs): pass class PrintLogger: """A Logger implementation that prints messages to stdout.""" def info(self, msg, *args, **kwargs): print(f"[INFO] {msg}", *args, **kwargs) def error(self, msg, *args, **kwargs): print(f"[ERROR] {msg}", *args, **kwargs) def warning(self, msg, *args, **kwargs): print(f"[WARNING] {msg}", *args, **kwargs) def debug(self, msg, *args, **kwargs): print(f"[DEBUG] {msg}", *args, **kwargs)