What do you think? Discuss, post comments, or ask questions at the end of this article [More about me]

Skip to end of metadata
Go to start of metadata

Problem

Apache logs are rotated periodically using logrotate on Linux.  By default logrotate was set to rotate my apache logs weekly and this would often occur around ~0620hrs.  I would prefer to rotate every night precisely at midnight.  This way you separate apache logs by a by day.  Note, you may prefer weekly if you have less traffic and/or audit on a weekly basis.

Solution

Apache logs rotate via the logrotate utility.  Although the frequency and parameters of rotating logs with logrotate can be configured to your needs, I wanted to rotate logs precisely every night at midnight.  Furthermore, I only wanted this behaviour for my apache logs (and leave other logs being rotated by logrotate).  Below outlines changes to force apache log rotation every night at midnight.

We will take the following steps:

  1. move apache2 logrotation config from the normal logrotate daily cron scripts
  2. setup an weekly cron job to force execution of apache log rotation script every Sunday at midnight

Move apache2 logrotation config

Since we only want to force apache logs to be rotated every night at midnight, we need to move the apache2 logrotate config files to another folder so that the normal logrotate cron scripts still run as per usual (but not apache log rotations).

To do this we will create a new folder in /etc and move the apache logrotate conf file

sudo mkdir /etc/logrotate.apache
sudo mv /etc/logrotate.d/apache2 /etc/logrotate.apache/

Note that if you're using CentOS or Amazon linux the the file to move will be /etc/logrotate.d/httpd instead

Note that since we're moving our apache logrotation config (which we will run directly) it won't inherit the default options defined in /etc/logrotate.conf.  Hence we should make sure it contains all the logrotation options we would like.  Below is an example of my logrotate.apache file:

/var/log/apache2/*.log {
        missingok
        dateext
        rotate 14
        create 640 root adm
        sharedscripts
        postrotate
                if /etc/init.d/apache2 status > /dev/null ; then \
                    /etc/init.d/apache2 reload > /dev/null; \
                fi;
        endscript
        prerotate
                if [ -d /etc/logrotate.d/httpd-prerotate ]; then \
                        run-parts /etc/logrotate.d/httpd-prerotate; \
                fi; \
        endscript
}

Run man logrotate to see descriptions of these logrotate options.

Setup an "midnightly" cron job to execute Apache log rotation script

Now, let's create a cron job to execute the apache log rotation.  Simply run:

sudo crontab -e

This will open your crontab file in your system editor (probably vi or nano).  If you're using vi, please see here for how to use it.

Below is an example of sudo's crontab after adding a line to execute apache log rotation (see last line):

# Edit this file to introduce tasks to be run by cron.
#
# Each task to run has to be defined through a single line
# indicating with different fields when the task will be run
# and what command to run for the task
#
# To define the time you can provide concrete values for
# minute (m), hour (h), day of month (dom), month (mon),
# and day of week (dow) or use '*' in these fields (for 'any').#
# Notice that tasks will be started based on the cron's system
# daemon's notion of time and timezones.
#
# Output of the crontab jobs (including errors) is sent through
# email to the user the crontab file belongs to (unless redirected).
#
# For example, you can run a backup of all your user accounts
# at 5 a.m every week with:
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
#
# For more information see the manual pages of crontab(5) and cron(8)
#
# m h  dom mon dow   command

# Rotate logs at midnight on sunday
0 0 * * * /usr/sbin/logrotate -f /etc/logrotate.apache/apache2

The 0 0 * * * tells cron to execute it at midnight and the latter arguments tell logrotate to force rotate your apache logs.

Note that if you're using CentOS or Amazon linux you would use the following arguments instead: logrotate -f /etc/logrotate.apache/httpd

Testing logrotate scripts

You can test logrotate by running it with the debug flag to see what would happen (in debug mode logs will not actually be rotated):

sudo /usr/sbin/logrotate -df /etc/logrotate.apache/apache2

References

  1. https://support.rackspace.com/how-to/understanding-logrotate-utility/
  2. https://askubuntu.com/questions/24503/specify-the-time-of-daily-log-rotate
  3. https://www.tutorialspoint.com/unix/unix-vi-editor.htm