Python RotatingFileHandler日志异常:新日志存入test.log.1而非test.log
问题原因及解决办法
可能的原因
- 外部文件锁定或句柄泄漏:
RotatingFileHandler执行滚动时,需要重命名现有文件并创建新的test.log。如果该文件被外部工具(如日志查看器、备份脚本)锁定,或程序内部未正确释放文件句柄,handler无法完成滚动操作,会继续向原文件句柄(对应test.log.1)写入日志。 - 滚动操作异常静默失败:logging模块默认不会抛出文件操作异常,若
doRollover()执行时遇到权限不足、磁盘空间不足等问题,会失败但不报错,导致日志写入旧文件。 - 进程重启后句柄复用:程序意外重启时,若残留的文件句柄被新进程复用,会导致日志写入错误的文件,破坏正常的滚动逻辑。
解决办法
1. 修复当前异常状态
- 重启程序:停止进程,备份现有日志文件后重启,让
RotatingFileHandler重新初始化日志结构。 - 手动触发滚动:若无法停服,可在程序中执行以下代码强制触发滚动:
import logging from logging.handlers import RotatingFileHandler for handler in logging.root.handlers: if isinstance(handler, RotatingFileHandler): handler.doRollover()
2. 优化日志配置
- 添加
delay=True参数,延迟文件打开直到首次日志写入,避免提前占用文件句柄:RotatingFileHandler('test.log', maxBytes=25*1024*1024, backupCount=3, delay=True) - 开启异常捕获(调试阶段使用),排查滚动失败原因:
import logging logging.raiseExceptions = True # 默认关闭,开启后会抛出文件操作异常
3. 避免外部干扰
- 使用
tail -F而非tail -f查看日志,前者不会锁定文件。 - 禁止在程序运行时手动修改、移动日志文件。
4. 替换为更健壮的方案
- 考虑使用
TimedRotatingFileHandler实现按时间滚动,或结合大小滚动需自定义handler。 - 改用第三方日志库如
loguru,其滚动逻辑更稳定,配置更简洁:from loguru import logger logger.add("test.log", rotation="25 MB", retention=3)
内容的提问来源于stack exchange,提问作者Vishak Raj
相关产品推荐
相关产品推荐

