Rotating Nginx log files via Cron

 
Published on 2013-02-15 by John Collins. Socials: YouTube - X - Spotify - Amazon Music - Apple Podcast

Nginx is a great web server, however a default install will not rotate log files for you. This is a problem especially on busy sites, as the access log can eat up disc space quite quickly.

In this tutorial, I will show you how you can set up a simple Cron job to run a bash script that will rotate and compress these log files for you automatically each day.

The bash script

First we need to create the new bash script that will do the log rotation (this is based off the example from the Nginx wiki):

nano /usr/local/sbin/rotatenginxlogs.sh
chmod 770 /usr/local/sbin/rotatenginxlogs.sh

The second command will make it executable. You can place this script anywhere you want, but I like to use /usr/local/sbin/ as it is on the path for most users.

Here are the contents of the script:

#!/bin/bash
DATE=$(date +%Y-%m-%d-%H%M)
mv /var/log/nginx/access.log /var/log/nginx/nginx.access.log.$DATE
mv /var/log/nginx/error.log /var/log/nginx/nginx_error.log.$DATE
kill -USR1 `cat /var/run/nginx.pid`
sleep 1
gzip /var/log/nginx/access.log.$DATE
gzip /var/log/nginx/error.log.$DATE

The script makes copies of the access and error logs to new files appended with the current date and time. These new files are then compressed to save disc space. For example access.log becomes access.log.2013-02-15-0100.gz when this script is ran at 1:00 on 2013-02-15.

The "kill -USR1..." command requires a little explanation. It does not actually kill the Nginx process (which has it's process ID or "PID" stored in /var/run/nginx.pid on my machine, hence the cat), but instead it takes an action defined by that particular application when this SIGUSR1 signal is received. In the case of Nginx, it will re-open its logs. The "sleep 1" adds some delay afterwards before we attempt to compress the rotated logs.

Running the script via Cron

As root (or other user with appropriate permissions):

crontab -e

Now add:

00 01 * * * /usr/local/sbin/rotatenginxlogs.sh > dev/null 2>&1

The new script will now run at 1:00AM each day, adjust as required. For an explanation of what the > dev/null 2>&1 commands do, please see Suppressing Cron Job Email Notifications.


Updated 2023 : note that the above post was originally published in 2013, but is left here for archival purposes. I have fixed a few broken links.