iflog_formataccess_logaccess_logif=mapmapmap $status $log_if_error {
~^[45] 1; # 匹配以 4 或 5 开头的状态码(如 404、500、502)
default 0;
}
server {
access_log /var/log/nginx/error_only.log main if=$log_if_error;
...
}
$request_id$msec$connectionmap $status $log_if_200_sample {
200 $log_200_sample_flag;
default 0;
}
map $request_id $log_200_sample_flag {
~^(?:[0-9a-f]{8}-){3}[0-9a-f]{12}$ 0; # 防止空 request_id 干扰(可选)
default 0;
}
利用 $msec 小数点后三位做简单哈希(更轻量)
map $msec $sample_5_percent {
~.([0-4])$ 1; # 小数点后第一位是 0–4 → 约 50%?需调整
default 0;
}
更准确的 5%:用 $connection 取模(连接数相对均匀)
map $connection $sample_5_percent_conn {
~^[0-9]+$ $conn_mod;
}
map $connection $conn_mod {
~^([0-9]+)$ $(${1}%20==0); # Nginx 不支持算术表达式,此写法无效 → 改用第三方模块或 Lua 不现实
}
✅ 推荐做法:用 $remote_addr 哈希后取模(稳定且无需额外模块)
map $remote_addr $sample_5_percent {
default 0;
~. 1; # 占位,实际靠 split_clients 或更可靠方式
}
✔ 实际推荐(简洁可靠):
map $status $log_200_5pct {
200 $sample_flag_200;
default 0;
}
map $request_id $sample_flag_200 {
"~^[0-9a-f]{32}$" $(${1:0:1}%20==0); # ❌ Nginx map 不支持字符串截取和运算
}
map$msecmap $msec $sample_1pct {
~\.(\d{2})$ $1;
}
map $sample_1pct $log_if_200_1pct {
"00" 1;
default 0;
}
map $status $log_if_status_200 {
200 $log_if_200_1pct;
default 0;
}
access_log /var/log/nginx/200_sample.log main if=$log_if_status_200;
$msec1712345678.123~\.(\d{2})$12map"00"mapmap $status $log_500_or_sampled_200 {
500 1;
200 $sampled_200_flag;
default 0;
}
map $msec $sampled_200_flag {
~.00$ 1;
default 0;
}
access_log /var/log/nginx/combined_sample.log main if=$log_500_or_sampled_200;
log_format debug '$status $msec $request_id'; access_log /tmp/debug.log debug;curl -I http://your.site/if=maphttpserver