Nginx网关层通过log_format记录$request_time等字段,可构建轻量实时SLO监控体系;需包含$request_time、$status、$upstream_status,推荐补充$api_name、$http_x_request_id等业务维度字段,再经日志解析提取latency_seconds等指标用于P95/P99、错误率等计算。

在 Nginx 网关层通过 log_format 记录 $request_time,是构建轻量、实时、可观测的 SLO(Service Level Objective)监控体系的关键一步。它不依赖应用代码改造,直接从请求入口捕获端到端延迟,为 P95/P99 延迟、错误率、可用性等核心 SLO 指标提供原始数据支撑。
配置 log_format 包含 $request_time 和关键业务字段
$request_time 是 Nginx 处理请求的总耗时(单位:秒,精度为毫秒),从接收到第一个字节开始,到发送完最后一个字节结束。要让日志具备 SLO 分析价值,需同时记录可区分业务维度的字段:
-
必须包含:
$request_time(真实服务耗时)、$status(HTTP 状态码,用于计算错误率)、$upstream_status(上游状态,区分网关超时还是后端失败) -
推荐补充:
$http_x_request_id(链路追踪 ID)、$request_uri或自定义$api_name(通过 map 指令提取 API 路径,如/v1/users→users_read)、$http_user_agent(识别客户端类型) - 示例配置:
map $request_uri $api_name {
~^/v1/users$ users_list;
~^/v1/users/[0-9]+$ users_detail;
~^/v1/orders$ orders_create;
default unknown;
}
<p>log_format slo_log '$time_iso8601\t'
'$remote_addr\t'
'$api_name\t'
'$status\t'
'$upstream_status\t'
'$request_time\t'
'$bytes_sent\t'
'$http_x_request_id';然后在 server 或 location 块中启用:access_log /var/log/nginx/slo_access.log slo_log;
用日志解析构建 SLO 核心指标管道
原始日志需经结构化处理才能计算 SLO。推荐使用轻量方案(如 Filebeat + Logstash 或直接用 Loki + Promtail)完成解析与打标:
- 将
$request_time解析为浮点数字段(如latency_seconds),单位统一为秒 - 基于
$api_name和$status打出标签,例如:api=users_list status_code=200 - 定义“成功请求”语义:通常为
status >= 200 && status (或按业务排除 401/403);若需区分网关失败(如 502/504)和上游失败(<code>$upstream_status == 500),可额外打标error_type=gateway_timeout或error_type=upstream_error
在 Prometheus/Loki 中定义 SLO 表达式
以 Prometheus 为例(配合 Promtail 抓取日志并暴露指标):
-
延迟 SLO(如 P95 ≤ 800ms):
histogram_quantile(0.95, sum(rate(latency_seconds_bucket{job="nginx-slo", api="users_list"}[1h])) by (le)) * 1000 -
可用性 SLO(如 99.9%):
sum(rate(http_requests_total{job="nginx-slo", api="users_list", status=~"2..|3.."}[7d])) / sum(rate(http_requests_total{job="nginx-slo", api="users_list"}[7d])) > 0.999 -
错误预算消耗速率:用
rate(slo_error_seconds_total[1h])对比误差允许速率,驱动告警与复盘
注意边界与常见陷阱
$request_time 反映的是 Nginx 视角的完整请求生命周期,但不是纯后端耗时:
- 它包含网络传输时间(客户端→Nginx、Nginx→上游、Nginx→客户端),也包含 Nginx 自身处理开销(如 rewrite、limit_req)。若需精准后端耗时,应配合
$upstream_response_time并做差值分析 - 对长连接、流式响应(如 SSE、gRPC-Web),
$request_time是整个连接关闭时才写入,可能滞后;建议对这类接口单独标记并监控$upstream_header_time - 日志采样不可少:高 QPS 场景下全量记录 I/O 压力大,可用
access_log ... slo_log buffer=64k flush=1s缓冲,或加if=$loggable条件日志(如仅记录慢请求或错误请求)

















