最有效压缩 access_log 体积的方式是只记录非200和非304响应,配合 map+if 实现状态码条件过滤,并对敏感路径(如登录、支付等)按方法+路径双重识别单独记录,同时确保日志含必要上下文与缓冲优化。

直接只记录非 200 和非 304 的响应,是压缩 access_log 体积最有效的方式之一。这类请求通常占比不到 10%,却承载了绝大多数排障和安全分析价值——4xx/5xx 错误、重定向异常、未授权访问、爬虫试探、接口失败等都集中在此。关键不是“全量记录”,而是“精准捕获”。
用 map + if 实现状态码条件过滤
Nginx 原生支持 if= 参数,配合 map 指令可高效标记异常状态。不推荐用正则反复匹配 $status,应提前映射布尔值:
- 在
http块顶部定义映射:map $status $log_abnormal {<br> ~^[45] 1;<br> 304 0;<br> default 0;<br>} - 在 server 或 location 中启用条件日志:
access_log /var/log/nginx/abnormal.log main if=$log_abnormal;
- 注意:map 的 key 是字符串,
~^[45]匹配以 4 或 5 开头的状态码(如 400、404、500、502),排除 304;304 显式设为 0,其余默认不记
安全路径需单独强化记录
登录、密码重置、支付回调、管理后台等路径,即使返回 200 也属于高风险操作,必须额外记录。不能依赖状态码判断,而要用路径+方法双重识别:
将 WCAG 2 AA 无障碍标准应用于设计系统、UI 组件和网页——通过可运行的验证器进行对比度计算,采用设计 token 模式使颜色天生可访问,设定排版和焦点状态规则,并提供语义检查清单。适用于构建或审查 UI。
- 定义路径映射:
map $request_uri $log_sensitive {<br> ~^/(login|logout|reset|pay|admin|api/v1/user) 1;<br> default 0;<br>} - 叠加条件(仅当是 POST 或 PUT 且路径敏感时才记录):
map "$request_method:$log_sensitive" $log_sensitive_action {<br> "POST:1" 1;<br> "PUT:1" 1;<br> default 0;<br>} - 启用独立日志:
access_log /var/log/nginx/sensitive.log main if=$log_sensitive_action;
避免踩坑的硬性约束
条件日志看似简单,但配置不当会导致日志缺失或性能下降:
-
不要嵌套多个 if=:Nginx 不支持多条件组合写法(如
if=$log_abnormal if=$log_sensitive_action),必须合并为一个 map - map 必须在 http 级定义:放在 server 或 location 内会报错
-
关闭默认日志:确保父级(如 http 或 server)没启用无条件
access_log,否则仍会写入大量正常请求 -
慎用 $request_body:若需记录敏感请求体,必须开启
echo_read_request_body或使用 lua-resty-logger-socket,并严格脱敏,避免泄露凭证
配套优化:让异常日志真正可用
只过滤还不够,要确保每条异常日志都带上下文信息:
- 自定义格式中至少包含:
$remote_addr $http_x_forwarded_for $time_local $request $status $body_bytes_sent $upstream_status $request_time $upstream_response_time - 对 401/403 加入
$http_authorization(截取前 20 字符防泄露),便于排查鉴权问题 - 启用缓冲写入:
buffer=64k flush=5s,避免高频异常冲击 I/O - 用 logrotate 每小时切分异常日志,保留 7 天,自动 gzip 压缩










