Python 定时清理过期日志文件实战:用 pathlib 安全删除旧文件

举报
yd_70403235 发表于 2026/11/04 09:10:44 2026/11/04
【摘要】 服务跑久了日志越积越多,手动删怕误删正在写入的当天日志。本文用 pathlib 写一个清理脚本:只删超过保留天数的旧日志,默认先演练打印清单,确认后才真正删除,并附本地实测结果与注意事项。

Python 定时清理过期日志文件实战:用 pathlib 安全删除旧文件

背景

服务跑久了,日志目录总会越长越大:一次请求一条访问日志、一天一个滚动文件,几个月下来磁盘就被吃掉不少。手动删又怕误删正在写入的当天日志。办法是写一个小脚本:只删“超过保留天数”的旧文件,目录本身不动,正在写的文件不动,删之前先打印清单,确认无误再真正删除。

实现思路

  1. 用 pathlib.Path 遍历目标目录,只匹配指定后缀的日志文件;
  2. 用 stat().st_mtime 判断文件最后修改时间,超过保留天数才进入待删清单;
  3. 默认只打印清单(演练模式),确认后加 --confirm 才真正删除;
  4. 删除失败的单个文件只记错误,不中断整个清理;
  5. 可以配合操作系统的定时任务每天跑一次。

代码

import argparse
import time
from pathlib import Path


def find_expired(log_dir: Path, days: int, suffix: str = ".log") -> list[Path]:
    """返回修改时间超过 days 天的日志文件,按修改时间从旧到新排序。"""
    cutoff = time.time() - days * 24 * 3600
    expired = [
        p
        for p in log_dir.iterdir()
        if p.is_file() and p.suffix == suffix and p.stat().st_mtime < cutoff
    ]
    return sorted(expired, key=lambda p: p.stat().st_mtime)


def main() -> None:
    parser = argparse.ArgumentParser(description="清理过期日志文件")
    parser.add_argument("log_dir", help="日志目录")
    parser.add_argument("--days", type=int, default=30, help="保留天数,默认 30")
    parser.add_argument("--confirm", action="store_true", help="真正删除,否则只打印清单")
    args = parser.parse_args()

    log_dir = Path(args.log_dir)
    if not log_dir.is_dir():
        raise SystemExit(f"目录不存在:{log_dir}")

    expired = find_expired(log_dir, args.days)
    if not expired:
        print(f"{log_dir} 中没有超过 {args.days} 天的日志文件")
        return

    total_size = sum(p.stat().st_size for p in expired)
    print(f"共 {len(expired)} 个过期文件,合计 {total_size} 字节:")
    for p in expired:
        print(f"  {p.name}")

    if not args.confirm:
        print("演练模式:未删除任何文件,加上 --confirm 才会真正删除")
        return

    deleted, failed = 0, 0
    for p in expired:
        try:
            p.unlink()
            deleted += 1
        except OSError as exc:
            failed += 1
            print(f"删除失败 {p.name}:{exc}")
    print(f"已删除 {deleted} 个,失败 {failed} 个")


if __name__ == "__main__":
    main()

验证结果

本地实测(Python 3.12):在临时目录新建 4 个 .log 文件,其中 2 个把修改时间改成 40 天前、1 个改成 10 天前、另放 1 个 .txt 文件做对照。运行演练模式只列出 2 个 40 天前的文件,10 天前的文件和 .txt 文件都不在清单里;加 --confirm 后只删了那 2 个文件,目录里其余文件完好;再次运行提示“没有超过 30 天的日志文件”。传入不存在的目录时脚本直接报错退出,不会误删。

注意事项

  • 不要用 rm -rf 式通配删除:先演练、再确认,清单里出现当天文件要立刻停下来排查时间判断逻辑。
  • 只按后缀匹配还不够:如果日志按日期滚动命名(如 app-2026-11-01.log),也可以在文件名里再加一层日期校验,避免同名不同类文件被误删。
  • 正在写入的文件一般修改时间就是现在,不会进入过期清单;但如果服务异常停写超过保留天数,脚本仍可能删掉它,重要日志先备份再清理。
  • 定时任务里建议把脚本输出重定向到一个清理日志文件,方便事后核对删了什么、删了多少。
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。