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