Nginx 通过 log_format 自定义日志格式,支持按 server/location 精准启用、注入业务字段(需脱敏)、配合轮转与 JSON 结构化采集。

通过 log_format 指令,你可以完全控制 Nginx 记录哪些字段、以什么顺序和格式输出访问日志,从而精准匹配监控、审计或数据分析等业务场景。
定义符合业务逻辑的日志格式
Nginx 默认的 combined 格式($remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent")对通用调试够用,但常缺少关键业务字段。你需要用 log_format 自定义一个新格式,例如:
log_format main '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" "$http_x_forwarded_for" $request_time $upstream_response_time $host $request_id';
其中:
– $request_id 可用于全链路追踪(需配合 map 或第三方模块生成);
– $request_time 和 $upstream_response_time 区分 Nginx 处理耗时与后端响应耗时;
– $http_x_forwarded_for 在有代理时还原真实客户端 IP;
– $host 明确请求的域名,便于多租户或多站点日志归类。
按 location 或 server 精准启用不同日志格式
不是所有接口都需要记录全部字段。比如支付回调接口需高精度耗时和完整请求体,而静态资源可简化日志降低 I/O 压力。可在不同作用域中指定 access_log:
- 在
server块中:全局启用主格式access_log /var/log/nginx/access.log main; - 在特定
location ~ ^/api/pay/callback中:覆盖为更详细格式access_log /var/log/nginx/pay_callback.log pay_detail; - 在
location ~* \.(js|css|png|jpg)$中:使用极简格式或关闭日志access_log off;
注入动态业务字段(如用户 ID、订单号)
若请求头(如 X-User-ID)、Cookie 或 URL 参数中携带业务标识,可用 $http_x_user_id、$cookie_uid、$arg_order_id 等变量直接嵌入日志:
log_format biz '$remote_addr [$time_local] $request_method $uri $args $status $body_bytes_sent $http_x_user_id $arg_order_id $request_time';
注意:
– 若字段可能为空,Nginx 默认记为短横线 -,无需额外处理;
– 敏感字段(如手机号、token)必须脱敏后再写入日志,可用 map 指令预处理,例如将手机号中间四位替换为 ****;
– 避免在日志中记录完整请求体($request_body),它不被默认支持,且易引发性能与安全问题。
配合日志轮转与结构化采集
自定义格式只是第一步,后续需确保日志可持续使用:
- 用
logrotate或 Nginx 内置的reopen信号管理日志文件大小与保留周期 - 若对接 ELK 或 Loki,建议在
log_format中使用 JSON 格式(需转义引号),例如:
log_format json '{ "time": "$time_iso8601", "remote_addr": "$remote_addr", "request": "$request", "status": $status, "request_time": $request_time }'; - JSON 格式利于 Logstash 或 Fluentd 解析,避免正则提取错误











