How to Monitor Cron Jobs in Bash with Cronaman
The silent failure problem
Shell scripts are the workhorses of most Linux servers. Backups, log rotations, database dumps, cleanup tasks — they all end up as Bash scripts in a crontab. And they all share the same blind spot: cron doesn't tell you when something goes wrong.
Unless you're actively reading /var/log/syslog or have set up mail delivery (which almost nobody does anymore), a failed cron job will disappear silently into the night. Your backup stops running. You find out three weeks later when you actually need the backup.
What is heartbeat monitoring?
Heartbeat monitoring works like a dead man's switch. You tell Cronaman how often your job should run, and your script sends a simple HTTP ping after each successful execution. If that ping doesn't arrive within the window, Cronaman transitions the monitor to "late" and then "down" — and fires an alert to your email or Slack.
There's nothing to install on your server. No agents, no daemons. A single curl call at the end of your script is the entire integration — and curl is already installed on virtually every Linux server.
Create a Cronaman monitor
Before touching any script, create a monitor in Cronaman:
- Sign up at cronaman.dev — free plan, no credit card required
- Click New Monitor
- Name it (e.g., "Nightly backup") and set the interval to match your cron schedule
- Copy your unique ping URL:
https://cronaman.dev/ping/nightly-backup
That URL is all you need. Every successful script run calls it; every missed call triggers an alert.
The simplest approach: inline curl
For a script that already exits with a non-zero code on failure, you can add monitoring directly in crontab without touching the script at all:
# Run daily at 2:00 AM — ping Cronaman only if the script exits 0
0 2 * * * /home/user/backup.sh && curl -fsS --retry 3 --max-time 10 \
https://cronaman.dev/ping/nightly-backup > /dev/null 2>&1The && means curl only runs if backup.sh exits with code 0. A non-zero exit skips the ping, and Cronaman will alert when the deadline passes. The -fsS flags silence curl's progress output while still surfacing actual errors to syslog.
Wrapper script pattern
For more control — logging, explicit failure signals, retry logic — wrap your job in a shell script:
#!/usr/bin/env bash
set -euo pipefail
PING_URL="https://cronaman.dev/ping/nightly-backup"
FAIL_URL="https://cronaman.dev/ping/nightly-backup/fail"
LOG_FILE="/var/log/backup.log"
ping_cronaman() {
curl -fsS --retry 3 --max-time 10 "$1" > /dev/null 2>&1 || true
}
echo "[$(date -Iseconds)] Starting backup" >> "$LOG_FILE"
if /home/user/backup.sh >> "$LOG_FILE" 2>&1; then
echo "[$(date -Iseconds)] Backup succeeded" >> "$LOG_FILE"
ping_cronaman "$PING_URL"
else
echo "[$(date -Iseconds)] Backup FAILED (exit $?)" >> "$LOG_FILE"
ping_cronaman "$FAIL_URL"
exit 1
fiA few things worth noting:
set -euo pipefailmakes the script exit immediately on any error, unset variable, or failed pipe- The
|| trueon the ping call prevents a transient network error from masking the original job result - The
/failsuffix signals an immediate failure — no waiting for the deadline — so you're alerted right away --retry 3retries the ping up to 3 times on transient network errors
Add the wrapper to crontab
# Run daily at 2:00 AM via the wrapper
0 2 * * * /home/user/run-backup.shIn Cronaman, set the interval to 24 hours and add a grace period of 10–15 minutes. The grace period lets Cronaman absorb minor timing drift — load spikes, slow startup — before alerting.
Verify your setup
Run the wrapper manually to confirm the ping fires:
bash /home/user/run-backup.shOpen your Cronaman dashboard. Within a few seconds the monitor should show "healthy" with a "Last ping" timestamp. If it stays grey, confirm that your server can reach cronaman.dev on port 443:
curl -v https://cronaman.dev/ping/nightly-backupFrom here, Cronaman watches the clock so you don't have to. Miss a scheduled run, and you'll know within minutes — before anything downstream breaks.
More cron monitoring guides
Using a different stack? The same heartbeat pattern works everywhere:
- How to Monitor Cron Jobs in Python — covers urllib and the requests library
- How to Monitor Cron Jobs in Node.js — covers native fetch, Axios, and node-cron
- How to Monitor Cron Jobs in PHP — covers file_get_contents, cURL, and Laravel schedulers
More guides
What Is Cron Job Monitoring? (And Why You Need It)
5 min readProBeyond Timing: Catch Silent Successes with Semantic Ping Payloads
5 min readPythonHow to Monitor Cron Jobs in Python with Cronaman
6 min readNode.jsHow to Monitor Cron Jobs in Node.js with Cronaman
7 min readPHPHow to Monitor Cron Jobs in PHP with Cronaman
6 min readRubyHow to Monitor Cron Jobs in Ruby with Cronaman
6 min readGoHow to Monitor Cron Jobs in Go with Cronaman
6 min readLaravelHow to Monitor Laravel Cron Jobs with Cronaman
6 min readStart monitoring your Bash cron jobs
Free forever for up to 3 monitors. No credit card required. Set up in under 2 minutes.
Start monitoring free