nginx 1.11.8+ 支持 escape=json 的 log_format,可直接输出标准 json 日志,需在 http 块定义格式、server 中用 access_log 启用,字段引号规范、数值不加引号、时间用 $time_iso8601,路径须绝对且有写权限,采集端需按 json lines 解析。

让 Nginx 日志直接输出标准 JSON 格式,是对接大数据平台(如 ELK、Loki、ClickHouse)最高效的方式——省去 Logstash 的 grok 解析开销,字段天然可索引、可聚合。
在 http 块中定义 escape=json 的 log_format
这是最关键的一步。Nginx 1.11.8+ 支持 escape=json 参数,自动转义双引号、换行符、控制字符,避免 JSON 结构损坏:
- 所有字符串字段(如
"$remote_addr"、"$http_user_agent")必须用双引号包裹 - 数值字段(如
$status、$request_time、$body_bytes_sent)不加引号,确保 Elasticsearch 或 ClickHouse 自动识别为数字类型 - 时间统一用
$time_iso8601,方便日志系统解析为@timestamp - 字段名建议加前缀(如
http_user_agent而非user_agent),避免与目标平台内置字段冲突
启用并绑定到具体 server 或 location
仅定义格式不会生效,必须在作用域中显式调用 access_log:
- 写法必须是
access_log /path/to/access.json json_format_name;,缺格式名会回退到默认combined - 路径需为绝对路径,且 Nginx 进程有写权限(如
/var/log/nginx/access.json) - 若使用多个虚拟主机,确保
log_format在http块顶层唯一定义,不要在各server中重复声明
适配不同采集端的注意事项
JSON 日志输出后,采集工具配置要匹配“每行一个 JSON 对象”(JSON Lines)格式:
- Filebeat:启用
json.enabled: true+json.keys_under_root: true,并设json.add_error_key: true便于排查解析失败 - Logstash:用
json过滤器即可,无需 grok;推荐加remove_field => ["message"]避免冗余字段 - Loki:配合 Promtail 的
docker或file类型 input,启用json解析器,自动提取标签
验证与排错要点
配置完成后,务必验证输出是否真正合法:
- 重启 Nginx,发一次请求(如
curl -I localhost) - 用
tail -1 /var/log/nginx/access.json | jq .检查是否单行、无报错 - 常见错误:字段漏引号、数值加了引号、
escape=json拼错、Nginx 版本低于 1.11.8 - 高危字段(如
$http_user_agent)若仍担心风险,可用map预清洗非法字符,再引用清洗后变量











