Nginx通过map提取灰度标识(如Cookie、Header、IP段)生成$is_gray变量,再用access_log /var/log/nginx/gray_access.log main if=$is_gray实现条件日志,仅命中灰度的请求写入独立文件,并配合log_format增强标识字段与logrotate自动归档。

在灰度发布期间,让 Nginx 单独记录灰度流量的日志,关键不是“新建一个日志模块”,而是利用 Nginx 原生的 条件日志(conditional logging) 机制,结合灰度标识(如 Cookie、Header、IP 段等)动态决定是否写入特定日志文件。这比事后从全量日志里 grep 更高效、更可靠,也便于后续用 logrotate 归档或对接日志系统。
用 map + access_log if 实现灰度日志分流
核心是:先用 map 提取并标记灰度请求,再在 access_log 中用 if= 条件控制写入行为。
- 在
http块中定义灰度标识映射,例如识别Cookie: gray=1或X-Release-Version: v2 -
注意:
map的值只能是字符串或空,不能直接赋布尔值;推荐用"1"表示命中灰度,""(空字符串)表示不命中 - 在
server或location块中,用access_log /var/log/nginx/gray_access.log main if=$is_gray;—— 只有当$is_gray非空时才写入该文件
支持的灰度标识类型及配置示例
以下变量均可作为分流依据,按实际灰度策略选用一种或组合:
-
基于 Cookie:
map $cookie_gray $is_gray { "1" "1"; default ""; } -
基于请求头:
map $http_x_release_version $is_gray { ~^v2 "1"; default ""; }(正则匹配 v2 开头的版本) -
基于真实客户端 IP 段:
map $remote_addr $is_gray { ~^192\.168\.10\. "1"; default ""; } -
多条件合并(Header 优先,Cookie 备选):
map $http_x_gray $tmp { default $http_x_gray; } map $tmp $is_gray { "" $cookie_gray; default "1"; }
日志格式与路径注意事项
灰度日志建议复用主日志格式,但可额外添加灰度标识字段,方便排查:
- 定义带灰度标记的日志格式:
log_format gray '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" "$cookie_gray" "$http_x_release_version"'; - 确保日志目录存在且 Nginx 进程有写权限:
mkdir -p /var/log/nginx && chown nginx:nginx /var/log/nginx - 避免使用相对路径;
access_log必须指定绝对路径,否则会写入到 Nginx 安装前缀下的默认目录,易被忽略
配合 logrotate 自动归档灰度日志
独立日志文件需单独配置轮转规则,防止磁盘打满:
- 新建
/etc/logrotate.d/nginx-gray: /var/log/nginx/gray_access.log { daily rotate 30 compress missingok notifempty sharedscripts postrotate if [ -f /var/run/nginx.pid ]; then kill -USR1 `cat /var/run/nginx.pid` fi endscript }- 执行
logrotate -d /etc/logrotate.d/nginx-gray测试配置是否生效


















