Nginx 用 map 指令实现原生日志降载,通过毫秒/客户端哈希采样、分层保底(5xx全量、健康检查过滤)、按天分割日志及规避配置陷阱(如 log_format 位置、单 access_log 生效)提升效率与可观测性。
用
指令控制
是否写入,是 Nginx 原生、零依赖的日志降载方案,核心在于“请求进入时就决定是否记”,避免无效日志占用 I/O 和磁盘空间。
按采样比例动态开关日志
适用于高 QPS 场景(如万级请求/秒),通过构造可预测的哈希逻辑实现近似均匀采样:
用
小数点后三位取模:如
提取毫秒值,再用
实现约 5% 采样
用
做 CRC32 哈希后取模:保证同一客户端请求始终被采或不被采,便于问题复现
注意:
后必须是整数 0 或 1;
默认未启用,直接使用会导致全量落入 default 分支
分层保底:关键路径全量,低价值流量过滤
兼顾分析效率与故障可见性,避免“一刀切”采样导致问题漏报:
PHP数据库链接类(PDO+Access)
PHP数据库链接类(PDO+Access)
下载
健康检查接口(如
)、爬虫 UA、内网探测 IP 段可统一设为
,完全不记
错误响应(
匹配
)强制设为
,确保 5xx 全量记录
高频业务路径(如
)设为全量;低频慢接口(如
)单独配置 1% 采样
结合时间变量实现按天日志分割
缓解单文件膨胀和清理难题,避免因直接删除日志导致句柄残留、空间不释放:
用
提取日期部分,例如
在
路径中引用该变量:
配合
或定时脚本清理过期文件,只保留最近 30 天
避免常见配置陷阱
不少性能问题源于细节疏忽,而非逻辑错误:
必须在所有
块之后定义,否则变量无法被识别
多个
指令共存时,只有最后一个生效;不能靠重复声明实现“多级日志”
若需按响应耗时分级(如 slow/fast),应将等级写入日志字段(如
),再由 filebeat 等工具后端过滤,而非在 Nginx 内部尝试多文件写入
确保日志目录有写权限,且磁盘不处于只读状态——否则
控制再精准也无输出
mapaccess_log$msec~^\d+\.(\d{3})$ $1~^[0-4][0-9]$ 1$remote_addrif=$request_id/healthz0$status5[0-9]{2}1/api/v1/user/api/v1/reportmap $time_iso8601 $log_date~^(\d{4}-\d{2}-\d{2}) $1access_logaccess_log /var/log/nginx/access-$log_date.log mainlogrotatelog_formatmapaccess_log"level":"slow"map