如何实现Python logging每条日志生成独立文件的轮转处理器?
实现每条日志触发轮转的自定义日志处理器
核心思路
要实现每次记录日志就触发文件轮转,基于Python标准库的logging.handlers.BaseRotatingHandler自定义处理器即可,关键重写两个方法:
shouldRollover():强制返回True,让每条日志都触发轮转逻辑doRollover():实现文件重命名、新文件创建的具体轮转操作
自定义处理器代码实现
import logging import os from logging.handlers import BaseRotatingHandler class PerRecordRotatingHandler(BaseRotatingHandler): def __init__(self, base_filename, mode='a', encoding=None, delay=False): self.base_filename = os.path.abspath(base_filename) self.current_index = 0 # 初始化时扫描现有轮转文件,确定起始序号 while os.path.exists(f"{self.base_filename}.{self.current_index}"): self.current_index += 1 super().__init__(self.base_filename, mode, encoding, delay) def shouldRollover(self, record): # 每条日志都触发轮转 return True def doRollover(self): # 关闭当前日志文件流 if self.stream: self.stream.close() self.stream = None # 轮转现有备份文件:将旧序号依次递增 for i in range(self.current_index, 0, -1): src_path = f"{self.base_filename}.{i-1}" dst_path = f"{self.base_filename}.{i}" if os.path.exists(src_path): os.rename(src_path, dst_path) # 将当前主日志文件重命名为序号0的备份 if os.path.exists(self.base_filename): os.rename(self.base_filename, f"{self.base_filename}.0") self.current_index += 1 # 打开新的主日志文件 self.stream = self._open()
使用示例
# 配置日志器 logger = logging.getLogger("per_record_logger") logger.setLevel(logging.INFO) logger.handlers.clear() # 避免重复添加处理器 # 添加自定义轮转处理器 rot_handler = PerRecordRotatingHandler("app.log") formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s") rot_handler.setFormatter(formatter) logger.addHandler(rot_handler) # 测试日志记录 logger.info("I'm written to my own file") logger.info("I'm written to my own file #2") logger.info("I'm written to my own file #3")
执行后会生成以下文件:
app.log:存储第三条日志app.log.0:存储第二条日志app.log.1:存储第一条日志
备选简化方案(不推荐)
如果不想自定义处理器,也可以在每条日志记录后手动触发轮转,但这种方式侵入性强:
from logging.handlers import RotatingFileHandler handler = RotatingFileHandler("app.log", maxBytes=1, backupCount=10) logger.addHandler(handler) logger.info("I'm written to my own file") handler.doRollover() logger.info("I'm written to my own file #2") handler.doRollover() logger.info("I'm written to my own file #3")
内容的提问来源于stack exchange,提问作者maxwell_rob33
相关产品推荐
相关产品推荐

