要让 nginx ingress controller 日志透传 pod 内部真实响应时间,需后端服务主动注入 x-response-time 响应头,并在 ingress-nginx configmap 中配置 log-format-upstream 包含 $upstream_http_x_response_time 字段,该字段将提取并记录 pod 级业务耗时。

要让 Nginx Ingress Controller 的访问日志中透传 Pod 内部真实的响应时间(即后端容器实际处理耗时),关键不是改 Nginx 自身的 $request_time,而是通过日志格式配置 + 后端服务配合,把 Pod 级响应时间注入到 HTTP 响应头,再由 Ingress 提取并写入日志。
理解两个不同层级的响应时间
Nginx Ingress 中常见的两个时间字段容易混淆:
-
$upstream_response_time:Nginx 到后端 Pod 的网络往返+Pod 应用层处理总耗时(单位秒,逗号分隔多个 upstream) -
$upstream_http_x_response_time:从后端 Pod 响应头中提取的自定义字段(如X-Response-Time),这才是 Pod 内部纯业务逻辑耗时(不含网络延迟)
前者受调度、网络、kube-proxy 等影响,后者才是你真正想监控的“应用内部性能”。必须靠后端服务主动输出,Ingress 才能捕获。
后端服务需主动注入 X-Response-Time 响应头
在你的 Pod 应用代码或中间件中,需在请求处理完毕后、返回前,将本次处理耗时写入响应头。例如:
- Node.js Express:
res.set('X-Response-Time', `${Date.now() - start}ms`) - Go Gin:
c.Header("X-Response-Time", fmt.Sprintf("%dms", time.Since(start).Milliseconds())) - Java Spring Boot:使用 Filter 或 Interceptor 设置响应头
注意:该头必须是显式设置的,不能依赖框架默认行为;且建议统一单位(毫秒或秒),便于日志解析。
修改 Ingress-Nginx ConfigMap 配置日志格式
编辑 ingress-nginx-controller 所在命名空间下的 configmap/ingress-nginx-controller,更新 log-format-upstream 字段:
log-format-upstream: '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" $request_length $request_time [$proxy_upstream_name] $upstream_addr $upstream_response_length $upstream_response_time $upstream_status $upstream_http_x_response_time $req_id'
其中 $upstream_http_x_response_time 会自动提取后端返回的 X-Response-Time 值;若后端未返回,则该项为空字符串。
修改后触发滚动更新(如删掉旧 pod),新日志即可包含该字段。
验证与采集建议
确认生效后,可通过 kubectl logs -n ingress-nginx deploy/ingress-nginx-controller 查看实时日志,检查是否出现类似:
最后一段 128ms 就是 Pod 内部真实耗时。后续可对接日志服务(如阿里云 SLS、Loki)做字段提取、聚合分析和 P95/P99 延迟告警。











