先给结论,再给明细
一、先给结论,再给明细
体检脚本最常见的失败方式,是输出一屏 200 行的「全部正常」。人只在两种时候打开它:早上扫一眼,或者线上出事了翻它。这两种场景都没有耐心。
所以第一行必须是结论,格式固定到可以 grep:
healthcheck: 2 FAIL, 1 WARN, 15 OK / 18 checks, 2.4s
第二段只列异常项,四列对齐:状态、检查项 id、实测值、阈值:
[FAIL] disk.usage /data 93% > 90%[WARN] load.1m 7.8 > 6.0
正常项收进 --verbose。对齐不要手动拼空格,用 printf "%-6s %-22s %s\n";颜色只在 [ -t 1 ] 成立时启用 ANSI,重定向到文件时自动变干净。
二、一份数据,两种渲染
采集和展示必须分离。每个检查函数不要 print,返回结构体:{ID, Status, Value, Threshold, Hint}。主流程收齐后交给渲染器,支持 --format=text|json|prometheus。
收益很实在:CI 里写 healthcheck --format=json | jq '.checks[] | select(.status!="OK")',早报直接读 json,Prometheus textfile collector 复用同一份数据。在 check 函数里混着 echo 和判断,是这类脚本三个月后没人敢改的主因。
Hint 字段不要省:FAIL 时直接给出下一步命令,比如 journalctl -u nginx --since -10min,比写「请检查服务状态」有用一百倍。
三、每个检查项都要能单独失败
单项超时:timeout 3 stat /mnt/nfs。NFS 挂住的时候,一个 stat 能把整个体检拖到五分钟,最后被 cron 的 MAILTO 淹没。
单个 check 的 panic 必须 recover,记成 ERROR 而不是让脚本整体退出:你有 18 项检查,不该因为第 3 项的空指针丢掉后面 15 项的结果。
并发要有上限,worker pool 开到 8 就够。见过有人 xargs -P 64 同时打 64 个 SSH,把堡垒机打到限流,体检自己变成了故障。
外部命令先 command -v 探测,缺 ss 或 smartctl 时记 SKIP 并写明原因,而不是刷一屏 command not found。
四、检查项是注册表,不是 if 堆
把检查项做成注册表。Go 里就是 Register("disk.usage", SeverityWarn, checkDisk),Python 用装饰器往 list 里塞。加一项新检查 = 写一个函数 + 一行注册,主流程一行不动。
两条纪律:id 一旦发布就别改名,否则历史 diff 全乱;severity 跟退出码绑定,WARN 进早报,FAIL 直接非零退出,别让调用方去猜。
五、让它能被对比
把上次结果存到 /var/lib/healthcheck/last.json,跑完做 diff,单独输出一段:
since last run (2h ago): +2 new, -1 recovered
「新增异常」比「当前有异常」信息密度高得多:磁盘 85% 挂了三个月没人管,从 85% 涨到 93% 才是要动手的信号。
退出码写进 README:0 全 OK,1 有 WARN,2 有 FAIL。CI 里 if healthcheck; then ... 就能直接用。最后,阈值外置到配置文件,别在代码里写死 80:同一份脚本要跑在 4C8G 的跳板机和 64C256G 的数据库上,硬编码的阈值只能服务其中一台。
- 点赞
- 收藏
- 关注作者
评论(0)