Nginx 反向代理的日志记录问题

Logging issue with Nginx reverse proxy

我正在使用以下 Nginx 反向代理配置。

server {
    listen      80;
    listen      [::]:80;
    server_name www.test.com;

    access_log /var/log/nginx/www.test.com.access.log;
    error_log  /var/log/nginx/www.test.com.error.log warn;

    location / {
        proxy_pass                         http://12.23.45.78:8080;
        proxy_http_version                 1.1;
        proxy_set_header Connection        "";
        proxy_set_header Host              $host;
        proxy_set_header X-Real-IP         $remote_addr;
        proxy_set_header X-Forwarded-For   $remote_addr;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-Host  $host;
        proxy_set_header X-Forwarded-Port  $server_port;
    }
}

通过添加access_logerror_log参数,它会记录访问日志。

现在我想跳过一些日志记录,比如不记录favicon.icoapple-touch-icon.png,所以我添加了以下配置。

location ~* ^/(?:favicon|apple-touch-icon) {
    log_not_found off;
    access_log    off;
}

但是问题来了,我这样做的时候,http://www.test.com/favicon.ico无法正常访问,提示“404 Not Found”错误。

这似乎表明反向代理主机正在接管favicon.ico访问,而没有将其转发到上游进行处理,请问这是正常的Nginx行为吗?

如果这是正常行为,我应该如何设置不记录给定资源?

提前感谢任何帮助!

每个请求都在某个位置结束(如果之前没有完成)。每个位置都使用自己的 内容处理程序 。除非您通过内容处理程序声明指令明确指定某些内容(示例包括,位不限于 proxy_passfastcgi_passuwsgi_pass 等),它将是一个 static 内容处理程序,用于从本地文件系统提供请求的内容。查看我的 ServerFault 答案 (1, 2) 以了解更多详细信息。

在某些情况下,可以使用 map 块解决此类任务,例如

map $uri $log {
    ~^/(?:favicon|apple-touch-icon)  off;
    default                          /var/log/nginx/access.log;
}
server {
    ...
    access_log  $log;

当您需要实施条件基本身份验证 (example) 时,此方法可以发挥作用。不幸的是,它 无法与 access_log 指令一起工作 - 相反,nginx 将为图标请求创建名为 off 的第二个日志文件。因此,如果您希望每个请求都传递到 12.23.45.78 上游,我看不到任何其他方法,只能为两个位置复制内容处理程序声明。然而,所有其他使用的指令都可以向上移动一个级别,因此被两个位置继承:

server {
    listen      80;
    listen      [::]:80;
    server_name www.test.com;

    error_log  /var/log/nginx/www.test.com.error.log warn;

    proxy_http_version                 1.1;
    proxy_set_header Connection        "";
    proxy_set_header Host              $host;
    proxy_set_header X-Real-IP         $remote_addr;
    proxy_set_header X-Forwarded-For   $remote_addr;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-Host  $host;
    proxy_set_header X-Forwarded-Port  $server_port;
    location / {
        access_log  /var/log/nginx/www.test.com.access.log;
        proxy_pass  http://12.23.45.78:8080;
    }
    location ~ ^/(?:fav|apple-touch-)icon {
        access_log  off;
        proxy_pass  http://12.23.45.78:8080;
    }
}

另一方面,没有什么可以阻止您在本地提供这两个文件并且不将这些请求传递到任何地方。只需将它们放入某个专用目录并使用带有静态内容处理程序的位置:

location ~ ^/(?:fav|apple-touch-)icon {
    access_log  off;
    root  /full/path/to/folder/with/icons;
}