You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 04:15:00