Nginx 通过 log_format 拼接字符串模拟 JSON 日志,推荐使用 Nginx ≥1.11.8 的 escape=json 自动转义功能构建合法 JSON;旧版本需用 map 预处理或规避危险字段,并注意引号、逗号、控制字符转义及日志轮转一致性。

Nginx 本身不直接支持原生 JSON 日志,但可以通过 log_format 拼接字符串模拟 JSON 格式,配合转义和字段控制实现结构化输出。
基础 JSON 日志格式写法
在 http 块中定义 log_format,手动拼出合法 JSON 字符串。注意:字段值需用双引号包裹,特殊字符(如引号、换行)要转义,空格和逗号位置需严谨。
- 使用
$arg_*、$http_*、$time_local等变量获取请求信息 - 用单引号包裹整个 format 字符串,内部双引号不冲突
- 对可能含双引号或换行的字段(如
$request、$http_user_agent),建议用map预处理或 Nginx 1.11.8+ 的escape=json修饰符
推荐写法(Nginx ≥ 1.11.8)
利用 escape=json 自动转义,大幅降低出错风险:
log_format json_log escape=json '{'
'"time_local":"$time_local",'
'"remote_addr":"$remote_addr",'
'"request":"$request",'
'"status":$status,'
'"body_bytes_sent":$body_bytes_sent,'
'"http_referer":"$http_referer",'
'"http_user_agent":"$http_user_agent",'
'"request_time":$request_time,'
'"upstream_response_time":"$upstream_response_time"'
'}';
然后在 server 或 location 中启用:access_log /var/log/nginx/access.json json_log;
兼容旧版本 Nginx 的简化方案
若版本低于 1.11.8,可规避高危字段(如不记录完整 $request 或 $http_user_agent),或用 map 手动清理:
- 定义 map 清洗 user_agent(去掉双引号和换行):
map $http_user_agent $ua_clean {<br> default $http_user_agent;<br> ~"[" "$1"; # 示例,实际需正则替换 - 只保留确定安全的字段,例如:
"method":"$request_method","uri":"$uri","args":"$args" - 用
concat模块(需编译)或 Lua(via ngx_lua)做更灵活的 JSON 构建
验证与注意事项
生成日志后务必验证 JSON 合法性,常见问题包括末尾多逗号、引号不闭合、未转义控制字符。
- 用
jq -R 'fromjson' /var/log/nginx/access.json | head -5快速校验 - 避免在 JSON 中嵌入未过滤的客户端输入(如
$args),防止注入无效字符 - 日志轮转时确保新文件仍使用相同 format,否则解析工具可能失败
- 高并发下 JSON 日志体积略大,磁盘和 I/O 压力略高于默认格式


















