应使用 shutil.disk_usage() 直接读取指定路径(如 "/")获取 total、used、free 字节值,以 used/total 计算百分比并整数化;配合异常捕获、时间戳日志、SMTP 连通性预检、主机名与路径标识、动态阈值(如连续三次≥85%且递增)及告警限频。

用 shutil.disk_usage() 获取磁盘使用率,别碰 os.statvfs()
直接读取根路径的使用率是最稳妥的方式,shutil.disk_usage() 返回 total、used、free 三个字节值,计算准确且跨平台。Linux 下有人试过 os.statvfs("/"),但它的 f_blocks 和 f_bavail 受 reserved blocks 影响,普通用户看到的可用空间和它算出来经常对不上,预警阈值一设就误报。
实操建议:
- 监控点明确指定路径,比如
"/"或"/var/log",不要依赖自动发现——不同服务器挂载结构差异大,硬编码反而稳定 - 计算使用率用
used / (total - used)(即used / total的补集),不是used / free,后者数值会爆表 - 结果统一转成百分比整数,方便后续比较:
int(100 * usage.used / usage.total)
用 time.sleep(60) 轮询比系统级定时任务更可控
脚本常驻运行时,用 while True: + time.sleep() 比依赖 cron 更利于调试和状态追踪。cron 每分钟拉起新进程,旧进程残留、日志混杂、内存不释放,出问题难定位。
注意点:
立即学习“Python免费学习笔记(深入)”;
- sleep 时间别设太短(如 5 秒),频繁调用
shutil.disk_usage()对 IO 压力小,但日志刷屏、网络上报频次高,容易淹没真问题 - 必须加异常捕获:磁盘突然卸载、权限丢失、NFS 挂载点卡死都会让
disk_usage()抛OSError,不 catch 就退出 - 每次循环开头打个时间戳日志,比如
print(f"[{datetime.now().isoformat()}] checking /"),排查延迟或卡死时有依据
发邮件预警前先验证 SMTP 连接,避免告警静默
很多脚本写了 smtplib.SMTP() 却没做 connect() 和 login() 的连通性测试,结果磁盘爆了,邮件根本发不出去——你以为配置好了,其实密码过期或端口被封。
实操建议:
- 启动时立刻试连一次 SMTP,失败就
sys.exit(1),不等告警时刻才暴露问题 - 邮件内容里必须带主机名(
socket.gethostname())和触发路径,不然收件人打开十台服务器告警,分不清是哪台的/home还是/data满了 - 别用明文密码:改用应用专用密码(如 Gmail App Password)、或从环境变量读
os.getenv("SMTP_PASS"),别硬编码在脚本里
超过 90% 就预警?得看分区用途和增长节奏
固定阈值(如 90%)在日志盘上可能刚够用,在数据库数据盘上已经算危险。真正要关注的是「连续三次检测都上升且超 85%」,或者「24 小时内增长超 20GB」这类动态信号。
简单实现思路:
- 维护一个长度为 3 的列表记录最近三次使用率,用
collections.deque(maxlen=3)自动丢旧存新 - 当当前值 > 85 且列表里所有值都 ≥ 前一个值(单调递增),再触发预警——过滤掉临时文件写入又清理的毛刺
- 额外记一个上次告警时间戳,两次告警至少间隔 2 小时,避免磁盘卡死时每分钟一封邮件轰炸
阈值逻辑永远要和运维同学对齐:DBA 可能要求数据盘 75% 就叫人,而备份盘允许撑到 95%,脚本里留好配置入口比写死数字强得多。

















