直接在http块中定义log_format并使用$upstream_addr变量可记录实际后端ip和端口,该变量仅在proxy_pass完成通信后生效,需配合access_log启用且推荐加入$upstream_response_time以便性能分析。

直接在 log_format 中使用 $upstream_addr 变量,就能记录 upstream 节点的实际 IP 和端口。这个变量只在 proxy_pass 生效且完成通信后才有值,准确反映本次请求真正到达的后端地址。
必须在 http 块中定义日志格式
不能把 log_format 写在 server 或 location 里,否则无法被 access_log 正确识别。示例配置:
- 在
http块顶部或合适位置添加:
-
upstream="$upstream_addr"是核心,加引号便于后续结构化解析 - 推荐同时带上
$upstream_response_time,方便比对各节点响应快慢 - 若需区分重试路径,该变量会以逗号分隔多个地址(如
10.0.2.10:8080, 10.0.2.11:8080)
确保 proxy_pass 真正触发 upstream 行为
$upstream_addr 不是“只要写了 proxy_pass 就一定有值”,它依赖实际完成 upstream 通信。注意以下几点:
- location 必须匹配并执行了
proxy_pass(比如转发到upstream backend或具体http://10.0.1.5:8000) - 静态资源、return 指令、rewrite 后未走 proxy 的路径,该变量为空字符串
- 即使启用了 keepalive,它仍记录本次请求实际连接的后端,不是连接池里的任意节点
在 server 或 location 中启用该日志
仅定义格式不够,还需显式调用:
- 在处理代理请求的
server或location块中添加:
- 路径可自定义,确保 Nginx 进程有写入权限
- 若只想对特定 path 记录(如
/api/),就把access_log放在对应 location 里 - 避免在 root location 或全局 server 下滥用,防止非代理请求日志出现大量空 upstream 字段
补充:想同时记录客户端真实 IP?
如果前端还有 CDN 或 LB,$remote_addr 会是上一跳地址。要记录用户真实 IP,需配合 realip 模块:
- 在
http块中配置可信网段:set_real_ip_from 10.0.0.0/8;(替换成你实际的代理段) - 指定头字段:
real_ip_header X-Forwarded-For; - 日志中改用
$realip_remote_addr替代$remote_addr











