Proper way to rotate Nginx logs

While the world is divided on whether the humble named pipe is friend or foe, it is probably the simplest solution to your problem. It does have a few drawbacks (in that you need to create the pipes ahead of time), but it eliminates the need for a cron and allows you to used the logging pipe-filter of your choice.

Here’s an example using cronolog on access.log:

  1. Pick a path for our named pipe. I intend to keep my logs in /var/log/nginx, so I’ll put my pipes there as well. The name is up to you; I append .fifo, and it’s access.log, so mine will be at /var/log/nginx/access.log.fifo.
  2. Delete the file if it exists.
  3. Make a named pipe for the logfile:

    mkfifo /var/log/nginx/access.log.fifo
    
  4. Configure nginx.conf to point the log at the pipe you just made:

    access_log /var/log/nginx/access.log.fifo;
    
  5. Modify your init.d script to start the log rotator listening to the pipe before we start the server:

    LOGS="/var/log/nginx"
    pkill -f "/usr/sbin/cronolog --symlink $LOGS/access.log"
    ( cat $LOGS/access.log.fifo | /usr/sbin/cronolog --symlink $LOGS/access.log "$LOGS/%Y/%m/%d/access.log" ) &
    

    A similar commandline would be used for rotatelogs should you prefer it to cronolog — see their docs for the syntax.

    If your distrobution has a start-stop-daemon, you should be using that instead, as it theoretically has whatever special knoweldge about your platform there is, and taking care of pkill for you. Simply wrap the command in a script, and pass it as --exec to start-stop-daemon in your init.d/nginx.

Leave a Comment