I was looking for an answer to this question, and found this:
Basically, uses a lua script to gather and log all headers:
ngx.log(ngx.ERR, "REQUEST capturing started")
json = require("json")
function getval(v, def)
if v == nil then
return def
end
return v
end
local data = {request={}, response={}}
local req = data["request"]
local resp = data["response"]
req["host"] = ngx.var.host
req["uri"] = ngx.var.uri
req["headers"] = ngx.req.get_headers()
req["time"] = ngx.req.start_time()
req["method"] = ngx.req.get_method()
req["get_args"] = ngx.req.get_uri_args()
req["post_args"] = ngx.req.get_post_args()
req["body"] = ngx.var.request_body
content_type = getval(ngx.var.CONTENT_TYPE, "")
resp["headers"] = ngx.resp.get_headers()
resp["status"] = ngx.status
resp["duration"] = ngx.var.upstream_response_time
resp["time"] = ngx.now()
resp["body"] = ngx.var.response_body
ngx.log(ngx.CRIT, json.encode(data));
Then, refer to it from the nginx configuration:
location / {
proxy_pass http://127.0.0.1:8081/;
log_by_lua_file lua/request_logger.lua;
}
To gather the body, a block is needed in nginx main.conf:
#we must declare variables first, we cannot create vars in lua
set $response_body '';
body_filter_by_lua_block {
-- arg[1] contains a chunk of response content
local resp_body = string.sub(ngx.arg[1], 1, 1000)
ngx.ctx.buffered = string.sub((ngx.ctx.buffered or "") .. resp_body, 1, 1000)
-- arg[2] is true if this is the last chunk
if ngx.arg[2] then
ngx.var.response_body = ngx.ctx.buffered
end
}
The post linked above details this a lot better.