Python将捕获日志输出到变量的logging脚本封装为类的实现咨询
Python logging日志捕获到变量的类封装实现
你当前的封装已经可以正常运行,但存在几个可优化的问题:
- 固定写死logger名称,多次实例化时会给同一个logger重复添加handler,导致同一条日志被多次捕获
- 直接暴露内部的
logger、log_capture_string属性,不符合封装原则,使用时需要手动操作内部对象,步骤繁琐 - 没有内置日志内容获取、缓冲区清理、资源释放的相关方法,易用性差
优化后的封装实现
import logging import io from typing import Optional class LogCapturer: def __init__( self, logger_name: str = "captured_logger", logger_level: int = logging.ERROR, handler_level: int = logging.DEBUG, log_formatter: Optional[str] = "%(asctime)s - %(name)s - %(levelname)s - %(message)s" ): # 初始化logger self.logger = logging.getLogger(logger_name) self.logger.setLevel(logger_level) # 清理已有同类型handler,避免重复输出日志 for handler in self.logger.handlers[:]: if isinstance(handler, logging.StreamHandler) and hasattr(handler, "_is_capturer"): self.logger.removeHandler(handler) # 初始化内存缓冲区和日志handler self.log_buffer = io.StringIO() self.stream_handler = logging.StreamHandler(self.log_buffer) self.stream_handler.setLevel(handler_level) self.stream_handler.setFormatter(logging.Formatter(log_formatter)) # 给handler打标记,方便后续识别清理 setattr(self.stream_handler, "_is_capturer", True) self.logger.addHandler(self.stream_handler) def __getattr__(self, item): # 代理logger的日志方法,不需要额外暴露内部logger对象 if hasattr(self.logger, item): return getattr(self.logger, item) raise AttributeError(f"'LogCapturer' object has no attribute '{item}'") def get_logs(self, clear_after: bool = False) -> str: # 直接返回捕获到的日志内容 logs = self.log_buffer.getvalue() if clear_after: self.clear() return logs def clear(self) -> None: # 清空日志缓冲区,支持重复捕获 self.log_buffer.seek(0) self.log_buffer.truncate() def close(self) -> None: # 手动释放资源 self.logger.removeHandler(self.stream_handler) self.log_buffer.close() def __enter__(self): # 支持上下文管理器使用 return self def __exit__(self, exc_type, exc_val, exc_tb): # 上下文退出时自动释放资源 self.close()
使用示例
基础使用
# 初始化捕获器 log_capturer = LogCapturer(logger_level=logging.ERROR) # 直接调用日志方法输出日志,不需要手动访问内部logger log_capturer.debug('debug message') log_capturer.info('info message') log_capturer.warning('warn message') log_capturer.error('error message') log_capturer.critical('critical message') # 直接获取日志内容 log_contents = log_capturer.get_logs() print(log_contents.lower()) # 清空缓冲区可重新捕获日志 log_capturer.clear() # 用完释放资源 log_capturer.close()
上下文管理器方式(推荐,自动释放资源)
with LogCapturer() as log_capturer: log_capturer.error('test error log') log_capturer.critical('test critical log') print(log_capturer.get_logs()) # 退出with块后自动释放资源,不需要手动调用close
内容的提问来源于stack exchange,提问作者banana_99
相关产品推荐
相关产品推荐

