用rotatingfilehandler无法按天切日志,必须改用timedrotatingfilehandler;关键需设when="d"、attime=time(0,0)实现自然日切割,显式指定suffix与extmatch匹配日期格式,并在多进程场景下使用logrotate或concurrent-log-handler避免冲突。

为什么用 RotatingFileHandler 不行?
直接用 RotatingFileHandler 按大小滚动,没法按天切——它不识别日期,只看文件体积或数量。想每天一个日志文件(比如 app.log.2024-05-20),得换 TimedRotatingFileHandler。
TimedRotatingFileHandler 的关键参数怎么设?
核心是 when 和 interval,不是随便填个 "D" 就能准时切。常见错误是日志没在 00:00 切,而是按首次写入时间 +24 小时滚动。
-
when="D":按日滚动,但起始点是第一次调用handler.emit()的时间点 - 要真正按自然日(00:00)切,必须加
atTime=datetime.time(0, 0) -
backupCount=7控制保留最近 7 天,旧文件会被自动删除 - 注意时区:如果服务器用 UTC,而你要按本地时间切,得手动处理
atTime偏移
文件名带日期后缀但不覆盖,怎么确保格式统一?
默认滚动后文件名是 app.log.2024-05-20,但如果你看到 app.log.2024-05-20.1 或乱序数字后缀,说明 suffix 和 extMatch 没配对。
- 显式指定
suffix="%Y-%m-%d"(推荐) - 同时重写
extMatch正则,匹配该格式:handler.extMatch = re.compile(r"^\d{4}-\d{2}-\d{2}$") - 否则旧日志可能被当成无效备份删掉,或新文件名被误判导致切割失败
多进程下日志切割会冲突吗?
会。Python 标准库的 TimedRotatingFileHandler 不做进程间同步,多个进程同时触发切割,可能丢日志、文件被覆盖、甚至抛 OSError: [Errno 13] Permission denied。
- 单进程应用放心用;多进程(如 Gunicorn 多 worker)必须配合外部工具,比如
logrotate+copytruncate - 或者改用
concurrent-log-handler第三方包,它用文件锁规避竞争 - 别指望靠
delay=True或重试逻辑解决——底层是竞态,不是延迟问题
按天滚动看着简单,但时区、多进程、文件名正则这三个点,任何一个漏掉都会让日志“看起来在转,其实乱了”。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











