Cron jobs fail silently. That's their biggest flaw. A job can stop running — bad path, disk full, permission error, server reboot — and you won't know until something downstream breaks.
This guide covers three approaches to monitoring cron jobs, from basic to bulletproof.
The simplest method is redirecting output to a log file and checking it:
0 2 * * * /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1
Problems: you have to remember to check. Nobody does. You'll find out about failures when it's too late.
Cron can email you when a job produces output:
[email protected]
0 2 * * * /usr/local/bin/backup.sh
Better, but only triggers on output — not on absence. If the job doesn't run at all (server was down, cron daemon crashed), you get nothing.
This is the reliable method. Instead of watching for failures, you watch for expected successes. Your job pings a monitoring service after completing successfully. If the ping stops arriving, you get alerted.
0 2 * * * /usr/local/bin/backup.sh && curl -fsS https://ping.trebben.dk/YOUR_SLUG
This catches every failure mode:
&&# Ping only on success (exit code 0)
0 2 * * * /path/to/job.sh && curl -fsS https://ping.trebben.dk/YOUR_SLUG
import urllib.request
def main():
# Your job logic here
pass
if __name__ == "__main__":
main()
urllib.request.urlopen("https://ping.trebben.dk/YOUR_SLUG")
// At the end of your scheduled task
async function run() {
// Your job logic here
await fetch("https://ping.trebben.dk/YOUR_SLUG");
}
run();
apiVersion: batch/v1
kind: CronJob
spec:
schedule: "0 2 * * *"
jobTemplate:
spec:
containers:
- name: backup
command: ["/bin/sh", "-c", "/backup.sh && curl -fsS https://ping.trebben.dk/YOUR_SLUG"]
CronPulse gives you 20 monitors for free — no credit card, no trial expiration. That's enough for most setups. Email, Slack, webhook, and Telegram alerts are all included.
Start monitoring your cron jobs — freeBuilt by Jeff in Denmark. See also: free developer tools.