最近碰到研发特殊需求,需要获取请求服务后返回的响应体,因Nginx原生不支持此功能,使用lua实现,在此记录下
location 配置
注意: 注释的代码是针对upstream本身已对response body做gzip压缩的情况,为此还需要编译下lua-zlib库
location /xxxxxxx {
...
...
body_filter_by_lua_block {
-- local zip = require 'zlib'
-- local uncompress = zip.inflate()
local buffered = ngx.ctx.buffered
if not buffered then
buffered = {}
ngx.ctx.buffered = buffered
end
local chunk, eof = ngx.arg[1], ngx.arg[2]
if chunk ~= '' then
buffered[#buffered + 1] = chunk
ngx.arg[1] = nil
end
if eof then
ngx.ctx.buffered = nil
local whole = table.concat(buffered)
ngx.arg[1] = whole
-- whole, eof, bytes_in, bytes_out = uncompress(whole)
-- ngx.var.resp_body = whole
ngx.log(ngx.ERR,"resp_body: ", whole)
end
}
编译lua-zlib库
注意: 以下代码在L7机器上编译,如在其他环境编译,请将zlib.so放在要调试的L7机器相关位置
cd /usr/local/src
wget https://codeload.github.com/brimworks/lua-zlib/zip/refs/heads/master
unzip lua-zlib-master.zip
cd lua-zlib-master
cmake -DLUA_INCLUDE_DIR=/home/work/nginx/luajit/include/luajit-2.1/ -DLUA_LIBRARIES=/home/work/nginx/luajit/lib-DUSE_LUAJIT=ON -DUSE_LUA=OFF
make
cp zlib.so /home/work/nginx/luajit/lib/lua/5.1/
Extra:单独日志输出
1. nginx.conf 日志文件
# 先建立变量
map $hostname $resp_body {
default "";
}
# 再建立log_format
log_format debug_json escape=json '{"time":"$time_iso8601",'
'"http_host":"$http_host",'
'"cluster":"$cluster",'
'"server_addr":"$server_addr",'
'"hostname":"$hostname",'
'"remote_addr":"$remote_addr",'
'"http_x_forwarded_for":"$http_x_forwarded_for",'
'"server_protocol":"$server_protocol",'
'"scheme":"$scheme",'
'"ssl_protocol":"$ssl_protocol",'
'"ssl_cipher":"$ssl_cipher",'
'"status":"$status",'
'"request_method":"$request_method",'
'"request_uri":"$request_uri",'
'"http_user_agent":"$http_user_agent",'
'"http_referer":"$http_referer",'
'"http_x_mi_xflag":"$http_x_mi_xflag",'
'"http_x_mi_xprotocol":"$http_x_mi_xprotocol",'
'"upstream_cache_status":"$upstream_cache_status",'
'"request_length":"$request_length",'
'"upstream_addr":"$upstream_addr",'
'"upstream_bytes_received":"$upstream_bytes_received",'
'"upstream_response_time":"$upstream_response_time",'
'"body_bytes_sent":"$body_bytes_sent",'
'"request_time":"$request_time",'
'"bytes_sent":"$bytes_sent",'
'"proxy_host":"$proxy_host,'
'"resp_body":"$resp_body"}';
2. location 设置access_log
access_log /home/work/log/nginx/debug.json debug_json;