最稳妥方式是用os.path.getmtime()获取文件修改时间戳,与time.time()比较判断是否超7天;遍历需过滤子目录、隐藏文件及非日志后缀;删除前启用dry-run预览,捕获permissionerror和filenotfounderror异常,逐个安全删除。

用 os.path.getmtime() 获取文件最后修改时间
判断日志是否过期,核心是拿到文件的最后修改时间戳。Python 标准库中 os.path.getmtime() 最直接——它返回浮点数(秒级时间戳),和 time.time() 单位一致,方便做减法比较。
注意别误用 os.path.getctime():在 Linux/macOS 上它是“元数据变更时间”,不是创建时间;Windows 上才是创建时间,但日志轮转后这个值通常不变,不可靠。
- 对每个日志文件调用
os.path.getmtime(file_path) - 用
time.time() - mtime > 86400 * 7判断是否超过 7 天(86400 秒/天) - 如果文件被其他进程占用(如正在写入),
getmtime()仍能成功,不影响判断
遍历目录时避开子目录和非日志文件
实际日志目录里常混着 .tmp、archive/ 子目录或配置文件,全删会出事。推荐用 os.listdir() + 手动过滤,比 glob 或 pathlib.rglob() 更可控。
典型日志命名如 app.log.2024-05-10、debug.log.gz,可用后缀或正则筛:
- 只处理以
.log、.log.gz、.out结尾的文件:file.endswith(('.log', '.log.gz', '.out')) - 跳过目录:
if os.path.isdir(os.path.join(root, name)):continue - 避免误删隐藏文件(如
.gitignore):if name.startswith('.'):continue
删除前加 dry-run 模式和异常捕获
线上环境执行 os.remove() 前必须能预览要删什么。硬编码开关不如命令行参数灵活:
import sys dry_run = '--dry-run' in sys.argv
真正删除时,PermissionError 和 FileNotFoundError 最常见——前者因日志被服务进程独占写入(尤其 Windows),后者是并发中文件已被其他脚本删掉。都该显式捕获:
try: os.remove(path) except (PermissionError, FileNotFoundError): pass- 不要用
os.unlink()替代os.remove():二者行为一致,但remove()语义更清晰 - 删完建议打印简短日志:
print(f"Deleted {path}") if not dry_run else print(f"[DRY] {path}")
单文件处理比批量 shutil.rmtree() 更安全
有人想图快用 shutil.rmtree(log_dir) 再重建空目录,这是高危操作——万一路径拼错(比如多一个 /),可能清空父级目录。过期清理本质是“选中+逐个删”,不是重置目录。
另外,shutil.rmtree() 对正在被写入的日志文件会直接失败(抛 PermissionError),而单文件 os.remove() 可跳过并继续,容错性更好。
真正的性能瓶颈不在 Python 删除动作本身,而在磁盘 I/O 和文件系统锁。如果日志量极大(如每秒生成百个文件),可考虑加 time.sleep(0.001) 避免瞬时 I/O 峰值,但多数场景不需要。
时间戳判断本身没坑,坑都在路径处理和权限上——删错目录比删慢几秒严重得多。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











