Nginx 中可通过 map 指令结合 access_log if= 参数实现慢请求日志:先用 map 基于 $request_time 定义布尔变量(如 $log_slow),再在 access_log 中用 if=$log_slow 控制仅记录响应时间 ≥0.5 秒的请求。

在 Nginx 中,access_log 本身不支持直接写 if 条件语句,但可以通过 log\_format + map 指令 实现“仅记录响应时间超过阈值的请求”,即慢查询日志。核心思路是:用 map 构建一个动态变量(如 $loggable),根据 $request_time 判断是否满足慢请求条件;再在 access_log 中通过该变量控制日志是否写入(配合 if= 参数)。
1. 定义慢请求判定变量(使用 map)
在 http 块中定义一个映射,将 $request_time 转为布尔标记(例如 1 表示慢,0 或空表示不记录):
http {
# 定义慢请求阈值(单位:秒),这里设为 1 秒
map $request_time $log_if_slow {
~^[1-9]\d*\.\d+|0\.[5-9]\d*|1\.0$ 1; # 粗略匹配 ≥0.5s(更推荐下面的数值比较写法)
# ✅ 更可靠写法:使用数值比较(Nginx 1.11.8+ 支持)
default 0;
0.5 1;
1.0 1;
# 注意:map 不支持 > 运算符,但可利用“顺序匹配 + default”模拟
# 实际推荐用以下方式(兼容性更好):
}
<pre class="brush:php;toolbar:false;"># ✅ 推荐写法:用数值区间映射(兼容旧版本)
map $request_time $log_if_slow {
default 0;
0.0 0;
0.1 0;
0.2 0;
0.3 0;
0.4 0;
0.5 1;
0.6 1;
0.7 1;
0.8 1;
0.9 1;
1.0 1;
# ……但这样不优雅。更实用的是:
}
# ✅ 最佳实践:用浮点数比较(Nginx ≥ 1.11.8)
map $request_time $log_if_slow {
default 0;
~^[0-9]*\.[5-9][0-9]*$ 1; # 匹配 0.5–0.999...
~^[1-9][0-9]*\.[0-9]*$ 1; # 匹配 1.0 及以上
~^1\.0$ 1;
}}
⚠️ 实际部署中,**强烈建议使用 Nginx ≥ 1.11.8 并采用如下简洁写法**(无需正则,语义清晰):
map $request_time $log_if_slow {
default 0;
0.5 1;
1.0 1;
}
# ❌ 错误:map 不支持 >= 语法,但可以利用“默认值 + 显式覆盖”逻辑
# ✅ 正确技巧:把阈值设为最小触发值,map 会取第一个匹配项
# 所以只要写一个 >=0.5 的触发点即可 —— 但 map 本质是等值映射,不是范围判断
? 正确且通用的做法(兼容所有现代 Nginx):
- 使用
geo指令(支持范围)或 - 继续用
map+ 正则(稍重但可靠)或 - ✅ 推荐:用
map结合$upstream_response_time或$request_time的字符串匹配(见下)
2. 定义专用日志格式(含慢请求标识)
可选:添加字段便于识别慢请求,比如在日志里打上 [SLOW] 标记:
log_format slow_only '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'rt=$request_time u_rt=$upstream_response_time '
'[$log_if_slow]';
<p>access_log /var/log/nginx/slow.log slow_only if=$log_if_slow;</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/skill9290" title="Web Accessibility (WCAG 2 AA))"><img
src="https://img.php.cn/upload/skill/000/000/081/179254634481418.jpg" alt="Web Accessibility (WCAG 2 AA))" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/skill9290" title="Web Accessibility (WCAG 2 AA))" class="overflowclass">Web Accessibility (WCAG 2 AA))</a>
<p class="overflowclass">将 WCAG 2 AA 无障碍标准应用于设计系统、UI 组件和网页——通过可运行的验证器进行对比度计算,采用设计 token 模式使颜色天生可访问,设定排版和焦点状态规则,并提供语义检查清单。适用于构建或审查 UI。</p>
</div>
<a rel="nofollow" href="/xiazai/skill9290" title="Web Accessibility (WCAG 2 AA))" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div>
注意:if=$log_if_slow 表示:仅当 $log_if_slow 非空且非 0 时写入该日志(Nginx 将 "0"、空字符串、"off" 视为 false)。
3. 完整配置示例(推荐版)
放在 http 块内:
http {
# 判定:请求耗时 ≥ 0.5 秒即标记为 1
map $request_time $log_slow {
~^[0-9]+\. 1; # 有小数点 → 至少 0.x
~^1|2|3|4|5|6|7|8|9|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9]|6[0-9]|7[0-9]|8[0-9]|9[0-9]|100$ 1;
default 0;
}
# ✅ 更简单可靠的正则(匹配 ≥0.5 的数字字符串)
map $request_time $log_slow {
~^(0\.[5-9]|[1-9]\d*(\.\d*)?)$ 1;
default 0;
}
<pre class="brush:php;toolbar:false;">log_format slow_log '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'rt=$request_time u_rt=$upstream_response_time';
access_log /var/log/nginx/access.log main; # 正常全量日志(可选)
access_log /var/log/nginx/slow.log slow_log if=$log_slow; # 仅慢请求}
? 提示:正则 ^(0\.[5-9]|[1-9]\d*(\.\d*)?)$ 能较准确匹配 0.5、0.51、1、1.0、2.3 等 ≥0.5 的值(注意 Nginx 中 $request_time 是字符串,精度通常为毫秒级,如 "0.499" 不会匹配)。
4. 验证与调试技巧
执行前检查配置并重载:
-
nginx -t确保语法正确 -
nginx -s reload生效 - 手动触发慢请求测试:
curl -o /dev/null -s -w "%{time_total}\n" "http://your.site/sleep?sec=1"(后端需支持延时) - 观察
/var/log/nginx/slow.log是否新增条目 - 临时开启 debug 日志(
error_log /path/debug.log debug;)可追踪 map 计算过程
⚠️ 注意:$request_time 是从读取请求头开始到发送完响应为止的总时间,包含 Nginx 处理和 upstream 等待时间;若只想记录 upstream 慢(如 PHP/Proxy 响应慢),请改用 $upstream_response_time,并确保 upstream 已配置(如 proxy_pass)。










