配置Nginx日志urlencode问题
- 开源代码
- 2025-09-16 21:24:02

文章目录 配置Nginx日志url encode问题方法1-lua方法2-set-misc-nginx-module
配置Nginx日志url encode问题
问题描述:
当自定义日志输出格式,需要输出http请求中url参数时,如果参数中包含中文,是会进行url encode的,所以输出都是编码后的字符串,比如我配置的:
log_format test_log escape=json '{ "timestamp": "$msec", ' '"request": "$request",' '"name": "$arg_name",' '"uuid": "$http_uuid",' '"remoteAddr": "$remote_addr" }';请求 http://192.168.108.130:80/lua?name=我是中文 arg_name输出时就会是这样子:
{ “timestamp”: “1740829638.783”, “request”: “GET /lua?name=%E6%88%91%E6%98%AF%E4%B8%AD%E6%96%87 HTTP/1.1”,“name”: “%E6%88%91%E6%98%AF%E4%B8%AD%E6%96%87”, “uuid”: “-”,“remoteAddr”: “192.168.108.1” }
所以目的是需要把它url decode再输出
方法1-lua首先需要安装Lua,具体可以网上找教程文章看下,这里只提及简要流程
安装lua所需模块包括:
lua-nginx-modulengx_devel_kit ./configure --prefix=/usr/local/nginx \ --pid-path=/var/run/nginx/nginx.pid \ --lock-path=/var/lock/nginx.lock \ --error-log-path=/var/log/nginx/error.log \ --http-log-path=/var/log/nginx/access.log \ --with-http_gzip_static_module \ --http-client-body-temp-path=/var/temp/nginx/client \ --http-proxy-temp-path=/var/temp/nginx/proxy \ --http-fastcgi-temp-path=/var/temp/nginx/fastcgi \ --http-uwsgi-temp-path=/var/temp/nginx/uwsgi \ --http-scgi-temp-path=/var/temp/nginx/scgi \ --with-http_stub_status_module \ --with-http_ssl_module \ --with-file-aio \ --with-http_realip_module \ --with-openssl=/usr/local/software/openssl-1.1.1w \ --add-module=/usr/local/software/lua-nginx-module-0.10.27rc1 \ --add-module=/usr/local/software/ngx_devel_kit-0.3.3然后 make(注意,如果无需替换原nginx目录的内容,则只需要make,不需要make install,然后编译后的objs目录里,把nginx可执行文件copy过去即可,可以先把原来nginx可执行文件备份下)
另外需要本地先安装luajit,比如我安装的 luajit2-2.1-20240626
另外有可能会报错 resty 相关的错误,网上文章有提到用 lua_load_resty_core off; 解决,但是我实际测试无效,故按照错误提示又下载了相关的包:
lua-resty-corelua-resty-lrucachenginx.conf 中添加配置:lua_package_path “/usr/local/software/lua-resty-core-0.1.29/lib/?.lua;”;
安装完成之后,可以测试下lua:
location /lua { default_type 'text/plain'; content_by_lua 'ngx.say("hello, lua")'; }之后加上我们的url解析配置:
set $decoded_arg_name ''; location /lua { default_type 'text/plain'; content_by_lua 'ngx.say("hello, lua")'; access_by_lua_block { local args = ngx.req.get_uri_args() if args.name then local decoded_name = ngx.unescape_uri(args.name) ngx.var.decoded_arg_name = decoded_name ngx.log(ngx.ERR, "Decoded name: ", decoded_name) # 打印日志调试用 end } }完整nginx配置代码如下:
#user nobody; worker_processes 1; #error_log logs/error.log; #error_log logs/error.log notice; #error_log logs/error.log info; #pid logs/nginx.pid; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; #log_format main '$remote_addr - $remote_user [$time_local] "$request" ' # '$status $body_bytes_sent "$http_referer" ' # '"$http_user_agent" "$http_x_forwarded_for"'; log_format test_log escape=json '{ "timestamp": "$msec", ' '"request": "$request",' '"name": "$decoded_arg_name",' '"uuid": "$http_uuid",' '"remoteAddr": "$remote_addr" }'; #access_log logs/access.log main; access_log logs/test_access.log test_log; sendfile on; #tcp_nopush on; lua_load_resty_core off; lua_package_path "/usr/local/software/lua-resty-core-0.1.29/lib/?.lua;"; #keepalive_timeout 0; keepalive_timeout 65; #gzip on; server { listen 80; server_name localhost; set $decoded_arg_name ''; #charset koi8-r; charset utf-8; #access_log logs/host.access.log main; location / { root html; index index.html index.htm; } location /lua { default_type 'text/plain'; content_by_lua 'ngx.say("hello, lua")'; access_by_lua_block { local args = ngx.req.get_uri_args() if args.name then local decoded_name = ngx.unescape_uri(args.name) ngx.var.decoded_arg_name = decoded_name ngx.log(ngx.ERR, "Decoded name: ", decoded_name) end } } #error_page 404 /404.html; # redirect server error pages to the static page /50x.html # error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } } }但加上上面这一部还不够,lua的输出日志,如果是非ascii码,会输出为十六进制字符串:像是:
{ “timestamp”: “1740835690.677”, “request”: “POST /lua?name=%E6%88%91%E6%98%AF%E4%B8%AD%E6%96%87 HTTP/1.1”,“name”: “\xE6\x88\x91\xE6\x98\xAF\xE4\xB8\xAD\xE6\x96\x87”,“uuid”: “testuuid”,“remoteAddr”: “192.168.108.1” }
对于这个问题,偏新版的nginx可以通过加上 escape=json解决:
log_format test_log escape=json '{ "timestamp": "$msec", ' '"request": "$request",' '"name": "$decoded_arg_name",' '"uuid": "$http_uuid",' '"remoteAddr": "$remote_addr" }';至此打印的日志则是中文了:
{ “timestamp”: “1740834963.209”, “request”: “POST /lua?name=%E6%88%91%E6%98%AF%E4%B8%AD%E6%96%87 HTTP/1.1”,“name”: “我是中文”,“uuid”: “testuuid”,“remoteAddr”: “192.168.108.1” }
方法2-set-misc-nginx-module在nginx中添加此模块,下载模块包 set-misc-nginx-module-0.33 解压后,configure命令如下:
./configure --prefix=/usr/local/nginx \ --pid-path=/var/run/nginx/nginx.pid \ --lock-path=/var/lock/nginx.lock \ --error-log-path=/var/log/nginx/error.log \ --http-log-path=/var/log/nginx/access.log \ --with-http_gzip_static_module \ --http-client-body-temp-path=/var/temp/nginx/client \ --http-proxy-temp-path=/var/temp/nginx/proxy \ --http-fastcgi-temp-path=/var/temp/nginx/fastcgi \ --http-uwsgi-temp-path=/var/temp/nginx/uwsgi \ --http-scgi-temp-path=/var/temp/nginx/scgi \ --with-http_stub_status_module \ --with-http_ssl_module \ --with-file-aio \ --with-http_realip_module \ --with-openssl=/usr/local/software/openssl-1.1.1w \ --add-module=/usr/local/software/lua-nginx-module-0.10.27rc1 \ --add-module=/usr/local/software/ngx_devel_kit-0.3.3 \ --add-module=/usr/local/software/set-misc-nginx-module-0.33以上添加模块的lua相关的两个模块,可能可以不用加,但我测试的时候没有去掉,这里可以看大家需求
然后 make(注意,如果无需替换原nginx目录的内容,则只需要make,不需要make install,然后编译后的objs里,把nginx可执行文件copy过去即可,可以先把原来nginx可执行文件备份)
更改 nginx.conf
set $decoded_arg_name ''; set_unescape_uri $decoded_arg_name $arg_name;再同样加上 escape=json
其他什么的都不用配置了,实现效果是一样的。
配置Nginx日志urlencode问题由讯客互联开源代码栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“配置Nginx日志urlencode问题”