nginx 默认 access_log 无法记录上游响应头,需用 $upstreamhttp* 变量显式捕获,如 $upstream_http_x_response_time;定义含该变量的 log_format 并在 server/location 中启用 access_log;注意响应头可能被过滤、隐藏或属 hop-by-hop 类型而不可用。

Nginx 默认的 access_log 无法直接记录后端(如 upstream)返回的响应头,因为这些头在 Nginx 作为反向代理时属于“上游响应”,需通过 $upstream_http_* 变量显式捕获。
使用 $upstream_http_* 变量记录特定响应头
若后端返回了例如 X-Response-Time、X-App-Version 或 Content-Type 等响应头,可在 log_format 中用对应变量引用:
-
$upstream_http_x_response_time→ 记录后端返回的X-Response-Time头(注意下划线替代连字符) -
$upstream_http_content_type→ 记录Content-Type -
$upstream_http_x_app_version→ 记录X-App-Version
变量值为空时显示短横线 -,不报错。大小写不敏感,但建议按标准命名转为小写下划线格式(如 X-Rate-Limit → $upstream_http_x_rate_limit)。
定义并启用自定义日志格式
在 http 块中定义 log_format,包含所需 upstream 响应头变量:
使用tbot机器ID身份文件配合tsh CLI,通过Teleport访问控制SSH登录托管主机或执行远程命令。
log_format upstream_log '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'rt=$upstream_response_time uct="$upstream_cache_status" '
'xrt="$upstream_http_x_response_time" '
'ver="$upstream_http_x_app_version"';
然后在 server 或 location 块中启用:
access_log /var/log/nginx/access_upstream.log upstream_log;
注意响应头是否被 Nginx 过滤或重写
Nginx 默认会过滤部分敏感响应头(如 Set-Cookie、Server),且不会透传以 Connection、Keep-Alive 等为代表的 hop-by-hop 头。若发现 $upstream_http_* 为空,检查:
- 后端是否确实返回了该头(可用 curl -I 验证)
- 是否被
proxy_hide_header显式隐藏(如proxy_hide_header X-App-Version) - 是否属于 hop-by-hop 头(这类头无法被 Nginx 缓存或记录)
调试技巧:临时打印到 error_log
开发阶段可快速验证变量是否取到值:
log_subrequest on; error_log /var/log/nginx/debug.log notice; # 在 location 中加: add_header X-Upstream-Ver "$upstream_http_x_app_version" always;
再配合 nginx -t && nginx -s reload,查看 debug.log 或用 tail -f 观察实际值。










