nginx通过$log_format暴露$request_time等耗时变量,配合日志解析工具(如awk、logstash、prometheus)实现毫秒级响应时间分段统计(如

在 Nginx 中记录响应时间的分段统计,核心是利用 $request_time 和 $upstream_response_time 变量,配合自定义日志格式与外部工具(如 Logstash、Prometheus 或脚本)做后处理分析。Nginx 本身不直接支持“内置分段统计”(比如按 100ms/500ms/1s 分桶),但可通过日志格式化 + 日志解析实现高效分段归类。
配置日志格式,暴露关键耗时字段
在 http 块中定义一个包含响应时间细节的日志格式:
log_format timing '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'$request_time $upstream_response_time $upstream_connect_time $upstream_header_time';
说明:
-
$request_time:从接收客户端请求头开始,到将最后一字节发送给客户端为止的总时间(单位:秒,精度为毫秒) -
$upstream_response_time:Nginx 与上游服务(如 FastCGI、proxy)交互的响应耗时,可能含多个值(如负载均衡多台后端),用逗号分隔 -
$upstream_connect_time和$upstream_header_time:可进一步拆解网络连接与首包等待时间
按毫秒级精度写入日志,便于后续分段
Nginx 默认输出 $request_time 最多三位小数(如 0.123),即毫秒级。若需更精确(微秒),需打补丁或改用 OpenResty 的 ngx.now(true),但对绝大多数分段统计(如 500ms)毫秒已足够。
确保 access log 使用该格式:
access_log /var/log/nginx/timing.log timing;
用脚本或日志分析工具做实时分段统计
原始日志中每行含一个 $request_time 值(如 0.456),可在收集后按阈值归类。例如用 awk 实时统计每分钟各区间请求数:
awk '{t = $10 * 1000; # 转为毫秒
if (t <p>生产环境推荐方式:</p>
- 用 Filebeat + Logstash / Fluentd 提取
$request_time字段,转成数字类型,再用聚合插件按 range 分桶 - 接入 Prometheus:通过
nginx-vts-exporter或自定义 exporter 解析 access log,暴露nginx_request_duration_seconds_bucket指标 - 使用 Grafana + Loki:用 LogQL 的
range运算符(如| json | __error__ == "" | duration )做动态分段查询
补充:区分不同 upstream 的响应时间分布
如果后端有多个服务(如 API / 静态资源 / 认证服务),建议在 location 中为不同 upstream 单独配置日志格式,或用 $upstream_http_x_backend_name 等自定义 header 标记来源,再结合 $upstream_response_time 做分组统计。例如:
location /api/ {
proxy_pass https://backend-api;
proxy_set_header X-Backend-Name "api";
access_log /var/log/nginx/api_timing.log timing;
}
这样可分别统计各业务模块的响应时间分布,定位慢接口更精准。











