Nginx可通过map指令构建条件日志变量,并在access_log中用第三个参数控制日志记录:如$loggable_final为0、空或未定义则跳过写入,实现对健康检查、爬虫等冗余流量的精准过滤。

在 Nginx 的 access_log 中,不能直接用 if 指令控制某条日志是否写入(Nginx 官方明确禁止在 log_format 或 access_log 上下文中使用 if),但可以通过「条件日志」机制实现对健康检查、爬虫、探针等冗余流量的过滤——核心是利用 access_log 指令的 可选第三个参数(log condition)。
用 map 构建日志开关变量
先定义一个变量(比如 $loggable),根据请求特征决定是否记录。推荐用 map(高效、支持正则、可在 http 块中定义):
http {
# 匹配常见健康检查路径和 User-Agent
map $request_uri $loggable {
default 1; # 默认记录
~*^/health$ 0; # /health 不记
~*^/ping$ 0; # /ping 不记
~*^/readyz$ 0; # k8s readiness 探针
~*^/livez$ 0; # k8s liveness 探针
}
<pre class="brush:php;toolbar:false;">map $http_user_agent $loggable_ua {
default 1;
~*(kube-probe|Prometheus) 0; # 屏蔽 k8s probe 和 Prometheus 抓取
~*^ELB-HealthChecker 0; # AWS ELB 健康检查
}
# 合并逻辑:任一为 0 就不记录
map $loggable $loggable_final {
0 0;
default $loggable_ua;
}}
在 access_log 中启用条件日志
在 server 或 location 块中,将变量名(不带 $)作为 access_log 的第三个参数:
将 WCAG 2 AA 无障碍标准应用于设计系统、UI 组件和网页——通过可运行的验证器进行对比度计算,采用设计 token 模式使颜色天生可访问,设定排版和焦点状态规则,并提供语义检查清单。适用于构建或审查 UI。
server {
listen 80;
server_name example.com;
<pre class="brush:php;toolbar:false;">access_log /var/log/nginx/access.log main $loggable_final;
location / {
proxy_pass http://backend;
}}
只有当 $loggable_final 的值为非空且非 0(或非空字符串如 "1")时,该请求才会被写入 access_log。值为 0、空字符串或未定义,就跳过记录。
验证与调试技巧
- 临时加一条
log_format debug '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" $loggable_final';,配合access_log ... debug查看变量实际取值 - 用
curl -H "User-Agent: kube-probe" http://localhost/health测试是否真的没进日志 - 注意:
map匹配区分大小写(~*表示忽略大小写),路径匹配的是$request_uri(含 query string),如需精确匹配路径不含参数,改用$uri
补充:避免踩坑的细节
- 不要在
location内用if判断再 set 变量——if在 location 中有陷阱,且变量无法透传到 log condition -
map必须定义在http块,不能放在 server 或 location 内 - 多个
map链式判断更清晰,比单个 map 里写几十行正则更易维护 - 如果用了
log_format自定义字段,确保这些字段本身不依赖被过滤掉的变量(比如不要在 log_format 里引用$upstream_response_time却又在 upstream 失败时跳过日志)










