Nginx记录到access.log.1而不是access.log

时间:2016-08-28 19:05:20

标签: logging nginx logrotate

我知道之前有人问过,但我相信这是一个不同的问题。

Nginx在www-data下运行:

$ ps -eo "%U %G %a" | grep nginx
root     root     nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
www-data www-data nginx: worker process

/var/log/nginx/*拥有正确的权限:

$ ls -lah /var/log/nginx/
total 291M
drwxr-x---  2 www-data adm     4.0K Jul 25 06:25 .
drwxrwxr-x 14 root     syslog  4.0K Aug 28 06:25 ..
-rw-r-----  1 www-data adm      12K Aug 28 19:03 access.log
-rw-r-----  1 www-data adm     250M Aug 28 18:50 access.log.1

Logrotate使用正确的权限创建日志文件:

/var/log/nginx/*.log {
        ( ... )
        create 0640 www-data adm

Nginx在重新启动时会记录到access.log,但在logrotate第一次运行后会移至access.log.1。之后,始终记录到access.log.1,之后不会旋转日志文件。

编辑:在评论中指出,您之后access.log访问access.log.1的原因是因为我在我做ls之前就重新启动了nginx为了确保自己在发布之前,确实重新启动nginx正在修复问题(直到下一个logrotate)。但在此之前ls nginx已经登录access.log.1大约3周......

EDIT2:这是/etc/nginx/nginx.conf,提及记录的头部和位

user www-data;
worker_processes auto;
pid /run/nginx.pid;

( ... )

http {

        ( ... )
        ##
        # Logging Settings
        ##

        access_log /var/log/nginx/access.log;
        error_log /var/log/nginx/error.log;

        ( ... )

2 个答案:

答案 0 :(得分:5)

解决。

我的问题几乎就像this但不完全相同。在那一篇中,作者最终解决了这个问题,并说问题是" nginx在从kill接收到-USR1信号时没有释放日志文件的文件句柄。简而言之,它没有重新加载日志文件的原因是因为/ var / log / nginx文件夹不是由与nginx工作进程相同的用户所拥有(由www-data拥有,在web下运行)。&#34 ;正如我们所见,这不是我的问题,因为我的权限是正确的。但是,我把我的logrotate日志和那个问题上的日志进行了比较,并找到了一些东西。在该问题上,kill信号成功终止,但由于权限,nginx不会释放文件句柄。就我而言,invoke-rc.d命令不会成功终止。 nginx的logrotate配置如下:

/var/log/nginx/*.log {
        weekly
        missingok
        rotate 52
        compress
        delaycompress
        notifempty
        create 0640 www-data adm
        sharedscripts
        prerotate
                if [ -d /etc/logrotate.d/httpd-prerotate ]; then \
                        run-parts /etc/logrotate.d/httpd-prerotate; \
                fi \
        endscript
        postrotate
                invoke-rc.d nginx rotate >/dev/null 2>&1
        endscript
}

请注意postrotate脚本,它是告诉nginx执行其操作的命令,对于另一个线程上的作者,该命令是kill信号。在我的logrotate日志中,我收到以下错误(顺便说一句,你可以通过执行sudo logrotate -f -v /etc/logrotate.d/nginx强制logrotate):

( last two lines ... )
running postrotate script
error: error running shared postrotate script for '/var/log/nginx/*.log '

当我使用你在logrotate / nginx配置中看到的postrotate脚本并手动执行它时,它会出错:

$ invoke-rc.d nginx rotate
initctl: invalid command: rotate
Try `initctl --help' for more information.
invoke-rc.d: initscript nginx, action "rotate" failed.

这是nginx中的bug。所以我所做的就是将该命令替换为另一个线程上的人正在使用的命令。所以现在配置文件中的logrotate / nginx postrotate脚本是

postrotate
        kill -USR1 `cat /run/nginx.pid`
endscript

这解决了这个问题。

答案 1 :(得分:0)

从这里获得一些更好的解决方案

https://unix.stackexchange.com/questions/186807/what-does-nginx-s-reopen-do

所以:

postrotate
  invoke-rc.d nginx -s reopen >/dev/null 2>&1
endscript