Rotate Nginx log files

Nginx is a great web server, however a default install will not rotate log files for you. there’s no size limit, it will keep getting bigger until your disk is full.

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 to rotate ngnix log files automatically, my version is nginx/1.4.3. but any modern distribution should function in a similar way.

Manual rotating nginx log files via Cron

First we need to create the job bash script for cron that will do the log rotation.

sudo vi /usr/local/sbin/rotate_nginx_log.sh

Here are the contents of the script (this is based off the example from the Nginx wiki):

#!/bin/bash
# <https://gist.github.com/allex/10360845>

# Set variable
logs_path="/var/log/nginx/"
old_logs_path=${logs_path}/old
nginx_pid=`cat /var/run/nginx.pid`

time_stamp=`date -d "yesterday" +%Y-%m-%d`

mkdir -p ${old_logs_path}

# Main
for file in `ls $logs_path | grep log$ | grep -v '^20'`
do
    if [ ! -f ${old_logs_path}/${time_stamp}_$file ]
    then
        dst_file="${old_logs_path}/${time_stamp}_$file"
    else
        dst_file="${old_logs_path}/${time_stamp}_$file.$$"
    fi
    mv $logs_path/$file $dst_file
    gzip -f $dst_file  # do something with access.log.0
done

kill -USR1 $nginx_pid

Note:

First, we move the current log to a new file for archiving. A common scheme is to name the most recent log file with a suffix of current time stamp. e.g, $(date "+%Y-%m-%d").

The command that actually rotates the logs is kill -USR1 $(cat /var/run/nginx.pid). This does not kill the Nginx process, but instead sends it a SIGUSR1 signal causing it to re-open its logs.

THen execute sleep 1 to allow the process to complete the transfer. We can then zip the old files or do whatever post-rotation processes we would like.

Next please make sure that the script file is executable by running

chmod +x /usr/local/sbin/rotate_nginx_log.sh

In our final step we will create a crontab file to run the script we just created.

sudo crontab -e

In this file let’s create a cron job to run every day at 1am

Add the following lines to the file as follows:

00 01 * * * /usr/local/sbin/rotate_nginx_log.sh &> /dev/null

Also we can config suppressing cron jobs status email notifications. see Suppressing Cron Job Email Notifications


Log Rotation With Logrotate

The logrotate application is a simple program to rotate logs.

sudo vim /etc/logrotate.d/nginx

Put this content inside and modify the first line to match your Nginx log file

/var/log/nginx/*.log {
    daily
    missingok
    rotate 30
    dateformat .%Y-%m-%d
    compress
    delaycompress
    notifempty
    create 640 nginx adm
    sharedscripts
    postrotate
        [ -f /var/run/nginx.pid ] &amp;&amp; kill -USR1 `cat /var/run/nginx.pid`
    endscript
}

Wait 24 hours until cron daily runs and check out if you see any .gz file inside your logs directory, if you see some gzipped files, your Nginx rotation is working fine :D


Related References: