Nginx 用 map 块对 $request_time 分级映射为日志等级变量,结合 if=变量名 控制 access_log 分流至 slow.log(buffer=64k/flush=1s)、sample.log(buffer=128k/flush=5s)或跳过;后端异步接入 Kafka/Filebeat,支持按 status、trace_id 等多维扩展。

用 Nginx 的 map 块实现请求耗时分级日志采样,核心是把 $request_time 映射成不同日志等级变量,再配合条件化 access_log 指令分流写入,从而在不改动业务、不引入额外组件的前提下完成异步化采样与存储优化。
构造耗时分级映射规则
利用正则匹配对请求耗时做区间划分,避免 Nginx 不支持数值比较的限制:
-
0.000–0.599 秒 → 抽样记录:
~^[0-9]*\.[0-5][0-9]{2}$(开头匹配,防误判如10.5被当成0.5) -
0.600–0.999 秒 → 全量记录:
~^[0-9]*\.[6-9][0-9]{2}$ -
≥1.000 秒 → 全量记录:
~^[1-9][0-9]*\.[0-9]{3}$ - 默认值设为
skip,表示不记录该请求日志
绑定多路日志输出路径
Nginx 不允许在 if 块中使用 access_log,但支持通过 if=变量名 控制某条日志指令是否生效:
- 全量日志走
/var/log/nginx/slow.log,启用buffer=64k flush=1s,兼顾实时性与 I/O 效率 - 抽样日志走
/var/log/nginx/sample.log,可设更大 buffer(如buffer=128k)和更长 flush(如flush=5s),降低磁盘刷写频次 - 跳过日志无需显式配置,或指向
/dev/null占位,避免空行干扰
配合后端异步采集提升整体吞吐
前端 Nginx 分级采样只是第一步,后端日志消费也需异步化:
- 将
slow.log接入高可靠通道(如 Kafka 或 Pulsar),供实时监控与告警系统消费 - 将
sample.log交由轻量采集器(如 Filebeat + Logstash pipeline)做结构化清洗后入库 - 若使用 ELK 架构,建议对 slow 日志开启索引生命周期管理(ILM),按小时滚动+冷热分离
扩展建议:按场景叠加更多维度
单一耗时维度不够时,可组合其他变量增强策略灵活性:
- 结合
$status:对 5xx 响应强制全量,无论耗时多低 - 结合
$http_x_trace_id:对带链路 ID 的请求固定采样,保障追踪完整性 - 新增 debug 级别:对 >5s 请求单独映射为
debug,写入/var/log/nginx/debug.log并触发告警










