应优先依据日志文件名中的日期解析为datetime对象判断过期,而非依赖修改时间;需适配不同命名格式提取日期,再与当前时间减30天比较;删除前须确认文件未被占用,避免直接删除活跃日志导致丢失。

直接删掉比保留更安全,但必须用 datetime 算真实过期时间,不能只靠文件名或 os.path.getmtime() 判断。
用 datetime 解析日志文件名中的日期再比较
很多日志按 app-2024-03-15.log 或 error_20240315.txt 命名,靠文件名最可靠——因为写入时间可能被 touch 修改,而日志内容本身的时间戳才是业务意义上的“生成时间”。
- 先用
re.search(r'(\d{4}-\d{2}-\d{2})', filename)或re.search(r'(\d{8})', filename)提取日期字符串 - 再用
datetime.strptime(date_str, '%Y-%m-%d')或datetime.strptime(date_str, '%Y%m%d')转成日期对象 - 和
datetime.now() - timedelta(days=30)比较,小于即为过期 - 注意:不同日志命名格式要单独适配,别指望一个正则通吃所有项目
避免误删:跳过正在写入的活跃日志文件
直接 os.remove() 正在被 logging.FileHandler 写入的文件,在 Linux 可能没报错但导致后续日志丢失;Windows 下常抛 PermissionError。得先确认文件是否“空闲”。
- 用
os.open(path, os.O_RDWR | os.O_NONBLOCK)尝试非阻塞打开,失败说明被占用(慎用,部分系统不支持) - 更稳妥的是检查文件修改时间是否在最近 5 秒内:
(datetime.now() - datetime.fromtimestamp(os.path.getmtime(path))).seconds ,是则跳过 - 或者加白名单:把
app.log、current.log这类固定名称列入keep_list = ['app.log', 'latest.log']
批量删除前务必加 dry-run 模式
线上环境执行 os.remove() 前不验证路径和权限,等于给磁盘装了定时炸弹。
立即学习“Python免费学习笔记(深入)”;
- 默认行为应是打印将删哪些文件,不真删;加
--force参数才执行删除 - 用
pathlib.Path(file).resolve()获取绝对路径并校验是否存在、是否为文件(不是目录)、是否有读/写权限 - 对每个待删文件,先
print(f"[DRY] Would remove: {file}"),确认无误再切到真实模式 - 错误日志统一捕获
PermissionError和FileNotFoundError,不要让一个文件失败中断整个清理流程
真正难的不是写删除逻辑,而是搞清“过期”的定义:是日志里最后一条记录的时间?文件名日期?还是首次创建时间?三者不一致时,业务方必须明确选哪一种——代码没法替人做这个决定。


















