要在 Nginx 中记录负载均衡集群的详细调度日志,需自定义 log_format 使用 $upstream_addr、$upstream_status、$upstream_response_time 等变量,并在 proxy_pass 位置启用该日志格式;配合 $upstream_http_x_backend_id 可记录后端返回的业务标识,实现精准链路追踪。

要在 Nginx 中记录负载均衡集群的详细调度日志,核心是利用 $upstream_addr、$upstream_status、$upstream_response_time 等内置变量,并自定义 log_format,同时确保后端服务能返回可识别的标识(如响应头)用于追踪请求流转路径。
配置自定义日志格式,包含关键上游信息
在 http 块中定义一个带上游调度详情的日志格式:
log_format upstream_log '$remote_addr - $remote_user [$time_local] ' '"$request" $status $body_bytes_sent ' '"$http_referer" "$http_user_agent" ' 'upstream: $upstream_addr ' 'upstream_status: $upstream_status ' 'upstream_response_time: $upstream_response_time ' 'request_id: $request_id';
说明:
-
$upstream_addr:实际转发到的后端地址(含 IP 和端口),若经过多级代理或失败重试,会以逗号分隔多个地址 -
$upstream_status:对应每个 upstream server 的 HTTP 状态码,也按逗号分隔,与$upstream_addr顺序一一对应 -
$upstream_response_time:各次转发的耗时(秒,精度毫秒),同样逗号分隔 -
$request_id可配合map或第三方模块(如nginx-http-request-id)生成唯一请求 ID,便于全链路追踪
启用 upstream 模块的健康检查与状态日志(可选但推荐)
若使用 upstream 块做负载均衡,建议开启主动健康检查,并配合 stub_status 或 nginx_upstream_check_module 查看实时调度状态:
upstream backend {
server 10.0.1.10:8080 max_fails=2 fail_timeout=10s;
server 10.0.1.11:8080 max_fails=2 fail_timeout=10s;
check interval=3 rise=2 fall=5 timeout=1;
}
注意:check 指令需编译时启用 nginx_upstream_check_module。它本身不写日志,但能让你确认哪台节点被选中、是否被标记为 down,辅助分析日志中的调度异常。
在 location 中应用自定义日志并确保变量可用
在 server 或 location 块中启用该日志格式,并确保请求确实经过 upstream 转发(即用了 proxy_pass):
location /api/ {
proxy_pass https://www.php.cn/link/65b5b8d1f89bf53a5713bc3afdd83e9e;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
<pre class="brush:php;toolbar:false;">access_log /var/log/nginx/upstream_access.log upstream_log;
error_log /var/log/nginx/upstream_error.log warn;}
关键点:
- 只有在执行了
proxy_pass到 upstream 的 location 中,$upstream_*变量才有效;静态资源或内部重定向不会填充这些值 - 如果启用了
proxy_next_upstream(如超时、502 时重试),日志中$upstream_addr会显示所有尝试过的后端,例如10.0.1.10:8080, 10.0.1.11:8080 - 建议搭配
proxy_next_upstream_tries 3和proxy_next_upstream_timeout 5s明确控制重试行为,让日志更可控
补充:记录后端返回的自定义响应头(如 X-Backend-ID)
若后端服务在响应头中返回标识(如 X-Backend-ID: node-a),可在 Nginx 中捕获并写入日志:
log_format upstream_log
...
'backend_id: $upstream_http_x_backend_id';
<h1>在 location 中透传并捕获</h1><p>location /api/ {
proxy_pass <a href="https://www.php.cn/link/65b5b8d1f89bf53a5713bc3afdd83e9e">https://www.php.cn/link/65b5b8d1f89bf53a5713bc3afdd83e9e</a>;
proxy_pass_request_headers on;</p><h1>让 $upstream_http_x_backend_id 可用</h1><pre class="brush:php;toolbar:false;">proxy_hide_header X-Backend-ID;
add_header X-Backend-ID $upstream_http_x_backend_id;}
说明:
-
$upstream_http_XXX变量自动映射后端响应头(小写连字符转下划线),前提是该响应头未被proxy_hide_header隐藏 - 若后端返回
X-Backend-ID: web-01,日志中将出现backend_id: web-01,比 IP 更具业务语义











