配置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

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

相关推荐
deeper_wind14 分钟前
防火墙设置实战操作案例(小白的“升级打怪”成长之路)
linux·运维·网络
huangyuchi.23 分钟前
【Linux】自动化构建-Make/Makefile
linux·运维·服务器·笔记·自动化·makefile·make
搬码临时工1 小时前
什么是内网映射?如何将内网ip映射到外网访问?
运维·服务器·网络·网络协议·tcp/ip·智能路由器
千里镜宵烛1 小时前
Linux--进程概念
linux·运维·服务器
中云时代-防御可测试-小余2 小时前
高防服务器价格高原因分析
运维·服务器·tcp/ip·安全·web安全·udp·ddos
IT葛大侠3 小时前
OSPF域间路由
运维·网络·计算机网络
搬码临时工3 小时前
有公网ip但外网访问不到怎么办?内网IP端口映射公网连接常见问题和原因
运维·服务器·网络·网络协议·tcp/ip·php·远程工作
huangyuchi.3 小时前
【Linux】编译器gcc/g++及其库的详细介绍
linux·运维·服务器·笔记·编译器·gcc·g++
egoist20235 小时前
【Linux仓库】冯诺依曼体系结构与操作系统【进程·壹】
linux·运维·服务器·开发语言·操作系统·冯诺依曼体系结构
白总Server6 小时前
Golang 依赖注入:构建松耦合架构的关键技术
linux·运维·服务器·macos·架构·golang·xcode