7

I am running Ubuntu 15.04 and have a standard installation of nginx (apt-get install nginx) running.

Everything is running fine but I notice that the nginx logs are being rotated but nginx carries on outputting to the same log file e.g. /var/log/nginx/error.log is empty yet /var/log/nginx/error.log.1 is getting stuff written to it.

Of course if I restart nginx the regular log file starts to get written to. Is there a bug somewhere in the logrotate script? Does it need to restart nginx on a rotate ?

3 Answers 3

6

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

4
  • 1
    definitely the right thing to do.. You have to be wary of things like fail2ban nginx filters and other things dependent on the log files.. But yep. Much better. I have a problem though turning on access_log to stderr. With the example above using syslog:server=unix:/dev/log; I get: nginx: [emerg] open() "/usr/share/nginx/syslog:server=unix:/dev/log" failed (2: No such file or directory) nginx: configuration file /etc/nginx/nginx.conf test failed
    – willwade
    Commented Jul 27, 2015 at 15:25
  • Does this pertain to only Ubuntu 15 and higher, or did the change come with an earlier version?
    – Sonny
    Commented Feb 2, 2016 at 17:05
  • See the operating system's own release notes, and the many items here on Ask Ubuntu such as askubuntu.com/questions/613366 .
    – JdeBP
    Commented Feb 4, 2016 at 7:19
  • upvoted! any ideas for 18.04
    – PirateApp
    Commented Aug 27, 2019 at 5:59
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
1
  • @Arronical I have not used nginx so i am not sure but the concept is generic..
    – heemayl
    Commented May 28, 2015 at 15:22
1

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
}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .