Cron's default behavior of emailing job output often causes issues, especially when:
- Mail services are disabled on the server
- Administrators forget to properly redirect output
- Output disappears into /dev/null when mail isn't configured
Cron handles output in three ways:
- Explicit redirection (best practice):
0 * * * * /path/command >> /var/log/command.log 2>&1
- MAILTO environment variable configuration
- Default behavior (output to user's local mail)
For Ubuntu/Debian systems, edit /etc/default/cron
:
# Add or modify this line EXTRA_OPTS="-L /var/log/cron.log"
Then restart cron:
sudo service cron restart
Create a global wrapper in /usr/local/bin/log_wrapper
:
#!/bin/bash LOG_DIR="/var/log/cronjobs" mkdir -p "$LOG_DIR" LOG_FILE="$LOG_DIR/$(basename "$0").log" "$@" >> "$LOG_FILE" 2>&1
Make it executable:
sudo chmod +x /usr/local/bin/log_wrapper
Then modify crontab entries:
0 * * * * /usr/local/bin/log_wrapper /bin/date
Configure /etc/rsyslog.conf
:
# Add this line cron.* /var/log/cron_output.log
Then restart rsyslog:
sudo service rsyslog restart
- Log rotation: Ensure your solution includes proper log rotation
- Permissions: Cron jobs run as various users - ensure log files have proper permissions
- Disk space: Monitor log file growth for high-frequency jobs
The default behavior of cron is to email any output (both stdout and stderr) from jobs to the system administrator or the user who owns the cron job. This creates several practical issues:
- Mail service might be disabled on the server (common in minimal installations)
- Important output gets lost in mailboxes that aren't monitored
- No centralized logging of cron job execution
While Ubuntu's cron (Vixie cron) doesn't have a direct configuration option for default output logging, we can implement these workarounds:
# System-wide solution (affects all users)
1. Edit /etc/default/cron
2. Add or modify:
CRONOPTS='-L /var/log/cron.log'
3. Restart cron service:
sudo service cron restart
For Debian/Ubuntu systems, this creates a combined log file at /var/log/cron.log
containing output from all cron jobs that don't have explicit redirection.
For more control, create a wrapper script that handles logging automatically:
#!/bin/bash
# /usr/local/bin/cron-wrapper
LOG_DIR="/var/log/cron-jobs"
mkdir -p "$LOG_DIR"
exec >> "$LOG_DIR/$(basename "$0").log" 2>&1
exec "$@"
Then modify crontab entries to use the wrapper:
0 * * * * /usr/local/bin/cron-wrapper /bin/date
Don't forget to manage the growing log files:
# /etc/logrotate.d/cron-logs
/var/log/cron-jobs/*.log {
daily
missingok
rotate 7
compress
delaycompress
notifempty
}
For enterprise systems, consider routing cron output through syslog:
# /etc/rsyslog.d/30-cron.conf
cron.* /var/log/cron-syslog.log
This provides better integration with existing logging infrastructure and allows for remote logging.
When implementing these solutions:
- Ensure log directories have proper permissions (usually root:root with 755)
- Monitor log file growth to prevent disk space issues
- Consider SELinux/apparmor contexts if enabled
For Ubuntu 20.04+ and modern cron implementations, you may also find additional logging options in /etc/systemd/system/cron.service.d/
if using systemd.