只在状态变化时告警:用 cron + 状态文件搭一套不吵人的轻量监控
凌晨三点服务挂了,你早上八点才发现。不是你收不到报警,而是过去一周每五分钟就有一条“一切正常”的推送,那个群早就被你静音了。
监控最难的部分从来不是采集指标,而是在不该说话的时候闭嘴。这篇文章记录一套只用 cron 和一个状态文件就能落地的做法:探针只做判定,状态写盘,只在状态翻转时输出。没有 Prometheus,没有告警平台,一台最低配的服务器就够。
一、先把“探针”和“告警”拆开
很多脚本的错误在于把两件事写在一起:检查、发现问题、顺手发消息。结果是脚本既是探针又是通知器,换一次通知渠道就要动检查逻辑,而且永远回答不了“这东西到底挂了多久”。
拆成三层就清爽了:
- 探针:只输出一个状态字符串,例如
healthy/unauthorized/unreachable; - 状态文件:记录上一次的状态和时间戳,用来去重、算持续时长;
- 通知器:只在状态变化时,把“新状态 + 上一条状态持续了多久”发出去。
二、最小可用实现
探针脚本 probe.sh,只做判定,退出码永远是 0:
#!/usr/bin/env bash
set -u
DIR=/var/lib/probe
mkdir -p "$DIR"
code=$(curl -s -o /tmp/body -w '%{http_code}' \
--max-time 8 https://127.0.0.1:5000/v1/api/health || true)
case "$code" in
200) state=healthy ;;
401|403) state="unauthorized" ;; # 鉴权接口:401 就是“没登录”
000|"") state="unreachable" ;;
*) state="http-$code" ;;
esac
last=$(cat "$DIR/last" 2>/dev/null || echo unknown)
if [ "$state" != "$last" ]; then
printf '%s' "$state" > "$DIR/last.tmp" && mv "$DIR/last.tmp" "$DIR/last"
printf '%s' "$(date +%s)" > "$DIR/since"
printf '%s %s -> %s\n' "$(date '+%F %T')" "$last" "$state" >> "$DIR/transitions.log"
echo "$state" # 只有这一行会变成手机上的推送
fi
有三个细节值得单独说:
1. 状态文件要原子写。 用 printf > tmp && mv,不要直接覆盖。读文件的那一瞬间如果正好写到一半,读到空内容会让下一次判定误以为“状态变了”,凭空制造一条假告警。
2. 退出码恒为 0。 大多数调度器把非零退出当成“任务失败”,于是你不仅收到业务告警,还额外收到一条“探针自己挂了”。把判断结果写在 stdout,把“我跑不动了”留给真正的异常路径。
3. HTTP 状态码先于响应体。 401/403 的 body 通常是空的,先当 JSON 解析再判断会得到“解析失败”,一个真实的鉴权故障就这样被伪装成了脚本 bug。先看 %{http_code},只有 200 才值得读 body。
三、接到 cron 上
*/5 * * * * /usr/local/bin/probe.sh >> /var/log/probe.log 2>&1
如果调度器支持“只有输出才通知”的脚本模式(stdout 为空就什么都不发),到这里就结束了:正常时零消息,翻转时一条。
如果不支持,加一层薄包装:把非空的 stdout 转成一次 webhook 调用。包装层不要写任何判断逻辑——判断只有一处,才不会有第二个真相。
四、把“观察”和“自愈”拆成两个任务
线上最危险的动作是“探针判断失败就自动重启、自动重新登录”。判断错的代价可能比故障本身更大:涉及账号鉴权的场景,连续失败重试会直接撞上风控,一次掉线被放大成账号锁定。
所以实际部署里我拆成两个任务:
- 观察任务:只读状态、只报变化,永远不执行修复。它的真正价值是测量——某个会话平均能活多久、失败集中在什么时段。这些数据决定了自愈到底值不值得做。
- 自愈任务:频率更低、动作更保守,一次只尝试一次,失败就停下来等人。
先跑一周观察、攒够数据,再决定要不要上自愈。顺序反过来,你会收获一堆“系统正在自我修复”的推送,以及一个越来越难解释的故障史。
五、边界
它不存历史指标,不做趋势分析,替代不了真正的时序数据库。但它能回答三个最要紧的问题:现在是什么状态、什么时候变的、这个状态持续了多久。对单机、单服务、个人项目来说,这三个问题占了告警价值的九成。
整套东西不到六十行,没有依赖,半年后的你自己还能读懂——这大概是它最大的优点。
- 点赞
- 收藏
- 关注作者
评论(0)