How to monitor a cron job and get alerted when it stops running如何监控 cron 任务,并在它停跑时收到告警
Use a heartbeat monitor so a missed backup, report or sync raises an alert instead of going unnoticed: one curl at the end of the job, a grace period and a failure threshold.用心跳监控让漏跑的备份、报表或同步任务触发告警,而不是无人发觉:任务末尾一条 curl,加上宽限期和失败阈值。
The worst failures are the quiet ones. A website that goes down gets noticed within minutes. A nightly backup that stopped running three weeks ago does not, until the day you need the backup. An uptime check cannot see it, because there is nothing to request: the job runs on a server, talks to nobody and has no URL.最糟的故障往往是悄无声息的那种。网站挂了,几分钟内就有人发现;而三周前就已经停跑的夜间备份,要等到你真正需要备份的那天才会被发现。普通的可用性检测发现不了它,因为没有东西可以请求:任务跑在服务器上,不和任何人对话,也没有 URL。
A heartbeat monitor turns the question around. Instead of OpenUptime asking your job whether it is alive, the job tells OpenUptime every time it finishes. If the message does not arrive on schedule, that is the alert.心跳监控把问题倒了过来:不是 OpenUptime 去问任务"你还活着吗",而是任务每次跑完都主动告诉 OpenUptime。如果这条消息没有按时到达,那就是告警。
Step 1: create the heartbeat monitor第一步:创建心跳监控
In the app, add a monitor and choose the Heartbeat type, or create it through the API. Set the interval to how often the job should run, and the grace period to how late it may be before that counts as a miss.在应用里添加监控并选择心跳类型,或者通过 API 创建。把间隔设成任务应该运行的频率,把宽限期设成允许它迟到多久才算漏跑。
curl -X POST https://openuptime.app/api/monitors \
-H "x-api-key: ou_..." \
-H "content-type: application/json" \
-d '{"name":"Nightly backup","type":"heartbeat","intervalSec":86400,"graceSec":3600,"failureThreshold":1}'Here the backup is expected once a day (86,400 seconds) and gets an hour of grace. The response includes a heartbeatToken. The interval can be anything from 30 seconds to a day, and the grace period from 0 seconds to a day.这里的备份预期每天一次(86400 秒),并给了一小时的宽限。返回结果里带有 heartbeatToken。间隔可以是 30 秒到一天,宽限期可以是 0 秒到一天。
Step 2: ping it when the job succeeds第二步:任务成功后发送心跳
Add one line at the very end of the job, so that it only runs when everything before it worked. No API key is needed; the token in the URL is the secret, and both GET and POST are accepted.在任务的最末尾加一行,让它只在前面的步骤都成功时才会执行。不需要 API 密钥,URL 里的令牌就是凭证,GET 和 POST 都可以。
0 3 * * * /usr/local/bin/backup.sh && curl -fsS --retry 3 https://openuptime.app/api/heartbeat/<heartbeatToken>The && matters: curl runs only if backup.sh exits with status 0. A script that crashes midway never pings, and that silence is exactly what the monitor is waiting to notice. The same pattern works at the end of a CI job, a Kubernetes CronJob, a systemd timer or a scheduled cloud function.这个 && 很关键:只有 backup.sh 以状态码 0 退出,curl 才会执行。脚本中途崩溃就不会发送心跳,而这份沉默正是监控在等待发现的信号。同样的写法也适用于 CI 任务末尾、Kubernetes CronJob、systemd 定时器和云函数定时任务。
How a missed ping becomes an alert漏掉心跳是怎么变成告警的
Each ping tells OpenUptime that the next one is due one interval plus the grace period from now. If that moment passes with no ping, the monitor records a failed check with the message "Heartbeat missed". An incident opens once the number of consecutive misses reaches the monitor's failure threshold, and your alert channels are notified.每次心跳都会告诉 OpenUptime:下一次心跳应在"一个间隔加宽限期"之后到达。如果这个时刻过了还没有心跳,监控就会记录一次失败的检测,信息为"Heartbeat missed"。连续漏掉的次数达到该监控项的失败阈值后,会开启事件,并通知你的告警渠道。
That threshold defaults to 3, which suits a job that runs every minute and is wrong for a job that runs daily: you would find out three days late. For slow schedules set failureThreshold to 1, as in the example above.这个阈值默认是 3:对每分钟一次的任务合适,对每天一次的任务就不合适,你会晚三天才知道。慢节奏的任务请像上面的例子那样把 failureThreshold 设为 1。
Recovery needs no extra work. The next successful ping resolves the open incident and the monitor returns to up. A ping to a paused monitor is acknowledged and changes nothing, so you can pause a job for maintenance without noise.恢复也不需要额外操作:下一次成功的心跳会关闭未结束的事件,监控回到正常状态。向已暂停的监控发送心跳会被接收但不产生任何变化,因此你可以放心暂停任务做维护。
Choosing the interval and grace period怎么选间隔和宽限期
- Interval: how often the job should run. Match the schedule, not how quickly you want to hear about problems.间隔:任务应该多久运行一次。以任务的调度周期为准,而不是你希望多快得知问题。
- Grace period: how long a normal run may overrun or start late. Use the longest normal duration of the job, plus a margin. A job that takes ten minutes needs more than ten minutes of grace.宽限期:一次正常运行允许晚多久。取任务正常运行的最长耗时再加一点余量。一个跑十分钟的任务,宽限期就要超过十分钟。
- Failure threshold: how many consecutive misses open an incident. One for daily and weekly jobs, more for frequent ones where a single late run is not worth a page.失败阈值:连续漏掉几次才开启事件。每日、每周任务设为 1;高频任务可以更大,避免偶尔一次迟到就打扰你。
The full request and response shapes are in the API reference. For websites and APIs that have a URL to request, see how OpenUptime checks them; to be told before a certificate lapses, read how to monitor SSL certificate expiry.完整的请求与响应格式见 API 参考。对于有 URL 可请求的网站和 API,可以看看 OpenUptime 如何检测它们;想在证书过期前收到提醒,请读如何监控 SSL 证书到期。
Common questions常见问题
- What happens if my job runs but fails?任务运行了但执行失败,会怎样?
- A heartbeat monitor only knows whether the ping arrived. Send the ping as the last step, after the work succeeded, and a failed run simply never pings.心跳监控只知道心跳有没有到达。把心跳放在最后一步、工作成功之后,失败的那次运行就不会发送心跳。
- Do I need an API key to send the ping?发送心跳需要 API 密钥吗?
- No. The ping URL contains a secret token and accepts GET or POST without any key, so it works from any shell script, scheduler or CI job.不需要。心跳地址里带有一个私密令牌,GET 或 POST 都不需要密钥,所以任何 shell 脚本、调度器或 CI 任务都能直接调用。
- Why did a missed run not alert me straight away?漏跑一次为什么没有立刻告警?
- A missed ping counts as one failed check, and an incident opens after the monitor's failure threshold of consecutive failures. The default is 3; set it to 1 for a job that runs once a day.漏掉一次心跳算作一次失败的检测,连续失败达到监控项的失败阈值后才会开启事件。默认值是 3,每天只跑一次的任务建议设为 1。