先想清楚谁会读,再决定输出长什么样
先想清楚谁会读,再决定输出长什么样
体检脚本的读者其实有三类:凌晨被叫起来处理故障的人、每周扫一眼趋势的人、三个月后接手这台机器的人。这三类人都不看“正在检查 CPU... 完成”这种流水账。所以输出固定分三段:结论行、明细、建议。结论行放在第一行,格式定死:
SUMMARY host=web-03 role=api ver=1.4.2 ok=12 warn=2 fail=1 cost=3.8s
这行能被 grep、能被日志系统按字段切分、能在巡检平台上画成趋势图。明细里每条检查一行,用 printf '%-6s %-22s %s\n' 对齐,级别在前、检查 ID 在中、信息在后。检查 ID 用 disk.root.usage 这种英文键,不用中文描述——中文描述会改,键不能改,否则抑制规则和历史数据全都对不上。
用级别和汇总压住噪声
只输出“有问题”的检查,脚本会安静得让人忘记它的存在;把所有检查都打出来,两周后没人再看。折中做法是四级:OK / INFO / WARN / FAIL,默认只打印 WARN 及以上,加 --verbose 才展开全部。阈值全部从配置文件读,不写死在代码里,例如 disk.root.usage.warn=80、disk.root.usage.fail=92,这样不同角色的机器可以共用一份脚本、各自的阈值。
- 同一类问题合并计数,不要 200 个挂载点刷 200 行,输出
disk.mount.usage 3 mounts over 80%: /var /data /opt。 - 慢检查必须包超时:
timeout 5 smartctl -H /dev/sda,超时记为INFO而不是让整个脚本卡死。 - 脚本自身耗时打进 SUMMARY,超过 30 秒说明某个检查该拆出去了。
稳定排序与稳定 diff,让输出可比
检查一旦并行执行,结果顺序就是随机的,人眼每次都要重新扫一遍,久了就不看了。所以输出前按检查 ID 字典序排一次;时间戳统一成固定时区(比如全部 UTC),不要混用本地时间。更进一步,把本次结果落到 /var/lib/check/last.json,下次运行时做 diff,只报新增的问题和已恢复的问题:
NEW disk.root.usage 83% > 80%FIXED disk.inode.usage 已回落到 61%
这一步是长期可读性的关键——读者关心的是“变了什么”,而不是“现在是什么”。另外记得判断颜色:[ -t 1 ] 为真才上色,输出重定向到文件或管道时保持纯文本,否则日志里全是 ANSI 转义符。
把“发现问题”升级成“给出下一步”
最容易被忽略的一行是建议。同样的 disk.root.usage,写“磁盘使用率过高”等于没说,写成下面这样就有人愿意看:
建议:清理 /var/log 下 7 天前的 *.gz,预计释放 2.1G;操作手册 runbook#12建议:inode 偏高但空间充足,检查 /data/tmp 的小文件堆积
建议不用覆盖所有检查,先把历史工单里排名前十的故障各写一条,剩下的留空也比写套话好。另外输出里不要出现密码、AK、完整内网地址,主机名和 IP 该脱敏的脱敏,体检脚本的日志经常被贴进群里。
让脚本自己安静下来:退出码与抑制
退出码要能直接被调度器用:0 全 OK,1 有 WARN,2 有 FAIL,3 脚本自身异常。别在 crontab 里随手写 || true,那等于把告警通道焊死。已知问题用带过期时间的抑制文件管理,而不是改代码:
disk.data.usage 2025-03-01 # 迁移中,扩容工单 OPS-4471
过期后自动恢复告警,避免“临时抑制”变成永久静音。做到这些,脚本才从一次性排查工具变成团队真的会长期打开的那一页。
- 点赞
- 收藏
- 关注作者
评论(0)