nginx中用lua在请求分发前记录调试日志,应使用access_by_lua*阶段,在rewrite后、upstream路由前执行;需启用debug日志、合理选取上下文变量(如host、uri、user_agent等)、输出json结构化日志并脱敏敏感字段。

在 Nginx 中用 Lua 在请求分发前记录详细调试日志与上下文,核心是利用 ngx_lua 模块的 access_by_lua* 阶段 —— 它在 rewrite 之后、proxy_pass 或 upstream 路由之前执行,正好满足“分发前”这一时机要求。
启用 Lua 环境与日志配置
确保已编译或安装了支持 Lua 的 Nginx(如 OpenResty),并在 nginx.conf 全局或 http 块中开启调试日志级别:
- 设置
error_log /path/to/debug.log debug;(注意:debug 级别需重新编译时启用--with-debug) - 使用
lua_package_path和lua_package_cpath加载自定义模块(如需) - 推荐用
access_by_lua_block替代access_by_lua_file,便于快速迭代调试逻辑
记录关键上下文字段(分发前必采)
在 access_by_lua_block 中可安全读取并记录以下变量,它们在 upstream 选择前均已就绪:
-
ngx.var.host、ngx.var.remote_addr、ngx.var.http_user_agent—— 客户端基础信息 -
ngx.var.request_uri、ngx.var.args、ngx.var.request_method—— 请求路径与参数 -
ngx.var.http_x_forwarded_for、ngx.var.http_x_real_ip—— 真实 IP 链路(注意可信代理配置) -
ngx.var.upstream_http_*不可用(尚未选 upstream),但ngx.var.proxy_host等 proxy 指令变量也未生效,切勿误用
结构化日志输出与性能兼顾
避免用 ngx.log(ngx.DEBUG, ...) 拼接长字符串(易阻塞、难解析),推荐方式:
- 用
ngx.say或ngx.header仅用于调试响应,生产环境禁用 - 用
ngx.log(ngx.DEBUG, json:encode{...})输出 JSON 行日志(需require "cjson") - 对高流量接口,加条件日志:例如只对特定 path、header 或抽样率(
math.random() )记录完整上下文 - 敏感字段如
ngx.var.http_authorization、ngx.var.args中的 token 参数应脱敏再记录
结合 map 或 set_by_lua 提前准备动态上下文
若需在日志中体现路由决策依据(如基于 header 的灰度标记),可在 access_by_lua_block 前用 set_by_lua_block 预计算:
- 在 server 块中定义:
set_by_lua_block $route_tag { return ngx.var.http_x_env == "staging" and "staging-v2" or "default" } - 然后在 access 阶段直接引用:
ngx.log(ngx.DEBUG, "route_tag:", ngx.var.route_tag) - 这种方式比在 access 中重复判断更轻量,且变量可被后续 proxy_set_header 复用











