How to Monitor Your Cron Jobs and Scheduled Tasks with Vigilmon
Cron jobs are the unsung workhorses of every production system. They handle invoicing, backups, report generation, cache warming, data sync, and dozens of other critical tasks. And they fail silently.
Unlike web endpoints that return error codes visible in logs and dashboards, a cron job that stops running just... stops. No error. No alert. No indication until someone notices that the weekly invoices didn't go out or the database backup is three weeks old.
This guide shows you how to monitor cron jobs properly with Vigilmon's heartbeat monitoring.
The Problem with Cron Job Monitoring
Standard uptime monitoring (HTTP checks) doesn't work for cron jobs because:
- Cron jobs don't expose endpoints — they run as background processes
- Failures are silent — a failed cron job returns no response to check
- They stop running — the problem isn't a bad response, it's no response at all
- Timing matters — a daily job that ran 26 hours ago instead of 24 is a problem
The solution is heartbeat monitoring (also called dead man's switch monitoring): the job pings Vigilmon when it completes successfully. If Vigilmon doesn't receive a ping within the expected window, it alerts you.
Setting Up Heartbeat Monitoring
Step 1: Create a Heartbeat Monitor in Vigilmon
- Go to vigilmon.online and sign up (free)
- Add Monitor → Heartbeat Monitor
- Set the expected interval (e.g., 25h for a daily job)
- Copy the unique ping URL provided
Step 2: Add the Ping to Your Cron Jobs
Shell/Bash Scripts
#!/bin/bash
# daily-backup.sh
set -e # Exit on any error
echo "Starting backup at $(date)"
# Your backup logic
pg_dump $DATABASE_URL | gzip > /backups/db-$(date +%Y%m%d).sql.gz
aws s3 cp /backups/db-$(date +%Y%m%d).sql.gz s3://my-backups/
echo "Backup completed at $(date)"
# Ping Vigilmon on success
curl -s "https://hb.vigilmon.online/YOUR_MONITOR_SLUG" --data 'status=ok' || true
In your crontab:
0 2 * * * /usr/local/bin/daily-backup.sh >> /var/log/backup.log 2>&1
Node.js
// cron/daily-report.js
const cron = require('node-cron');
const https = require('https');
cron.schedule('0 9 * * 1-5', async () => { // 9 AM weekdays
try {
await generateDailyReport();
await sendReportEmails();
// Ping Vigilmon on success
https.get('https://hb.vigilmon.online/YOUR_MONITOR_SLUG').on('error', () => {
console.warn('Failed to ping Vigilmon heartbeat');
});
console.log('Daily report sent successfully');
} catch (err) {
console.error('Daily report failed:', err);
// Don't ping — Vigilmon will alert on missing heartbeat
}
});
Python
import requests
import schedule
import time
from datetime import datetime
def daily_sync_job():
try:
print(f"Starting sync at {datetime.now()}")
sync_data_to_warehouse()
update_analytics_cache()
# Ping Vigilmon heartbeat
requests.get(
'https://hb.vigilmon.online/YOUR_MONITOR_SLUG',
timeout=5
)
print("Sync completed successfully")
except Exception as e:
print(f"Sync failed: {e}")
# No ping = Vigilmon will alert
schedule.every().day.at("03:00").do(daily_sync_job)
while True:
schedule.run_pending()
time.sleep(60)
Ruby
# Using the Whenever gem
require 'net/http'
task :daily_invoice_run do
begin
InvoiceService.run_all_pending
# Ping Vigilmon
Net::HTTP.get(URI('https://hb.vigilmon.online/YOUR_MONITOR_SLUG'))
Rails.logger.info "Invoice run completed"
rescue => e
Rails.logger.error "Invoice run failed: #{e.message}"
# No ping = alert fires
end
end
Common Cron Job Patterns to Monitor
| Job Type | Interval | Grace Period | Priority |
|---|---|---|---|
| Database backup | Daily | 2 hours | Critical |
| Invoice generation | Weekly/Monthly | 30 min | Critical |
| Cache warming | Hourly | 15 min | High |
| Data sync | 15 min | 5 min | High |
| Report generation | Daily | 1 hour | Medium |
| Cleanup tasks | Weekly | 4 hours | Low |
Advanced: Monitor with Context
Send additional context with your heartbeat ping:
#!/bin/bash
# Send success with metadata
curl -s -X POST "https://hb.vigilmon.online/YOUR_MONITOR_SLUG" \n -H 'Content-Type: application/json' \n -d "{
\"status\": \"ok\",
\"message\": \"Processed $(wc -l < /tmp/records.txt) records\",
\"duration_ms\": $(($(date +%s%3N) - START_TIME))
}"
Monitoring Kubernetes CronJobs
For Kubernetes CronJobs, add a heartbeat to your job spec:
apiVersion: batch/v1
kind: CronJob
metadata:
name: nightly-cleanup
spec:
schedule: "0 3 * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: cleanup
image: myapp:latest
command:
- /bin/sh
- -c
- |
python cleanup.py && \n curl -s https://hb.vigilmon.online/YOUR_MONITOR_SLUG
restartPolicy: OnFailure
Summary
Cron job failures are silent disasters. Heartbeat monitoring with Vigilmon means:
- Every scheduled job is verified — not just "did it start" but "did it complete"
- Timing violations alert you — a daily job that ran 36h ago triggers an alert
- Zero false positives — alerts only fire if the job actually fails to complete
- Works for any language — bash, Node.js, Python, Ruby, Go, any HTTP client
Protect your scheduled tasks at vigilmon.online — free for up to 5 monitors.
Top comments (0)