Python使用TimedRotatingFileHandler启动脚本时如何删除旧日志
问题根因
TimedRotatingFileHandler的backupCount自动清理逻辑,只会在实际触发日志轮转动作的时候执行。该类的运行逻辑是:每次写入日志时先判断是否到了轮转时间点,如果到了,就先完成当前日志文件的切分,再调用内部的清理方法把超出保留份数的旧备份删掉。
由于脚本单次运行仅5分钟,从来不会在00:00轮转节点保持运行,轮转事件从未被触发,对应的清理逻辑自然不会执行,旧日志就会持续堆积无法被自动清理。
最省事的实现方案
不需要自己从零写文件匹配、时间排序、批量删除的逻辑,直接复用TimedRotatingFileHandler内部已经实现好的清理判断方法即可。
这种方案的优势是和原有日志轮转的清理规则100%对齐,不需要单独维护匹配、排序、计数的逻辑,避免出现自己写的规则和handler实际轮转规则不一致的问题。
具体操作步骤:
- 按照原有代码逻辑完成TimedRotatingFileHandler的初始化
- 初始化完成后,直接调用该handler实例自带的
getFilesToDelete()方法,拿到所有符合清理规则的旧日志路径列表 - 遍历列表逐个删除文件,加上异常捕获避免清理失败影响脚本运行
示例代码:
import os import logging import logging.handlers log_dir = "/your/log/directory" log_fn = "your_app.log" backup_count = 3 # 原有handler初始化逻辑完全保留 hdlr = logging.handlers.TimedRotatingFileHandler( os.path.join(log_dir, log_fn), when="midnight", backupCount=backup_count, encoding="utf-8" ) # 新增启动时主动清理逻辑 old_file_list = hdlr.getFilesToDelete() for file_path in old_file_list: try: os.remove(file_path) except OSError as e: # 清理失败仅记录日志,不阻断脚本启动 logging.error(f"旧日志清理失败,文件路径: {file_path}, 错误: {e}")
自定义实现的注意事项
如果不想依赖handler内部方法,打算自己写清理逻辑,需要严格匹配原有轮转规则的要求,避免出现误删:
- 仅筛选日志目录下符合轮转命名规则的备份文件(即文件名格式为
{原日志名}.{时间戳后缀}的文件,比如your_app.log.2024-05-20),不要把目录下其他无关的日志文件纳入清理范围 - 排序时按照备份文件的时间戳从新到旧排列,严格按
backupCount设置的数量保留最新的几份备份,其余旧文件删除 - 不要把当前正在被写入的主日志文件算入备份保留计数
- 删除操作必须加异常捕获,不能因为文件被占用、权限不足等问题导致脚本启动失败
内容的提问来源于stack exchange,提问作者Ken Nieh
相关产品推荐
相关产品推荐

