Nginx可通过map+多access_log指令+if=条件实现按域名、请求特征、状态码等维度动态分流日志;需配合定制log_format、绝对路径权限配置、logrotate轮转及敏感字段脱敏。

要让 Nginx 同时输出多份日志以满足不同业务部门的查看需求,关键不是“复制日志文件”,而是按部门关注的维度(如域名、路径、状态码、来源 IP、Referer 等)做动态分流,再配合格式定制和独立路径输出。Nginx 原生不支持“一份请求写入多个文件”,但可通过 map + 多条 access_log 指令 + 条件判断(if=)实现精准分发。
按业务域名分离日志
这是最常用也最清晰的方式,适合市场、客服、技术等按业务线划分的团队:
- 在
http块中为每个业务域名定义独立日志格式(可差异化字段),例如只给市场部保留$http_referer和$request_uri - 在对应
server块中直接配置专属日志路径:access_log /var/log/nginx/marketing-access.log marketing_format; - 若同一 server 下需同时服务多个子业务(如
shop.example.com和api.example.com),可用server_name正则或map $host分类后绑定日志
按请求特征动态分流(如部门来源、接口类型)
适用于需要交叉分析的场景,比如运维关注错误、风控关注异常 UA、数据组关注特定参数:
- 用
map提前标记请求属性,例如:map $http_user_agent $log_risk { ~*curl|httpie "risk"; default ""; }map $args $log_data { ~*utm_source= "data"; default ""; } - 在
server或location中启用条件日志:access_log /var/log/nginx/risk-requests.log main if=$log_risk;access_log /var/log/nginx/data-traffic.log data_format if=$log_data; - 注意:
if=只在server和location级别有效,且变量值必须为非空字符串才记录
按响应状态码分级归档(适配质量与 SRE 团队)
故障排查、SLA 统计、告警联动都依赖状态码分类,建议为 4xx/5xx 单独建日志:
- 在
http块中定义映射:map $status $log_4xx { ~^4 "" ; default ""; }map $status $log_5xx { ~^5 "" ; default ""; } - 添加两条带条件的
access_log:access_log /var/log/nginx/4xx-errors.log error_format if=$log_4xx;access_log /var/log/nginx/5xx-errors.log error_format if=$log_5xx; - 可进一步结合
log_format加入$upstream_addr和$upstream_response_time,方便定位是上游超时还是自身逻辑异常
格式与权限管理要点
多日志输出后,可读性、安全性和维护成本同样重要:
- 所有日志路径使用绝对路径,并提前创建目录、赋权(如
chown nginx:adm /var/log/nginx/dept/),避免启动失败 - 为不同部门的日志定义专属
log_format,例如客服日志含$remote_addr $http_x_forwarded_for,法务日志加$time_iso8601精确到毫秒 - 搭配
logrotate配置独立轮转策略(如客服日志每日切分、SRE 日志按大小压缩),并在postrotate中调用nginx -s reopen重载句柄 - 敏感字段(如手机号、token)不可写入日志;必要时用
map过滤或正则脱敏(如map $args $sanitized_args { ~*(token=)[^&]* "$1***"; default $args; })











