All posts

Cron Log Explained: Location, Format, and Limits

August 11, 2026

What a Cron Log Actually Records

A cron log is a record kept by your system's logging daemon confirming that the cron scheduler triggered a job at a given time. It is not a record of what that job did. Crontab logs — whether written to syslog or captured by journald — answer one narrow question: did cron fire this command on schedule? They don't capture what the command printed, whether it succeeded, or what it changed.

Most developers go looking for a cron log because a scheduled task seems to have failed, expecting the log to explain why. It won't — it only confirms whether cron attempted the job. Keep that boundary in mind, because it's the reason file-based logging eventually stops being enough for teams running more than a handful of scheduled jobs.

Where Cron Logs Live, by System

The cron log file location varies by distribution and init system, and guessing wrong wastes time.

Ubuntu and Debian: cron activity goes to /var/log/syslog by default. Isolate it with:

grep CRON /var/log/syslog

RHEL, CentOS, and Rocky Linux: these ship a dedicated /var/log/cron file, so you don't need to filter a general syslog:

tail -f /var/log/cron

Systemd-based systems: if your distro runs cron under systemd (common on newer Ubuntu, Debian, and RHEL releases), journald may hold the logs instead of — or alongside — a flat file:

journalctl -u cron
journalctl -u crond

Try both unit names; the service is called cron on Debian-family systems and crond on RHEL-family systems.

macOS: modern macOS uses launchd instead of cron for most scheduled tasks, but if you're still using crontab, check /var/log/system.log or use the Console app to filter for cron-related entries.

Alpine Linux: Alpine's busybox crond typically logs to /var/log/cron.log if logging is enabled, though minimal Alpine installs often ship without any cron logging configured at all.

If none of these commands return anything, don't assume cron is silently broken — assume logging isn't configured yet. That's covered below.

Reading a Cron Log Entry

Once you've found the right file, a typical CRON log format entry looks something like this:

Mar 10 03:00:01 web01 CRON[14832]: (deploy) CMD (/usr/local/bin/sync-inventory.sh)

Breaking that down: the timestamp (Mar 10 03:00:01) is when cron triggered the job, not when it finished. The hostname (web01) matters once you're aggregating logs from more than one server. CRON[14832] identifies the process and its PID — useful for cross-referencing with other system logs at the same timestamp. (deploy) is the user whose crontab fired the job. CMD (...) shows the exact command cron executed.

That's the entire entry. There's no field for output, success or failure, or how long the job ran. The CRON CMD line is a receipt, not a report.

If the Log Is Empty: Enabling Cron Logging

A cron log empty of entries — or missing outright — almost always comes down to one thing: rsyslog isn't configured to capture cron facility messages. On Debian and Ubuntu systems, open /etc/rsyslog.d/50-default.conf and look for a line like:

#cron.*    /var/log/cron.log

If it's commented out with a #, that's your answer. Uncomment it, then restart rsyslog:

sudo systemctl restart rsyslog

New cron activity should start appearing within a minute of the next scheduled run. On RHEL-family systems, /var/log/cron is usually populated out of the box, so an empty file there more often points to cron itself not running, or the crontab entry not being installed correctly — worth checking with crontab -l under the right user. If you're running cron jobs on RHEL/CentOS with a systemd unit, confirm the service is active with systemctl status crond before assuming the logging config is the problem.

What Cron Logs Never Show You

Even with logging enabled and entries flowing in, cron logs have hard limitations that no configuration change fixes. They don't capture stdout or stderr — if your script prints an error or a stack trace, it disappears unless you've explicitly redirected it. They don't record exit codes, so a failed job and a successful one produce visually identical log lines. If your scheduled task makes an HTTP call, the log has no idea what response came back, what status code it received, or what body was returned.

There's also MAILTO, crontab's built-in mechanism for emailing a job's output to a specified address. It helps in isolation, but it wasn't built for teams — flooding an inbox with cron output doesn't give you searchable history, doesn't aggregate across servers, and breaks down entirely once you're running dozens of jobs. Add logrotate cycling out your syslog every few days, and last week's failure evidence may simply be gone.

None of this is a bug in cron; it's a design boundary. But it's exactly why grep-based debugging stops scaling once you have more than one server or more than a few scheduled HTTP jobs: rotated logs erase history, there's no cross-server view, nothing alerts you when something breaks, and you never see the response body that would explain a wrong result. If your job is failing due to environment or path issues rather than logging gaps, our PHP crontab setup guide covers the most common causes.

When grep Isn't Enough: Centralized Job Logging

Once you're maintaining scheduled HTTP jobs across multiple servers, the SSH-and-grep routine becomes the actual bottleneck, not the jobs themselves. Cron job monitoring built for this problem captures full cron execution history in one place: the request that was sent, the response received, timing data, and a clear pass/fail status — no server login required.

Cronevra sits between your scheduler and your HTTP endpoints, recording every execution and firing an alert the moment a job fails or returns an unexpected response, instead of waiting for someone to notice during a manual log check. For teams weighing this against building it themselves, our piece on keeping cron jobs reliable in production lays out the broader reliability picture, and our HTTP request scheduler guide is worth a look if scheduled HTTP calls are your primary use case.

If file-based logs have taken you as far as they can, see Cronevra's pricing and get execution-level visibility running in minutes.

Frequently Asked Questions

Where is the cron log file on Ubuntu?

Cron activity on Ubuntu is written to /var/log/syslog alongside other system messages. Filter it with grep CRON /var/log/syslog to see only cron-related entries. On systems where cron runs under systemd, journalctl -u cron may also show activity.

Why don't I have a /var/log/cron file?

That path is used by RHEL, CentOS, and Rocky Linux by default — Ubuntu and Debian route cron logs into /var/log/syslog instead. If you're on a Debian-family system expecting a dedicated /var/log/cron file, it simply doesn't exist there; check syslog or journalctl instead.

Does the cron log show me the error message from my script?

No. A cron log only confirms that cron triggered your command; it doesn't capture stdout, stderr, or exit codes. To see your script's actual error output, redirect it explicitly in the crontab entry or use a monitoring tool that captures execution output directly.

How do I view cron logs in real time?

Use tail -f /var/log/syslog (Ubuntu/Debian) or tail -f /var/log/cron (RHEL/CentOS) to watch entries as they're written. On systemd systems, journalctl -u cron -f or journalctl -u crond -f gives the same live view.

Can I get cron logs for jobs running on multiple servers in one place?

Not with native cron logging — each server keeps its own local log file with no built-in aggregation. Centralized job monitoring tools like Cronevra solve this by capturing execution history from all your scheduled HTTP jobs in a single dashboard, regardless of which server ran them.

Why is grep CRON /var/log/syslog showing nothing?

This usually means rsyslog isn't configured to capture the cron facility, or cron itself isn't running the job. Check /etc/rsyslog.d/50-default.conf for a commented-out cron.* line, uncomment it, and restart rsyslog with sudo systemctl restart rsyslog.