配置Nginx日志url encode问题

文章目录


配置Nginx日志url encode问题

问题描述:

当自定义日志输出格式,需要输出http请求中url参数时,如果参数中包含中文,是会进行url encode的,所以输出都是编码后的字符串,比如我配置的:

bash 复制代码
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所需模块包括:

  1. lua-nginx-module
  2. ngx_devel_kit
bash 复制代码
./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; 解决,但是我实际测试无效,故按照错误提示又下载了相关的包:

  1. lua-resty-core
  2. lua-resty-lrucache

nginx.conf 中添加配置:lua_package_path "/usr/local/software/lua-resty-core-0.1.29/lib/?.lua;";

安装完成之后,可以测试下lua:

bash 复制代码
location /lua {
    default_type 'text/plain';

    content_by_lua 'ngx.say("hello, lua")';
}

之后加上我们的url解析配置:

bash 复制代码
set $decoded_arg_name  '';
bash 复制代码
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配置代码如下:

bash 复制代码
#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解决:

bash 复制代码
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命令如下:

bash 复制代码
./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

bash 复制代码
set $decoded_arg_name  '';
set_unescape_uri $decoded_arg_name $arg_name;

再同样加上 escape=json

其他什么的都不用配置了,实现效果是一样的。

相关推荐
迁就却不将就31 分钟前
Linux总结
linux·运维·服务器
obboda33 分钟前
web高可用集群项目(数据库主从同步、文件共享存储、nginx动静分离+负载均衡+高可用)
数据库·nginx·负载均衡
沧浪之水!40 分钟前
Linux:文件系统的初步认识
linux·运维·服务器
m0_748257461 小时前
Linux系统编程:深入理解计算机软硬件体系和架构
linux·运维·架构
SuperGodK1 小时前
在linux上部署kubesphere
运维·服务器
Kevin__471 小时前
Ubuntu录屏--OBS
linux·运维·ubuntu
筑梦之路3 小时前
CentOS 7 aarch64上制作kernel rpm二进制包 —— 筑梦之路
linux·运维·centos
pitt19973 小时前
企业日常工作中常用的 Linux 操作系统命令整理
linux·运维·操作系统命令
星空露珠3 小时前
迷你世界脚本对象库接口:ObjectLib
数据结构·游戏·lua
星空露珠3 小时前
迷你世界脚本小地图接口:Mapmark
数据结构·游戏·lua