Nginx 1.19+ 废弃 rewrite_log,需用 error_log /path notice 启用重写日志;关注 *NNN 行中的 regex 匹配、rewritten data 和 test location;多级重写注意 if 中 break 与 return 差异;复杂条件推荐 map + log_format 替代。

rewrite_log 是 Nginx 调试重写规则最直接的工具,但它默认关闭、日志级别高、输出位置特殊——不搞清这些,光开日志也看不到有效信息。
开启 rewrite_log 的正确姿势
Nginx 1.19+ 已废弃 rewrite_log on 指令,改用 error_log 配合 notice 或更高级别。关键不是“打开”,而是让重写过程真正被记录:
- 在
http、server或location块中添加:error_log /var/log/nginx/rewrite.log notice; - 确保该路径 Nginx 进程有写权限(常被忽略)
- 重载配置后,执行一次触发重写的请求(如访问带参数的 URL),再查日志
- 注意:
notice级别才记录 rewrite 匹配与跳转;warn和error不会输出重写轨迹
识别日志中的关键线索
rewrite.log 每行以 "*NNN" 开头(NNN 是连接 ID),后面紧跟重写动作。重点关注三类输出:
-
using regex "^/old/(.*)$" ...→ 表示正则匹配成功,正在执行重写 -
rewritten data: "/new/$1"→ 显示变量展开后的目标路径(可验证 $1、$args 是否如预期) -
test location: "/"或using configuration "/new/"→ 表明重写后进入哪个 location 块,这是全局规则链路断裂的高发点
若看到 no matching location 或反复出现 test location 却无后续,说明重写结果未落入任何 location,请求可能被丢给 default_server 或返回 404。
调试多级重写的典型陷阱
全局规则常嵌套:server → location → if → rewrite → 再进 location。日志里会出现连续多行 test location,容易误判。实战建议:
- 用
curl -v http://example.com/xxx观察真实响应状态码和跳转头,和日志比对是否一致 - if 块内 rewrite 在 0.9.1+ 后才支持 break,否则会继续执行后续指令——日志里能看到“又 test 了一次 location”
- 避免在 if 中用
return+rewrite混用,它们执行顺序不同,日志行为不直观 - 临时加一条
rewrite ^(.*)$ /debug-rewrite$1 break;到顶层 location,把所有流量导到一个专用块,集中观察变量值
替代方案:用 map + log\_format 辅助验证
rewrite_log 只在错误日志中输出,且无法格式化。对复杂条件(如根据 $arg_x 或 $http_user_agent 重写),推荐组合使用:
- 定义 map 将判断逻辑外置:
map $arg_v $version_route { default "/v1/"; "2" "/v2/"; } - 在 log_format 中加入变量:
log_format debug "$remote_addr – $request_uri → $version_route $args"; - 配合 access_log 查看每次请求的实际路由选择,比 rewrite_log 更稳定、易过滤
这种方式不依赖 error_log 级别,也不受 if 执行模型干扰,适合长期监控或灰度验证。

















