查看: 101|回复: 3

Python TimedRotatingFileHandler日志切割详

[复制链接]
发表于 1 小时前 | 显示全部楼层 |阅读模式
在Python的logging模块中,TimedRotatingFileHandler是一个按时间自动切割日志文件的处理器,适合长期运行的生产环境服务。它能每天、每小时甚至每分钟生成新日志文件,并通过backupCount控制历史数量,避免磁盘被日志占满。本文将详细讲解其参数含义、使用方式以及实际开发中常遇到的坑。
  1. import logging
  2. from logging.handlers import TimedRotatingFileHandler
  3. logger = logging.getLogger("my_logger")
  4. logger.setLevel(logging.INFO)
  5. handler = TimedRotatingFileHandler(
  6.     filename="app.log",
  7.     when="midnight",
  8.     interval=1,
  9.     backupCount=7,
  10.     encoding="utf-8"
  11. )
  12. handler.setFormatter(logging.Formatter("%(asctime)s - %(levelname)s - %(message)s"))
  13. logger.addHandler(handler)
  14. logger.info("这是第一条日志")
复制代码

上述代码实现了每天凌晨切割日志,并保留最近7天的历史文件。

参数详解

构造方法签名为:
  1. TimedRotatingFileHandler(filename, when='h', interval=1, backupCount=0, encoding=None, delay=False, utc=False)
复制代码


  • filename:当前写入的日志文件名,切割后该文件会被重命名(加上日期后缀),然后创建新的同名文件继续写入。
  • when:最重要的参数,决定切割的时间单位。支持的值:
      - 'S':每秒
      - 'M':每分钟
      - 'H':每小时
      - 'D':每天
      - 'W0'~'W6':周一至周日(注意:按周切割时底层会转为midnight,当周为interval的倍数时触发)
      - 'midnight':每天午夜(00:00)切割,与'D'效果类似但更精确
  • interval:与when配合,例如when='H', interval=6表示每6小时切割一次。
  • backupCount:保留的历史日志文件数量,超过旧文件会被自动删除。例如backupCount=7,目录中最多有7个历史文件加上当前文件。
  • encoding:强烈建议设置为'utf-8',避免中文乱码。
  • utc:默认False,使用本地时间;设为True则使用UTC时间决定切割时机。


日志文件命名规则
当filename="app.log"时,切割后昨天生成的文件会被重命名为app.log.2026-04-26(根据日期),当前文件始终保持为app.log。不会自动给当前文件加日期后缀。

结合logging.basicConfig使用
如果想简化配置,可以直接在basicConfig中传入handlers列表:
  1. import logging
  2. from logging.handlers import TimedRotatingFileHandler
  3. logging.basicConfig(
  4.     level=logging.INFO,
  5.     handlers=[
  6.         TimedRotatingFileHandler("app.log", when="D", interval=1, backupCount=15, encoding="utf-8")
  7.     ],
  8.     format="%(asctime)s - %(levelname)s - %(message)s"
  9. )
  10. logging.info("服务启动")
复制代码

同时输出到控制台和文件(推荐)
生产环境通常需要既看终端又存文件:
  1. logger = logging.getLogger()
  2. logger.setLevel(logging.INFO)
  3. file_handler = TimedRotatingFileHandler("app.log", when="midnight", backupCount=7, encoding="utf-8")
  4. console_handler = logging.StreamHandler()
  5. formatter = logging.Formatter("%(asctime)s - %(levelname)s - %(message)s")
  6. file_handler.setFormatter(formatter)
  7. console_handler.setFormatter(formatter)
  8. logger.addHandler(file_handler)
  9. logger.addHandler(console_handler)
复制代码

常见坑与注意事项

1. 多进程写同一个日志文件
   TimedRotatingFileHandler不保证多进程安全,多个进程同时写入会导致日志混乱或文件损坏。
   解决方案:每个进程使用独立日志文件,或使用ConcurrentLogHandler(第三方库),或在Linux下借助logrotate系统工具切割。

2. 修改系统时间导致切分异常
   如果在运行中修改系统时间(比如回拨),可能导致切割逻辑出错,出现重复或丢失日志文件。Docker/K8s环境应确保容器时间同步。

3. 日志不立即写入
   默认有缓冲(buffer),调试时可以手动调用handler.flush()强制写入。

适用场景

适合:Web服务、后台任务、定时任务等长期运行的程序。
不适合:超大日志量(建议按大小切割的RotatingFileHandler),以及多进程并发写同一文件(需要外部工具辅助)。

TimedRotatingFileHandler的核心价值在于:按时间自动切分日志 + 控制历史数量,用最少的代码实现日志文件的自管理。
回复

使用道具 举报

发表于 1 小时前 | 显示全部楼层

Re: Python TimedRotatingFileHandler日志切割详

感谢分享,非常详细的讲解!你提到的“多进程写同一文件”这个坑我之前踩过,后来用了ConcurrentLogHandler才解决。另外关于`when="midnight"`和`when="D"`的区别,以前一直以为一样,原来`midnight`更精确,学到了。想请教一下:如果日志量特别大,每天切割会产生大量小文件,有没有比较推荐的策略?比如按小时切割并配合`backupCount`控制总量,会不会更合适?
回复 支持 反对

使用道具 举报

发表于 1 小时前 | 显示全部楼层

Re: Python TimedRotatingFileHandler日志切割详

感谢楼主这么详尽的分享!正好最近在优化一个长期运行的定时任务日志,准备从普通FileHandler换成TimedRotatingFileHandler,这篇帖子太及时了。 关于“修改系统时间导致切分异常”这个坑之前没太注意,您提醒后确实该在容器部署时确保NTP同步。另外我有个小疑问:如果when设为'W0'(周一),backupCount设成4,按周切割的话,是保留最近4周的周一文件还是按自然周数量保留?希望楼主或其他朋友指点一下。再次感谢!
回复 支持 反对

使用道具 举报

发表于 1 小时前 | 显示全部楼层

Re: Python TimedRotatingFileHandler日志切割详

感谢楼主详细的讲解,特别是参数定义和常见坑的部分非常实用。我之前也遇到过修改系统时间导致日志切割错乱的情况,确实需要小心。另外想请教一下,在多进程写同一日志文件时,除了改用第三方库或系统 logrotate,有没有什么轻量级的做法,比如用 SocketHandler 把日志统一发到单进程处理?期待更多经验分享。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

指导单位

江苏省公安厅

江苏省通信管理局

浙江省台州刑侦支队

DEFCON GROUP 86025

Hacking Group 021A

旗下站点

态势感知中心

应急响应中心

红盟安全

联系我们

官方QQ群:112851260

官方邮箱:security#ihonker.org(#改成@)

官方核心成员

关注微信公众号

Archiver|手机版|小黑屋| ( 沪ICP备2021026908号 )

GMT+8, 2026-7-9 12:53 , Processed in 0.031046 second(s), 18 queries , Gzip On, Redis On.

Powered by ihonker.com

Copyright © 2015-现在.

  • 返回顶部