L7获取response body

最近碰到研发特殊需求,需要获取请求服务后返回的响应体,因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;

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注