How to know if a cron job actually ran
Your cron job is configured, but did it run? Here is how to check cron logs on Linux, why logs are not enough, and how to get a real answer every time.
You added a line to your crontab, waited for the scheduled time, and now you are not sure anything happened. The output is gone, there is no obvious error, and the only way to tell is to go digging. This post walks through how to check whether a cron job ran on Linux, and why the logs alone will not give you a reliable answer over time.
Check the system log
On most Linux systems cron writes a line to the system log every time it runs a job. Where it lands depends on the distribution.
On systems with journald:
journalctl -u cron --since "today"
# or, depending on the unit name
journalctl -u crond --since "today"
On Debian and Ubuntu with rsyslog:
grep CRON /var/log/syslog
On RHEL, CentOS and Fedora:
grep CRON /var/log/cron
You are looking for a line showing your command was started, for example
CRON[12345]: (you) CMD (/usr/local/bin/backup.sh). If the line is there, cron started the
job. If it is missing, the job never fired, which usually means a bad schedule, a disabled
crontab, or the machine being off at that time.
The log only proves it started
Here is the catch. That log line means cron launched the command. It says nothing about whether the command succeeded, how long it took, or whether it did anything useful. A job can log a clean start and still fail halfway through, exit non-zero, or silently produce nothing.
To capture the actual result you have to do it yourself, by redirecting output and recording the exit code:
0 2 * * * /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1; echo "exit $?" >> /var/log/backup.log
Now the log has the output and the exit status. This is better, but it is still a pull model. You only learn the job failed if you remember to go and read the file, which is exactly the thing you forget to do until something is already broken.
Get a push instead of a pull
The reliable answer is to have the job tell you when it ran, and have something alert you when that signal does not arrive. Add a ping that only fires on success:
0 2 * * * /usr/local/bin/backup.sh && curl -fsS https://ping.cronaut.dev/your-check-id
If the job runs and succeeds, the ping arrives. If it errors, the && short-circuits and no
ping is sent. If the crontab line was dropped or the server was down, no ping is sent either.
A monitor that knows your schedule notices the missing ping and alerts you, so you find out the
job did not run without ever opening a log file.
Why this beats grepping logs
Checking logs answers the question once, for one job, after you already suspect something is wrong. A heartbeat answers it continuously, for every job, and tells you before you would have thought to look. With Cronaut the cron check also shares a dashboard and status page with your uptime checks, so “did my job run” and “is my site up” are answered in the same place.
Read more about cron job monitoring and how it works.