Apache logrotate with different names for current and archives

apache-2.2logrotate

I'm running Apache 2.2 on CentOS 6.5 and what I'd like to do is have Apache's current access log file be:

/var/log/httpd/access_log

And each day at midnight, that file is renamed like so (assume 2014-09-22 is the date that just passed):

/var/log/httpd/access_log.2014-09-22

…and a new log file (access_log) is created at that instant, and Apache continues logging to it. How can I do this? I've got this CustomLog directive set up already:

CustomLog "|/usr/sbin/rotatelogs /var/log/httpd/access_log.%Y-%m-%d 86400" combined

But this causes the current (active) logfile to be named access_log.2014-09-22 if today is 2014-09-22.

I can think of a hacky solution, where I have a script that runs just after midnight and sets /var/log/httpd/access_log to be a symlink to whatever the current day's logfile is. (It would be based on date, so even if it's a low-traffic server and the new logfile didn't exist yet, the symlink would be correct and would function as soon as any requests hit the server). But it seems like there must be a more elegant way to do this. Is there some way to tell rotate logs to use one filename for the current log, and a different filename for the rotated logs? Failing that, is there some other clean way to do what I want?

EDIT: Restarting Apache each day is not an option.

Best Answer

Looking at the man page for log rotate shows that dateext as well as dateformat can be used to achieve this goal.

  • dateext: Archive old versions of log files adding a daily extension like YYYYMMDD instead of simply adding a number. The extension may be configured using the dateformat option.

  • dateformat (format_string): Specify the extension for date ext using the notation similar to strftime(3) function. Only %Y %m %d and %s specifiers are allowed. The default value is -%Y%m%d. Note that also the character separating log name from the extension is part of the dateformat string. The system clock must be set past Sep 9th 2001 for %s to work correctly. Note that the datestamps generated by this format must be lexically sortable (i.e., first the year, then the month then the day. e.g., 2001/12/01 is ok, but 01/12/2001 is not, since 01/11/2002 would sort lower while it is later). This is because when using the rotate option, log rotate sorts all rotated filenames to find out which logfiles are older and should be removed.

So using a fairly simply logrotate script I use for Apache setups on Ubuntu, you could do this:

/var/log/apache2/*.log {
    weekly
    missingok
    rotate 26
    compress
    dateext
    dateformat %Y-%m-%d
    delaycompress
    notifempty
    create 640 root www-data
    sharedscripts
    postrotate
            /etc/init.d/apache2 reload > /dev/null
    endscript
    prerotate
            if [ -d /etc/logrotate.d/httpd-prerotate ]; then \
                    run-parts /etc/logrotate.d/httpd-prerotate; \
            fi; \
    endscript
}