如何在Nginx日志中记录proxy_pass处理后的URI路径
确实,Nginx没有直接提供一个内置变量来存储proxy_pass处理后的完整目标URI,但我们可以通过拼接现有变量和正则匹配的方式自己实现这个需求,完美适配你当前的配置场景。
针对你的配置场景的解决方案
你的配置是:
location /books/ { proxy_pass http://localhost:8888/; }
当请求http://nginx/books/some-book时,会被代理到http://localhost:8888/some-book。我们可以通过以下步骤在日志中记录这个完整目标地址:
1. 定义自定义日志格式
在http块中添加一个包含代理目标URI的日志格式:
log_format books_proxy_log '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "Proxy Target: $proxy_full_uri"';
2. 使用Map拼接完整代理URI
同样在http块中,用map指令根据请求URI生成代理后的完整地址(这种方式比if指令更高效,符合Nginx的最佳实践):
map $request_uri $proxy_full_uri { # 匹配以/books/开头的请求,捕获后面的路径部分 ~^/books/(?<request_rest>.*)$ http://$proxy_host/$request_rest; # 非该location的请求设为空默认值 default ""; }
这里的$proxy_host是Nginx内置变量,会自动取proxy_pass配置中的主机+端口(也就是localhost:8888),如果以后你修改代理目标地址,无需改动这个拼接规则。
3. 在目标Location中应用日志格式
修改你的location配置,指定使用自定义的日志格式:
location /books/ { proxy_pass http://localhost:8888/; access_log /var/log/nginx/books_proxy_access.log books_proxy_log; }
效果验证
当你发送http://nginx/books/some-book请求后,查看/var/log/nginx/books_proxy_access.log,会看到类似这样的日志条目:
192.168.1.1 - - [10/Oct/2024:14:30:00 +0800] "GET /books/some-book HTTP/1.1" 200 1234 "-" "Mozilla/5.0" "Proxy Target: http://localhost:8888/some-book"
其中Proxy Target字段就是你想要的完整代理URI。
通用场景扩展
如果你的proxy_pass配置没有末尾的斜杠(比如proxy_pass http://localhost:8888;),代理逻辑会把完整的请求URI(包括/books/前缀)拼到代理目标后,这时只需要调整map的正则规则,直接用$request_uri拼接即可:
map $request_uri $proxy_full_uri { ~^/books/.*$ http://$proxy_host$request_uri; default ""; }
内容的提问来源于stack exchange,提问作者Aleksei Budiak




