【问题标题】:Nginx logging to access.log.1 instead of access.logNginx 记录到 access.log.1 而不是 access.log
【发布时间】:2023-03-12 09:25:01
【问题描述】:

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

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,之后不会轮换日志文件。

编辑:已经在 cmets 中指出,您看到 access.log 的访问时间比 access.log.1 晚的原因是因为我在这样做之前重新启动了 nginx ls,只是为了确保在发帖之前对我自己来说,确实重新启动 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;

        ( ... )

【问题讨论】:

  • 那么为什么我们看到 access.log 会在以后更新 acces.log.1 呢?从您向我们展示的内容看来,它工作正常。
  • 因为在我这样做之前我刚刚重新启动了 nginx ls
  • 您能否发布一部分 nginx 配置文件,其中指定有关日志记录的任何内容?
  • @Neal 完成,请检查。

标签: logging nginx logrotate


【解决方案1】:

解决了。

我的问题和this 差不多,但不完全一样。在那篇文章中,作者最终解决了这个问题,并说问题是“nginx 在收到来自 kill 的 -USR1 信号时没有释放文件句柄到日志文件。长话短说,它没有重新加载日志文件的原因是因为 /var/log/nginx 文件夹不属于与 nginx 工作进程相同的用户(由 www-data 拥有,在 web 下运行)。”正如我们所见,这不是我的问题,因为我的权限是正确的。但是,我去比较了我的 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

这解决了问题。

【讨论】:

  • 很高兴你找到了这个!我在想(非常模糊)与 logrotate 相关的事情,但很高兴它已经解决了。
  • kill -USR1 cat /run/nginx.pid -- 不会重启 nginx 吗?它只是重新打开日志文件对吗?
【解决方案2】:

这里有一些更好的解决方案

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

所以:

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

【讨论】:

    猜你喜欢
    • 2020-06-20
    • 2013-10-19
    • 2012-03-22
    • 2011-06-15
    • 2012-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多