rotatingfilehandler按文件大小自动轮转日志,关键参数为maxbytes(字节单位)、backupcount和encoding;需传完整文件路径,避免多handler写同一文件,不支持多进程安全及自动压缩。

用 RotatingFileHandler 实现按大小切分日志文件
直接用 RotatingFileHandler,别碰 TimedRotatingFileHandler——后者按时间轮转,和文件大小无关。它会在日志写入时自动检查当前文件是否超过 maxBytes,超了就重命名旧文件、新建空文件。
关键参数有三个:maxBytes 控制单个文件最大字节数(注意不是 KB/MB 单位,是纯整数),backupCount 决定保留几个历史文件,encoding 建议显式设为 "utf-8",否则 Windows 下中文可能乱码。
常见错误是把 maxBytes 设得太小(比如 100),结果每写几条日志就切一次,磁盘里堆满 app.log.1、app.log.2……实际建议从 10_485_760(即 10MB)起步,再根据日志密度调整。
RotatingFileHandler 的初始化必须传 filename,不能只传路径
容易踩的坑:有人写成 RotatingFileHandler("/var/log/myapp/"),期望自动建目录+生成文件,结果报 IsADirectoryError。它只接受完整文件路径,比如 "/var/log/myapp/app.log"。目录得自己提前创建好,或加一层判断:
import os
log_dir = "/var/log/myapp"
os.makedirs(log_dir, exist_ok=True)
handler = RotatingFileHandler(f"{log_dir}/app.log", ...)
多个 handler 同时写同一个文件会出错
如果你在不同模块里各自调用 logging.basicConfig() 或重复添加 RotatingFileHandler 到 root logger,可能导致多个 handler 尝试同时写 app.log,轻则日志错乱,重则 PermissionError(Windows 下尤其明显)。
正确做法是:只在程序入口(如 if __name__ == "__main__":)配置一次 handler;如果要用多个 logger(比如 logger = logging.getLogger("db")),确保它们共享同一个 handler 实例,或使用 propagate=False 避免重复输出。
另外,RotatingFileHandler 默认是线程安全的,但不保证多进程安全——同一文件被两个 Python 进程同时写,切分逻辑会失效。多进程场景请改用 ConcurrentLogHandler(需 pip install)或改用日志中心方案。
日志切分后旧文件名带数字后缀,但不会自动压缩
默认行为是:当 app.log 达到 maxBytes,它被重命名为 app.log.1;如果已有 app.log.1,就变成 app.log.2,依此类推,直到保留数量达 backupCount,最老的被删掉。这些文件都是明文,不压缩。
想自动 gzip,得自己继承 RotatingFileHandler 重写 doRollover() 方法,或者用第三方库如 logging.handlers.RotatingFileHandler 的增强版(如 watchtower 不适用,它是发 CloudWatch 的)。简单项目不建议折腾压缩,先确保切分逻辑稳定更关键。
真正容易被忽略的是:日志内容本身影响文件大小判断——比如一条日志含大量 traceback 或 base64 字符串,可能单条就接近 maxBytes,导致几乎每次写都触发切分。上线前最好用真实日志量压测一下切分频率。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











