Python 日志系统进阶:多处理器与滚动日志

Python 的 logging 模块支持通过多处理器实现日志分流,并通过滚动日志解决文件过大问题。以下为进阶实现指南:


一、多处理器(Multiple Handlers)

作用:将不同级别的日志分发到不同目标(如文件/控制台)。
核心配置

import logging

# 创建日志记录器
logger = logging.getLogger("advanced_logger")
logger.setLevel(logging.DEBUG)  # 捕获所有级别日志

# 处理器1:输出到控制台(仅ERROR级别)
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.ERROR)  # 仅处理ERROR及以上
console_formatter = logging.Formatter('%(levelname)s - %(message)s')
console_handler.setFormatter(console_formatter)

# 处理器2:输出到文件(所有级别)
file_handler = logging.FileHandler("app.log")
file_handler.setLevel(logging.DEBUG)  # 处理DEBUG及以上
file_formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
file_handler.setFormatter(file_formatter)

# 绑定处理器
logger.addHandler(console_handler)
logger.addHandler(file_handler)

# 测试日志
logger.debug("Debug 信息(仅写入文件)")
logger.error("Error 信息(同时输出到控制台和文件)")


二、滚动日志(Rotating Logs)

作用:自动分割日志文件,避免单个文件过大。
两种实现方式

  1. 按大小滚动RotatingFileHandler
    当文件达到指定大小时创建新文件:

    from logging.handlers import RotatingFileHandler
    
    # 滚动处理器:单个文件最大10MB,保留3个备份
    rotating_handler = RotatingFileHandler(
        "app.log", maxBytes=10*1024*1024, backupCount=3
    )
    rotating_handler.setFormatter(file_formatter)
    logger.addHandler(rotating_handler)
    

  2. 按时间滚动TimedRotatingFileHandler
    按时间间隔(如每天/每小时)创建新文件:

    from logging.handlers import TimedRotatingFileHandler
    
    # 时间滚动处理器:每天午夜创建新文件,保留7天日志
    timed_handler = TimedRotatingFileHandler(
        "app.log", when="midnight", interval=1, backupCount=7
    )
    timed_handler.setFormatter(file_formatter)
    logger.addHandler(timed_handler)
    


三、多处理器 + 滚动日志综合示例
import logging
from logging.handlers import RotatingFileHandler, TimedRotatingFileHandler

# 创建记录器
logger = logging.getLogger("multi_handler_logger")
logger.setLevel(logging.DEBUG)

# 定义通用日志格式
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')

# 处理器1:控制台输出(仅WARNING+)
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.WARNING)
console_handler.setFormatter(formatter)

# 处理器2:按大小滚动(10MB/3备份)
size_handler = RotatingFileHandler(
    "size_rotated.log", maxBytes=10*1024*1024, backupCount=3
)
size_handler.setFormatter(formatter)

# 处理器3:按时间滚动(每天/7备份)
time_handler = TimedRotatingFileHandler(
    "time_rotated.log", when="D", interval=1, backupCount=7
)
time_handler.setFormatter(formatter)

# 绑定所有处理器
logger.addHandler(console_handler)
logger.addHandler(size_handler)
logger.addHandler(time_handler)

# 生成测试日志
for i in range(10000):
    logger.info(f"日志条目 {i}")  # 同时写入两个滚动文件
    if i % 1000 == 0:
        logger.warning(f"警告条目 {i}")  # 额外输出到控制台


四、最佳实践
  1. 分流策略

    • 错误日志 → 控制台 + 邮件通知
    • 调试日志 → 滚动文件
    # 邮件处理器示例(需配置SMTP)
    from logging.handlers import SMTPHandler
    mail_handler = SMTPHandler(
        mailhost=("smtp.example.com", 587),
        fromaddr="alerts@example.com",
        toaddrs=["admin@example.com"],
        subject="应用错误警报",
        credentials=("user", "password")
    )
    mail_handler.setLevel(logging.ERROR)
    

  2. 性能优化

    • 对高频日志使用 QueueHandler 避免阻塞
    • 设置 delay=True 延迟文件打开(直到首次写入)
  3. 动态配置
    通过 logging.config.dictConfig() 实现配置热更新:

    import logging.config
    
    config = {
        'version': 1,
        'handlers': {
            'file': {
                'class': 'logging.handlers.TimedRotatingFileHandler',
                'when': 'midnight',
                'backupCount': 7
            }
        },
        'root': {'level': 'DEBUG', 'handlers': ['file']}
    }
    logging.config.dictConfig(config)
    

提示:使用 logger.propagate = False 可阻止日志向父记录器传递,避免重复处理。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐