nginx通过log_format在http块中定义日志格式别名,用access_log启用;支持内置变量拼接、转义符和双引号,需重载生效,$upstream_*变量仅在反向代理时有效。

Nginx 使用 log_format 指令定义日志格式,核心是把内置变量按需组合成字符串,再通过 access_log 指令启用。关键不是“自定义变量”,而是灵活选用和拼接已有变量。
log_format 基本语法与作用域
log_format 必须放在 http 块中(不能在 server 或 location 内直接定义),它只是声明一种格式别名,不生效;真正写日志靠 access_log 引用该别名。
- 格式名不能含空格或特殊符号,如
main、json_log、with_upstream - 日志内容是纯字符串,变量用
$开头,如$remote_addr、$request_time - 支持普通文本、转义符(如
\t、\n)、双引号包裹的字符串(便于含空格)
常用内置变量组合示例
以下是一些高频、实用的组合方式,可直接复制调整:
-
带响应时间与上游信息的标准扩展格式:
log_format extended '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" $request_time $upstream_response_time $upstream_addr'; -
类 JSON 格式(便于日志采集):
log_format json '{"@timestamp":"$time_iso8601","remote_addr":"$remote_addr","request":"$request","status":$status,"bytes_sent":$body_bytes_sent,"request_time":$request_time,"upstream_time":"$upstream_response_time"}';
注意:JSON 中字符串值需加引号,数字不用;$upstream_response_time可能为空,输出为“-”,若需统一可配合map过滤 -
仅记录 API 接口耗时与状态(精简调试用):
log_format api '$time_iso8601 | $request_method $uri | $status | $request_time s | $upstream_response_time s';
如何让自定义格式生效
定义完 log_format 后,必须在 http、server 或 location 块中用 access_log 启用:
- 全局启用:
access_log /var/log/nginx/access.log extended; - 某虚拟主机单独启用:
server { ... access_log /var/log/nginx/app.log json; } - 关闭某个 location 的日志:
access_log off; - 多个日志文件可同时启用:
access_log /var/log/nginx/access.log main; access_log /var/log/nginx/json.log json;
注意事项与常见问题
实际使用中容易踩坑的地方:
-
$upstream_*类变量(如$upstream_response_time)只在配置了proxy_pass等反向代理指令的上下文中才有值,静态文件服务时为“-” - 变量值含空格或特殊字符(如
$http_user_agent)时,建议用双引号包裹,避免日志解析错位 - 修改
log_format后,需重载 Nginx(nginx -s reload)才生效,无需重启 - 不支持在
log_format中调用函数或做条件判断;如需逻辑处理(例如隐藏敏感 IP),应使用map指令预生成新变量











