要记录缓存绕过请求的访问日志,需通过map指令在http块中定义变量识别Cache-Control、Pragma、URI参数及自定义头等绕过条件,合并为$is_bypassed变量,再用access_log if=$is_bypassed将其单独记录到指定日志文件。

要记录缓存绕过请求的访问日志,核心是识别哪些请求被明确跳过了缓存(例如带 Cache-Control: no-cache、Pragma: no-cache、或含特定查询参数如 ?nocache=1 的请求),然后用 access_log 的 if= 条件将其单独记录到指定日志文件中。
识别缓存绕过请求
Nginx 本身不自动标记“缓存是否被绕过”,需结合请求头或 URI 特征主动判断。常用识别方式包括:
- 检查请求头:
$http_cache_control包含no-cache或max-age=0 - 检查请求头:
$http_pragma等于no-cache - 检查 URI 参数:
$args包含nocache、bypass等关键词 - 检查自定义请求头(如运维约定的
X-Bypass-Cache: 1)
用 map 构建绕过标识变量
在 http 块中定义一个布尔型变量,用于标记是否为缓存绕过请求:
map $request_uri $bypass_flag {
default 0;
~*[?&](nocache|bypass|debug)= 1;
}
<p>map $http_cache_control $cc_bypass {
"~*no-cache|max-age=0" 1;
default 0;
}</p><p>map $http_pragma $pragma_bypass {
"no-cache" 1;
default 0;
}</p><p>map $http_x_bypass_cache $xbypass {
"1" 1;
default 0;
}</p><h1>合并所有绕过条件</h1><p>map $bypass_flag:$cc_bypass:$pragma_bypass:$xbypass $is_bypassed {
default 0;
~1 1;
}这样,只要任一条件满足,$is_bypassed 就为 1,可用于后续日志条件判断。
配置专用日志并启用 if 条件
定义一个更详细的日志格式(可选),突出显示绕过原因:
log_format bypassed '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'cache_bypass="$is_bypassed" '
'cc="$http_cache_control" '
'pragma="$http_pragma" '
'args="$args"';在 server 或 location 块中启用带条件的日志:
access_log /var/log/nginx/bypassed.log bypassed if=$is_bypassed;
该行表示:仅当 $is_bypassed 非空且非 0 时,才将请求写入 bypassed.log。其余请求照常记录在主 access 日志中,互不影响。
验证与注意事项
测试时可用以下命令触发绕过请求:
curl -H "Cache-Control: no-cache" http://your.site/curl "http://your.site/?nocache=1"
确认日志文件中出现对应条目后,再观察是否漏记或误记。注意:
-
map指令必须在http块内,不能放在server或location中 -
if=后的变量值若为0、空字符串或未定义,Nginx 就不写入该条日志 - 避免在高并发场景下对复杂正则频繁匹配;如需更高性能,可考虑用
geo或第三方模块预判


















