Python 日志文件如何轮转?RotatingFileHandler 和 TimedRotatingFileHandler 有什么区别?
简化版
日志轮转用于避免日志文件无限增长。RotatingFileHandler 按文件大小轮转,TimedRotatingFileHandler 按时间轮转。生产环境还要考虑多进程写同一日志文件、容器 stdout 采集、日志保留天数和敏感信息脱敏。
详细版
按大小轮转:
from logging.handlers import RotatingFileHandler
handler = RotatingFileHandler("app.log", maxBytes=10_000_000, backupCount=5)
按时间轮转:
from logging.handlers import TimedRotatingFileHandler
handler = TimedRotatingFileHandler("app.log", when="midnight", backupCount=7)
前者适合控制单文件大小,后者适合按天归档。容器化环境常常不直接写文件,而是输出到 stdout/stderr,由平台负责采集和轮转。
完整版教学
一、为什么日志需要轮转
如果日志持续写入同一个文件,文件会越来越大。磁盘打满后,应用可能无法写日志、无法写临时文件,甚至数据库和系统服务也受影响。
每天 2GB 日志
保留 30 天
需要约 60GB
日志轮转就是把一个无限增长文件切成多个有限文件,并控制保留数量。
二、按大小轮转怎么工作
RotatingFileHandler 在文件达到 maxBytes 后重命名旧文件,再创建新文件继续写。backupCount 控制保留多少个旧文件。
app.log
app.log.1
app.log.2
...
如果 maxBytes=10MB、backupCount=5,最多约保留 50MB 历史日志,加上当前文件约 60MB。这个上限简单可控。
三、按时间轮转怎么工作
TimedRotatingFileHandler 按时间切分,例如每天午夜、每小时、每周。它适合运维按日期查日志。
TimedRotatingFileHandler(
"app.log",
when="midnight",
interval=1,
backupCount=14,
encoding="utf-8",
)
按时间轮转的单个文件大小不固定。如果某天流量暴涨,单日日志可能非常大。因此关键系统还要配合采集平台和磁盘告警。
四、多进程写同一文件的坑
Python 标准库文件 handler 对多线程通常有锁,但多进程同时写同一日志文件和轮转时可能出问题。多个进程可能同时判断需要 rollover,导致文件竞争。
worker1 -> rollover
worker2 -> rollover
Gunicorn 多 worker 这类场景,通常更推荐输出到 stdout,由进程管理器或日志平台处理;或者使用支持多进程安全的日志方案。
日志轮转不只是 Python 代码问题,也和部署形态强相关。
五、容器环境为什么常输出 stdout
Docker/Kubernetes 中,最佳实践通常是应用写 stdout/stderr,平台负责采集、存储、检索和轮转。这样容器内部不需要管理长期日志文件。
app -> stdout -> container runtime -> log collector -> ES/Loki/云日志
如果应用在容器里自己写文件,还要处理挂载卷、权限、轮转、采集路径等问题,复杂度更高。
六、日志保留和脱敏
轮转只解决文件大小,不解决合规。日志保留时间要按业务和法规确定,敏感字段要脱敏,错误日志不要直接打印 token、密码、身份证号。
password=******
token=abcd...masked
phone=138****0000
日志既是排障资料,也是潜在敏感数据集合。工程上要同时考虑“能查到”和“不泄露”。
七、常见误区与追问
- 误区:配置了 logging 就自动轮转。 普通 FileHandler 不轮转,要用轮转 handler 或外部工具。
- 误区:TimedRotatingFileHandler 能控制文件大小。 它按时间切,不保证大小。
- 误区:多进程写同一日志文件一定安全。 轮转时可能竞争,容器环境更推荐 stdout。
- 追问:按大小和按时间怎么选? 要大小上限选 Rotating,要日期归档选 Timed。
- 追问:backupCount 是什么? 保留旧日志文件数量。
- 追问:生产日志放哪里? 容器 stdout + 平台采集,或传统部署滚动文件 + logrotate。
- 追问:日志中敏感信息怎么办? 采集前脱敏,避免记录秘密。
八、加强记忆
日志轮转记成“别让日志无限长”。按大小用 RotatingFileHandler,按时间用 TimedRotatingFileHandler;多进程和容器场景要考虑平台采集,别只在 Python 里硬滚文件。日志还要有保留策略和脱敏,能排障也要守住安全边界。