← 全部文章Terminal window
Terminal window
定时任务失败时收到提醒
给任意定时命令包一层,失败时把退出码和最后几行输出发到你的收件箱。
定时任务出错时往往悄无声息:三周前就停掉的备份、没人注意到的证书续期失败。几行 shell 就能让每次失败都变成一条提醒。
1. 创建发送链接
为服务器创建一个频道(或直接使用设备自带的频道),再为它创建一个以机器命名的发送链接,例如 nas cron。把链接保存到只有 root 可读的文件中:
sudo install -m 600 /dev/null /etc/gregor-send-urlecho 'https://<你的服务器>/v1/send/<token>' | sudo tee /etc/gregor-send-url >/dev/null2. 添加包装脚本
把下面的内容保存为 /usr/local/bin/alert-on-failure,并用 chmod +x 设为可执行:
#!/bin/sh# 用法:alert-on-failure <任务名称> <命令> [参数...]name="$1"; shiftoutput=$("$@" 2>&1)status=$?[ "$status" -eq 0 ] && exit 0
tail=$(printf '%s' "$output" | tail -n 5)body=$(printf '%s 上的退出码 %s\n%s' "$(hostname)" "$status" "$tail")
jq -n --arg title "$name 失败" --arg body "$body" --arg subject "cron:$(hostname):$name" \ '{alert: {title: $title, body: $body}, level: "high", event: {type: "cron.failed", subject: $subject}}' | curl -fsS -X POST "$(cat /etc/gregor-send-url)" \ -H 'Content-Type: application/json' --data-binary @- >/dev/nullexit "$status"脚本会执行任务;成功时什么都不做,失败时发送一条 high 级别的提醒,带上退出码和最后五行输出。JSON 由 jq 生成,输出中的引号和换行不会破坏请求。
3. 包装你的任务
在每条 crontab 记录前加上包装脚本和一个简短的名称:
30 2 * * * /usr/local/bin/alert-on-failure "夜间备份" /usr/local/bin/backup.sh0 4 * * 1 /usr/local/bin/alert-on-failure "续期证书" certbot renew --quiet用一个必定失败的命令测试一次:
/usr/local/bin/alert-on-failure "测试任务" false变化用法
- 设为紧急。 对失败后需要立即有人处理的任务,把
level改为"urgent"。Gregor 会每分钟提醒一次,直到有人确认。 - 识别重复失败。 同一个任务每次失败时
event.subject都相同,因此会被识别为同一事件的重复。 - 不要把密钥发出去。 最后几行输出会放进提醒正文。如果任务会打印 token 或密码,请减少
tail -n 5的行数,或只发送退出码。