Back to blog
cron tutorial linux

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.

The Cronaut team

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.

Try Cronaut free

Uptime, cron and a self-updating status page in one tool.

Start free