配置 Flask 日志按天切割需使用 Python 标准库 logging.handlers 中的 TimedRotatingFileHandler,将其绑定到 app.logger。
适用场景为生产环境长期运行的服务,风险边界在于日志目录权限不足会导致启动报错。
先说结论:使用 Python 标准库的 TimedRotatingFileHandler 是最稳定方案,无需额外依赖。
- 适合:需要长期保留历史日志且希望自动归档的 Flask 应用
- 先准备:确保日志写入目录存在且进程有写权限
- 验收:观察午夜过后是否生成带日期的新日志文件
命令速用版
以下是最小化配置代码,可直接嵌入 Flask 应用初始化流程:
import logging
from logging.handlers import TimedRotatingFileHandler
handler = TimedRotatingFileHandler('app.log', when='D', interval=1, backupCount=7, encoding='utf-8')
handler.setLevel(logging.INFO)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
app.logger.addHandler(handler)
app.logger.setLevel(logging.INFO)为什么会这样
Python 的 logging 模块原生支持时间切割,Flask 的 app.logger 本质是标准 logging.Logger 实例。
TimedRotatingFileHandler 会在指定时间间隔到达时关闭当前文件并重命名,新建文件继续写入,无需外部脚本干预。
分步处理
步骤 1:导入模块
在应用入口文件导入 logging 和 TimedRotatingFileHandler,适用所有 Python 环境。
步骤 2:创建处理器
实例化 TimedRotatingFileHandler,参数 when='D' 表示按天,interval=1 表示每天,backupCount 控制保留文件数。
风险边界:路径不存在会报错,需先 os.makedirs 创建目录。
步骤 3:设置格式与级别
绑定 Formatter 定义日志内容格式,设置 setLevel 控制记录门槛,避免记录过多 DEBUG 信息占用磁盘。
步骤 4:绑定_logger
使用 app.logger.addHandler 将处理器加入 Flask 日志系统,确保请求上下文中的日志能正确输出。
怎么验证是否生效
运行应用并触发日志记录,检查指定目录下是否生成日志文件。
验证动作:修改系统时间跨越午夜或等待自然时间到达,观察是否生成 app.log.日期后缀 的新文件。
验证结果:原日志文件停止写入,新文件开始接收日志,旧文件数量不超过 backupCount 设定值。
常见坑
1. 目录权限问题:Linux 下运行用户无权写入日志目录会导致服务启动失败。
2. 多进程重复日志:使用 Gunicorn 等多进程部署时,每个 worker 都会加载配置,可能导致日志重复写入,需在配置中判断主进程或使用中央日志服务。
3. 编码错误:Windows 下默认编码可能非 utf-8,显式指定 encoding='utf-8' 避免乱码。
常见问题
多进程部署下日志会重复吗?
会重复。每个 worker 进程都会实例化一个 Handler,建议只在主进程添加 Handler 或使用 QueueHandler 集中收集。
如何清理旧日志文件?
通过 backupCount 参数限制保留数量,超出部分会被自动删除,无需额外清理脚本。
支持按小时切割吗?
支持。将 when 参数改为 'H',interval 设为需要的小时数即可。
参考来源
- Python Official Documentation - logging.handlers: https://docs.python.org/3/library/logging.handlers.html
- Flask Documentation - Logging: https://flask.palletsprojects.com/en/latest/logging/