How to Append Timestamp to Cron Job Output Filename to Prevent Overwriting


2 views

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