配置Nginx日志url encode問題及解決
問題描述
當自定義日志輸出格式,需要輸出http請求中url參數(shù)時,如果參數(shù)中包含中文,是會進行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,具體可以網(wǎng)上找教程文章看下,這里只提及簡要流程
安裝lua所需模塊包括:
- lua-nginx-module
- ngx_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目錄的內(nèi)容,則只需要make,不需要make install,然后編譯后的objs目錄里,把nginx可執(zhí)行文件copy過去即可,可以先把原來nginx可執(zhí)行文件備份下)
另外需要本地先安裝luajit,比如我安裝的 luajit2-2.1-20240626
另外有可能會報錯 resty 相關(guān)的錯誤,網(wǎng)上文章有提到用 lua_load_resty_core off; 解決,但是我實際測試無效,故按照錯誤提示又下載了相關(guān)的包:
- lua-resty-core
- lua-resty-lrucache
nginx.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) # 打印日志調(diào)試用
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相關(guān)的兩個模塊,可能可以不用加,但我測試的時候沒有去掉,這里可以看大家需求
然后 make(注意,如果無需替換原nginx目錄的內(nèi)容,則只需要make,不需要make install,然后編譯后的objs里,把nginx可執(zhí)行文件copy過去即可,可以先把原來nginx可執(zhí)行文件備份)
更改 nginx.conf
set $decoded_arg_name ''; set_unescape_uri $decoded_arg_name $arg_name;
再同樣加上 escape=json
其他什么的都不用配置了,實現(xiàn)效果是一樣的。
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Nginx一鍵安裝部署靜態(tài)網(wǎng)頁的過程詳解
這篇文章主要介紹了Nginx一鍵安裝部署靜態(tài)網(wǎng)頁,主要介紹nginx安裝和部署,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧2022-06-06
Nginx反向代理+DNS輪詢+IIS7.5 千萬PV 百萬IP 雙線 網(wǎng)站架構(gòu)案例
某公司有一站點,一天IP 430W,PV 3100W,之前采用5臺 DELL R610 做NLB,系統(tǒng)2008 IIS7.5.每天高峰期時都不堪重負.會出現(xiàn)以下情況2012-11-11
nginx配置請求轉(zhuǎn)發(fā)不生效的實現(xiàn)
本文主要介紹了nginx配置請求轉(zhuǎn)發(fā)不生效的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2025-02-02
nginx幾種網(wǎng)頁重定向(rewirte)的配置方法詳解
這篇文章主要詳細介紹了nginx幾種網(wǎng)頁重定向(rewirte)的配置方法,文中通過代碼示例和圖文介紹的非常詳細,對大家的學習或工作有一定的幫助,需要的朋友可以參考下2024-02-02
nginx配置proxy_pass后返回404問題以及Nginx host相關(guān)變量的說明
這篇文章主要介紹了nginx配置proxy_pass后返回404問題以及Nginx host相關(guān)變量的說明,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-01-01
Nginx流量拷貝ngx_http_mirror_module模塊使用方法詳解
這篇文章主要介紹了Nginx流量拷貝,Nginx專門提供了ngx_http_mirror_module模塊,用來實現(xiàn)流量拷貝。將生產(chǎn)環(huán)境的流量拷貝到預(yù)上線環(huán)境或測試環(huán)境2022-04-04

