Skip to content

Cron — alert when a scheduled job did not run

cron is alive, but the job (timer disabled, MAILTO=root spam, sh-syntax-error in crontab) did not run last night. The classic "we forgot last night gave empty reports".

Recipe

bash
#!/usr/bin/env bash
# /etc/cron.d/cron-skipped
# Run this at the END of the cron job you want to monitor:
#   30 3 * * * root /opt/some-job.sh && /opt/cron-ping.sh some-job
# /opt/cron-ping.sh — sends success ping with name

NAME=${1:?usage: cron-ping.sh <job-name>}
curl -fsS "$HEARTBEAT_URL/cron/$NAME" --data "ts=$(date +%s)"

# A separate guard runs at 03:45 (15 min AFTER the expected window)
# and complains if no ping arrived. That's a "dead-man's switch" —
# if the monitor itself has retention you need NOTHING ELSE on the box:
#   45 3 * * * root /opt/cron-watchdog.sh some-job

Same thing in Enterno.io

Use Enterno heartbeat in expected-schedule mode — it understands "should have arrived by 03:30" and alerts if the ping is late beyond the grace period. No second watchdog cron needed on the box.

Set up Heartbeat monitor → ← All recipes

Related recipes

Logs or backup files eat /var; in 24 hours the server falls over. A basic df check every 10 minutes saves a 2 AM incident.