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.serviceYou 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
}