Nginx logrotate logs

Solution 1:

You are running Ubuntu version 15.

Yes, you could muck around with logrotate and with script snippets as in the other answers. But you are running Ubuntu version 15. On your operating system services are run under systemd, which by default captures their standard error and syslog outputs and handles the logging. There's no need for nginx to be writing to that error.log file in the first place. There's no need for logrotate at all.

Other answers and the comments beneath them may cause you to look at /etc/init.d/nginx perhaps. Don't. That file is irrelevant. You are running Ubuntu version 15. The relevant file, as provided right out of the box in the Ubuntu nginx-common package, is /lib/systemd/system/nginx.service which is what systemd will be using, completely ignoring the old /etc/init.d/nginx file which is entirely overridden by a proper systemd service unit file.

Other answers might lead you to look at /etc/logrotate.d/nginx as well. You might be mystified by the contradiction between what you can clearly see there, trying to run the old System 5 rc script with a non-standard invoke-rc.d subcommand, and the claim that there's no postrotate stanza. But again, simply don't. Don't focus on these logrotate control stanzas in the first place. You are running Ubuntu version 15 with a package that has a system unit already and isn't using System 5 rc scripts on your operating system, and a service manager that logs service output.

Two steps to doing things the systemd way:

Configure nginx more appropriately.

Your nginx service needs to be told to simply write its log to its standard error. As a bonus, you can send your access log to the journal via syslog, which systemd also intercepts.

This is done with nginx global configuration directives and http module directives. Specifically:

  • error_log stderr ;
  • access_log syslog:server=unix:/dev/log ;

You either change your nginx.conf file to say these as this person did, or do what Alexander Kuznecov did here and change your nginx.service unit file to pass (global) directives on the nginx command line:

Type=forking
PIDFile=/run/nginx.pid
ExecStart=/usr/bin/nginx -g 'daemon on; error_log stderr; master_process on;'

Forget about logrotate entirely.

systemd puts the standard output and standard error of all services into its journal. It handles the rotation of the journal files itself. There are no signals and no nginx service reloading involved at all. You can read the last few entries in the journal that are related to the service with (run as the superuser or as an adm user)

systemctl status nginx.service
You can read everything in the log from that service since the last boot with
journalctl -u nginx.service -b

Solution 2:

The reason nginx is writing to the rotated file is a missing postrotate section in the logrotate file for nginx to reload the configuration of nginx.

logrotate has renamed the file all right but renaming does not closes or changes the file descriptor (kernel internally maintains a descriptor table that demonstrates all open files by file handles or descriptors), the file handle remains the same as it was previously. So the nginx process will keep on dumping to the same file handle (the rotated one) rather than the newly created file.

To solve this issue, add a postrotate section in the logrotate configuration file to reload the configuration file of nginx.

For example, here is the postrotate section of /etc/logrotate.d/apache2:

    postrotate
            if /etc/init.d/apache2 status > /dev/null ; then \
                /etc/init.d/apache2 reload > /dev/null; \
            fi;
    endscript

Solution 3:

Create a file /etc/logrotate.d/nginx with the following content. Works on debian at least. Your mileage may vary

/var/log/nginx/*.log {
    daily
    missingok
    rotate 99
    compress
    delaycompress
    notifempty
    create 0640 www-data adm
    sharedscripts
    postrotate
        /bin/kill -USR1 `cat /run/nginx.pid 2>/dev/null` 2>/dev/null || true
    endscript
}