为nginx日志增加请求体及响应内容记录
为nginx日志增加请求体及响应内容记录,一方面可以记录网站或者nginx代理的某服务详细的请求/响应内容,以便发现bug时可以回溯追查,另一方面可以配合gotty实现实时的请求数据显示,从而在开发过程中省去了打日志或者抓包的麻烦。
安装Lua-Nginx-Module
debian系很简单,直接通过包管理就可以安装:
1 | sudo apt install libnginx-mod-http-lua |
Redhat系就比较烦,没找到提供该模块的repo,但是通过源码编译是不可能编译的,这辈子都不可能用源码编译的←_←,参考文档 https://github.com/openresty/lua-nginx-module#installation ,可以安装 OpenResty 获得开箱即用的 Nginx 和 ngx_lua 模块,根据 安装文档 ,CentOS的安装方法:
1 | add the yum repo: |
这样安装好以后,OpenResty 将会被安装到 /usr/local/openresty/
这个路径下,而它提供的 Nginx 则是其中的 /usr/local/openresty/nginx/sbin/nginx
, 官方推荐的使用方式是将这个路径加入环境变量 PATH 中,这显然不是个好习惯,尤其是在已经安装过 Nginx 的情况下,所以还是做个软链接吧:
1 | 如果已经安装了Nginx,先把它重命名 |
这样就不用做任何修改,还可以复用之前包管理安装 Nginx 的服务(/usr/lib/systemd/system/nginx.service
),继续使用 systemctl 来管理 Nginx 服务的运行
修改 Nginx 配置
首先定义日志格式:
1 | log_format postdata escape=json '{"realip":"$remote_addr","timestamp":"$time_iso8601","request":"$request","req_body":"$request_body","status":"$status","resp_body":"$resp_body"}'; |
其中 postdata
为自定义日志格式的名称;escape=json
用来对日志内容进行转义,否则日志中会出现类似 \x22
这样的内容影响阅读;timestamp
有 $time_iso8601
和 $time_local
两种格式, $time_iso8601
相对来说可读性高一些;$request_body
和 $resp_body
即是用来输出请求和响应的内容,这两个变量都需要在下面的服务配置中做相应设置才能使用
在
1 | server { |
中加入:
1 | server { |
最后在需要的 location
中加入日志配置:
1 | access_log /var/log/nginx/postdata.log postdata; |
完整配置如下:
1 | log_format postdata escape=json '{"realip":"$remote_addr","timestamp":"$time_iso8601","request":"$request","req_body":"$request_body","status":"$status","resp_body":"$resp_body"}'; |
利用 Gotty 实现实时请求数据显示
GoTTY 是一个简单的基于 Go 语言的命令行工具,它可以将你的终端(TTY)作为 web 程序共享。它会将命令行工具转换为 web 程序。
首先利用 tail 命令,可以实时跟踪日志文件的追加内容并输入:
1 | -f 参数表示循环读取, -n 3 表示执行时先读取最后三行 |
然后将其输出给 jq
命令:
1 | tail -f -n 3 /var/log/nginx/postdata.log | jq |
如果不想安装
jq
也可以用python -m json.tool
代替,但是json.tool
在遇到不合法的 json 时会输出错误,而使用jq
则没有这个问题
这样就可以在服务器的 Terminal 上实时查看请求和响应的数据了:
然后利用 Gotty 把它变成 web 服务:
1 | /root/gotty -p 8888 -c [user]:[passwd] sh -c 'tail -f -n 3 /var/log/nginx/postdata.log | jq' >> /dev/null 2>&1 & |
用 root 帐号执行以避免权限问题,使用
-c [user]:[passwd]
设置使用网页访问时需要提供的帐户名和密码以提高安全性,使用sh -c
以开启一个 shell 来执行我们的命令
还可以利用 crontab 将其设置为开机执行:
1 @reboot /root/gotty -p 8888 -c shixin:gogo2020 sh -c 'tail -f -n 3 /var/log/nginx/postdata.log | jq' >> /dev/null 2>&1 &