Home > Mobile >  Logging issue with Nginx reverse proxy
Logging issue with Nginx reverse proxy

Time:05-27

I am using the following Nginx reverse proxy configuration.

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;
    }
}

By adding the access_log and error_log parameters, it will log the access log.

Now I want to skip some logging, such as not logging favicon.ico and apple-touch-icon.png, so I added the following configuration.

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

But here is the problem, when I do this, http://www.test.com/favicon.ico will not be accessed properly, it prompts "404 Not Found" error.

It seems to indicate that the reverse proxy host is taking over the favicon.ico access without forwarding it to upstream for processing, is this normal Nginx behavior please?

If this is normal behavior, how should I set not to log for a given resource?

Any help is appreciated in advance!

CodePudding user response:

Every request ends up in some location (if not being finished before). Every location uses its own content handler. Unless you specify something explicitly via content handler declaration directive (examples include, bit not limited to proxy_pass, fastcgi_pass, uwsgi_pass, etc.), it will be a static content handler to serve the requested content from local filesystem. Check my ServerFault answers (1, 2) to find out some more details.

In some cases such a task can be solved using the map block, e.g.

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

This approach can work when you need to implement lets say conditional basic auth (example). Unfortunately it won't work with the access_log directive - instead nginx will create the second log file named off for icon requests. So if you want every request to be passed to the 12.23.45.78 upstream, I don't see any other way but to duplicate content handler declaration for both locations. However every other used directive can be moved one level up, thus being inherited by both locations:

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;
    }
}

On the other hand, nothing can stop you from serving those two files locally and not passing those requests anywhere. Just put them into some dedicated directory and use a location with a static content handler:

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