nginx json日志需在http块定义log_format并启用escape=json,access_log须显式引用格式名;路径须绝对且权限正确,避免重复定义与非法变量。

直接在 server 或 location 块中用 access_log 指向你定义好的 JSON 格式即可,但前提是 log_format 已正确定义在 http 块内,并启用 escape=json 参数。否则日志要么不是合法 JSON,要么根本无法加载配置。
必须把 log_format 放在 http 块里
log_format 是全局指令,只能出现在 http 块中。如果误写进 server 或 location,Nginx 启动会报错:unknown directive "log_format"。常见错误还包括多个配置文件重复定义同名格式,比如两次写 log_format json_log ...,会导致 duplicate log_format "json_log"。
- 命名建议用语义化名称,例如
log_format json_access escape=json '{...}'; - 所有字符串字段值必须用双引号包裹,数值型字段(如
$status、$request_time)不加引号,保持原始类型 - 避免使用
$request这类可能含空格、换行或引号的变量;推荐拆成$request_method、$uri、$args等更可控字段
access_log 必须显式引用格式名
只写 access_log /var/log/nginx/access.log; 不会生效——Nginx 默认只认内置的 combined 和 main 格式。要启用自定义 JSON 格式,必须明确写出格式名:
-
access_log /var/log/nginx/access.json json_access;✅ -
access_log /var/log/nginx/access.json;❌(实际仍输出 plain text) - 支持同时写多条
access_log,比如同步输出到文件和 syslog:access_log /var/log/nginx/app.json json_access; access_log syslog:server=127.0.0.1:514 json_access;
escape=json 是关键安全机制
Nginx 1.11.8+ 提供的 escape=json 参数会自动对变量中的双引号、反斜杠、控制字符(如换行符)做 JSON 转义,极大降低日志损坏风险。没有它,$http_user_agent 或 $http_referer 中的非法字符极易导致整行 JSON 解析失败。
- 不要手动拼接转义逻辑,依赖
escape=json即可 - 高风险字段(如
$http_user_agent)若仍需额外清洗,可用map指令预处理,再在log_format中引用清洗后变量 -
$upstream_response_time可能为空或多值,建议保留为字符串形式(加引号),后续由 Logstash 或 Elasticsearch Ingest Pipeline 拆分
路径与权限不能忽略
日志路径必须是绝对路径,且 Nginx 工作进程(通常是 nginx 用户)要有写入权限:
- 提前创建目录并授权:
mkdir -p /var/log/nginx && chown nginx:nginx /var/log/nginx - 确保
logrotate配置兼容 JSON Lines:每行一个 JSON 对象,禁止合并多行或添加空行 - 验证日志是否生成且格式合法:用
tail -n 1 /var/log/nginx/access.json | jq .测试解析是否成功











