Flask日志按天滚动需用TimedRotatingFileHandler并设when='D',清除默认handler防重复,预建logs目录、指定utf-8编码,backupCount控制归档数量,注意滚动基于24小时而非零点。

Flask 应用日志按天滚动的关键是 TimedRotatingFileHandler
Flask 本身不管理日志滚动,得靠 Python 标准库的 logging 模块配合 TimedRotatingFileHandler。它支持按时间(秒/分/时/天)切分日志文件,when='D' 就是按天滚动的核心参数。
常见错误是直接用 RotatingFileHandler —— 它只按文件大小切,和“按天”无关;还有人误设 when='midnight',其实这个值已废弃,应统一用 'D'。
-
backupCount=7表示最多保留最近 7 天的日志(如app.log、app.log.2024-05-20、app.log.2024-05-19…) -
encoding='utf-8'必须显式指定,否则中文日志可能乱码 - 日志文件名不能带扩展名变量(比如别写成
app.log.%Y-%m-%d),TimedRotatingFileHandler会自动在后面追加日期后缀
如何把 TimedRotatingFileHandler 正确集成进 Flask
必须在 Flask 应用实例创建后、首次记录日志前完成 handler 配置,否则 Flask 的默认 StreamHandler 会抢跑,导致日志重复或丢失。
推荐在应用工厂函数里做,避免全局作用域污染:
立即学习“Python免费学习笔记(深入)”;
图片提示词生成器?不止如此。 马甲系统 —— 把脑海中的画面,翻译成AI能理解的专业表达。 用得越多,它越懂你:首次需要多问几句确认方向,用久了几乎一说就懂。 用得越多,它越快:缓存机制让后续对话越来越省。 RAG进化:成功案例持续入库,越跑越聪明。 输入「新手指南」查看完整功能介绍
import logging
from logging.handlers import TimedRotatingFileHandler
from flask import Flask
<p>def create_app():
app = Flask(<strong>name</strong>)</p><pre class='brush:python;toolbar:false;'># 清除 Flask 默认的 handler(防止重复输出)
app.logger.handlers.clear()
# 创建按天滚动的 handler
handler = TimedRotatingFileHandler(
filename='logs/app.log',
when='D',
interval=1,
backupCount=7,
encoding='utf-8',
delay=False
)
handler.setFormatter(logging.Formatter(
'%(asctime)s %(levelname)s %(name)s %(message)s',
datefmt='%Y-%m-%d %H:%M:%S'
))
app.logger.addHandler(handler)
app.logger.setLevel(logging.INFO) # 注意:这里设的是 logger 级别,不是 handler 级别
return app注意:delay=True 会导致首次写日志时才创建文件,但若应用启动即写日志(如记录启动时间),建议保持 delay=False。
TimedRotatingFileHandler 按天滚动的几个坑
最常踩的坑不是代码写错,而是环境和行为理解偏差:
- 滚动触发时机不是“每天零点”,而是“距上次创建/滚动后满 24 小时”。例如首次运行在 5 月 20 日 14:00,下次滚动就在 5 月 21 日 14:00,不是凌晨。要严格零点滚动,得配
atTime=datetime.time(0, 0, 0) - Windows 下如果日志文件被其他进程占用(比如用记事本打开过),滚动会失败并静默丢弃日志 —— 生产环境务必关闭所有手动打开日志文件的行为
-
backupCount是指 *归档文件数*,不包括当前app.log。设为 7 实际最多有 8 个文件(1 个当前 + 7 个历史) - 重启应用不会强制触发滚动,滚动只由 handler 内部定时器驱动;但长时间不写日志,定时器可能延迟触发,首次写入时才补上
要不要加 WatchedFileHandler 或第三方轮子?
一般不用。有人听说 “Linux 下 logrotate 可以重命名日志文件”,担心 TimedRotatingFileHandler 会失效,于是想套一层 WatchedFileHandler 监控文件变化 —— 这反而增加复杂度且无必要。
TimedRotatingFileHandler 在大多数部署场景下足够健壮,只要确保:
- 日志目录存在(启动前
os.makedirs('logs', exist_ok=True)) - 应用有该目录的读写权限(尤其容器或 systemd 服务中容易忽略)
- 不手动 touch/mv 日志文件(交给 handler 自己管理)
真正需要额外轮子的情况极少,比如要求精确到秒级滚动、或需压缩归档(TimedRotatingFileHandler 不压缩,得自己封装或换 ConcurrentLogHandler 类库)。

















