Rotating Log Files

If you’re not careful with how you handle log files on your server, you may be surprised one day if it crashes because the file grows to the file size limit on your operating system. To prevent that, you’ll want to implement some sort of log rotation system. On most linux distributions, this is most commonly handled by LogRotate which runs as a daily cronjob.

One minor drawback to logrotate is that you have to list explicitly which logs to rotate in its configuration files. This can be pretty tedious once Apache serving more than a handful of sites. One solution is to log all trafic to your virtual hosts to a single file, but I like each site to have its own logfiles. In the past, I had put together a quick little script that would rotate scripts for me at the begining of each month but this also requires adding a new host to the list of logs to rotate.. Since I didn’t want to have to remember another step when setting up sites on my server, I decided to look for other options for rotating the apache logs on a monthly basis. I found cronolog, which is a clever little program:

cronolog is a simple filter program that reads log file entries from standard input and writes each entry to the output file specified by a filename template and the current date and time. When the expanded filename changes, the current file is closed and a new one opened.

The program was easy to download and compile from source. Now, when setting up a virtual host, instead of using lines like the following:

CustomLog /www/hosts/oscarm.org/logs/access.log combined

I simply use the following to get automagically rotating logs with the year and month at the beggining of the filename (note the quotes and pipe at the beginning):

CustomLog "|/path/to/cronolog /www/hosts/oscarm.org/logs/%Y-%m.access.log" combined

On a related topic, if you are writing web applications and logging any errors or output yourself, you’d be wise to rotate logs as well and not expect your server admin to know to do it for you. In PHP, this is trivially easy using the date function when you specify what file to log to. Instead of doing:

$logfile = "/path/to/my_logfile.log"

You should do this:

$logfile = "/path/to/".date('Y-m').".my_logfile.log"