When setting up cron jobs, many developers use the simple redirection syntax:
0 0 * * * /path/to/script.php > $HOME/cron.log 2>&1
This approach has a significant limitation - it overwrites the log file each time the job runs. For debugging and auditing purposes, we need to preserve historical execution logs.
The most effective method is to incorporate the execution timestamp directly into the filename. Here's how to implement it:
0 0 * * * /path/to/script.php > $HOME/cron-$(date +\%Y-\%m-\%d-\%H\%M\%S).log 2>&1
Let's examine the key components:
$(date +\%Y-\%m-\%d-\%H\%M\%S)
generates the timestamp- Note the escaped percent signs (
\%
) - crucial for cron - The format produces: YYYY-MM-DD-HHMMSS
You can customize the timestamp format to suit your needs:
# Short date format
0 0 * * * /path/to/script.php > $HOME/cron-$(date +\%F).log 2>&1
# Unix timestamp
0 0 * * * /path/to/script.php > $HOME/cron-$(date +\%s).log 2>&1
# Week-based format
0 0 * * * /path/to/script.php > $HOME/cron-$(date +\%Y-W\%U).log 2>&1
For production systems, consider adding log rotation:
0 0 * * * /path/to/script.php > $HOME/logs/cron-$(date +\%F).log 2>&1
0 0 1 * * /usr/sbin/logrotate /etc/logrotate.d/cronlogs
When managing several cron jobs, include the script name in the log:
0 0 * * * /path/to/script.php > $HOME/logs/script-$(date +\%F).log 2>&1
30 * * * * /path/to/cleanup.sh > $HOME/logs/cleanup-$(date +\%F-\%H\%M).log 2>&1
- Ensure the log directory exists and is writable
- Monitor disk space when storing many log files
- Consider implementing a cleanup mechanism for old logs
- For sensitive data, set appropriate file permissions
Here's a robust implementation for a production environment:
# Ensure log directory exists
mkdir -p $HOME/logs/cron
# Main job with full timestamp
0 0 * * * /path/to/script.php > $HOME/logs/cron/script-$(date +\%Y\%m\%d-\%H\%M\%S).log 2>&1
# Weekly log cleanup
0 0 * * 0 find $HOME/logs/cron -name "*.log" -mtime +30 -delete
When setting up cron jobs, many developers use simple output redirection like:
0 0 * * * /path/to/script.php > $HOME/cron.log 2>&1
This approach has a significant limitation - it overwrites the log file on each execution. For debugging and auditing purposes, we need to preserve historical output.
The key is to generate a unique filename for each execution. Here's how to implement timestamped logging:
0 0 * * * /path/to/script.php > $HOME/cron-$(date +\%Y-\%m-\%d-\%H\%M\%S).log 2>&1
The magic happens with $(date +\%Y-\%m-\%d-\%H\%M\%S)
:
\%Y
: 4-digit year\%m
: 2-digit month\%d
: 2-digit day\%H
: 2-digit hour (24-hour format)\%M
: 2-digit minute\%S
: 2-digit second
For different requirements, consider these variations:
# Date only format
0 0 * * * /path/to/script.php > $HOME/cron-$(date +\%F).log 2>&1
# Compact timestamp
0 0 * * * /path/to/script.php > $HOME/cron-$(date +\%Y\%m\%d\%H\%M).log 2>&1
# Including process ID
0 0 * * * /path/to/script.php > $HOME/cron-$(date +\%F)-$$.log 2>&1
For better organization, create a logs directory and modify the command:
0 0 * * * /path/to/script.php > $HOME/cron_logs/$(date +\%F)/script-$(date +\%H\%M\%S).log 2>&1
Remember to create the directory first:
mkdir -p $HOME/cron_logs
For production systems, combine with logrotate:
0 0 * * * /path/to/script.php > $HOME/cron_logs/script.log 2>&1 && \
mv $HOME/cron_logs/script.log $HOME/cron_logs/script-$(date +\%F-\%H\%M).log
In crontab, percent signs need escaping with backslashes. The command:
date +%Y-%m-%d
Becomes in crontab:
date +\%Y-\%m-\%d