关键是从 nginx 侧直接输出结构化 json 日志,通过 log_format 拼接合法 json 字符串并启用 access_log json 格式;filebeat 需配置 json.enabled: true、keys_under_root: true 及 timestamp_key 等参数以正确解析字段。

要让 Nginx 日志能被 Filebeat 高效、准确地采集并送入 Elasticsearch 或 Logstash,关键不是“先输出再格式化”,而是**从 Nginx 侧直接输出结构化的 JSON 日志**。Filebeat 本身不解析非结构化文本(如默认的 `combined` 日志),它依赖日志内容本身具备字段边界——而 JSON 天然满足这点。
配置 Nginx 输出原生 JSON 日志
Nginx 不支持直接写 JSON,但可通过 log_format 拼接合法 JSON 字符串。需注意转义、空格、引号和字段完整性:
- 使用双引号包裹键名和字符串值,用
\转义内部双引号(如$request可能含引号) - 对可能为空的变量(如
$http_x_forwarded_for)用"-"或null占位,保持 JSON 合法性 - 时间建议统一用
$time_iso8601,避免时区歧义
示例配置(放入 http 块):
log_format json '{"@timestamp":"$time_iso8601",'
'"host":"$server_addr",'
'"clientip":"$remote_addr",'
'"method":"$request_method",'
'"url":"$uri",'
'"status":$status,'
'"bytes":$body_bytes_sent,'
'"referer":"$http_referer",'
'"useragent":"$http_user_agent",'
'"request_time":$request_time,'
'"upstream_time":"$upstream_response_time"}';然后在 server 或 location 中启用:access_log /var/log/nginx/access.json json;
确保 Filebeat 正确识别 JSON 行并解析字段
Filebeat 默认把每行当纯文本。要让它把整行当作 JSON 解析,需启用 json.keys_under_root: true,并关闭默认的行首检测(避免误判为普通日志):
- 在 Filebeat 的
filebeat.inputs中指定日志路径,并设置json.enabled: true - 添加
json.keys_under_root: true将 JSON 字段提升到根层级,便于 Kibana 过滤 - 推荐加
json.add_error_key: true,便于排查解析失败的日志行
示例 input 配置片段:
- type: filestream
enabled: true
paths:
- /var/log/nginx/access.json
json.enabled: true
json.keys_under_root: true
json.add_error_key: true
json.message_key: "@timestamp"
fields:
service: nginx
log_type: access处理常见问题:空字段、嵌套与时间解析
原始 JSON 日志虽结构清晰,但仍有细节影响下游使用:
-
空字段或非法值:Nginx 变量如
$upstream_response_time在无 upstream 时为空字符串,JSON 中应写成"upstream_time":"-"或预处理为"null";Filebeat 无法自动将字符串"-"转为 null,建议在 Logstash 或 Ingest Pipeline 中清洗 -
嵌套字段需求:若需将
clientip和useragent归入client对象,Nginx 侧无法直接生成嵌套 JSON,应在 Filebeat 的processors中用rename+dissect或交由 Logstash 处理 -
@timestamp 识别:Filebeat 默认用读取时间作为
@timestamp。要使用日志中的@timestamp字段,需在 input 中设json.timestamp_key: "@timestamp"并指定格式:json.timestamp_format: "2006-01-02T15:04:05-07:00"
验证与调试建议
上线前务必验证 JSON 合法性与字段可用性:
- 用
tail -n 1 /var/log/nginx/access.json | jq .检查单行是否为有效 JSON - 在 Filebeat 启动时加
-e -d "publish"查看实际发送到 ES 的文档结构 - Kibana 中检查索引中字段类型:数字字段(如
status、bytes)应为long或float,而非text;若为 text,说明 Filebeat 未成功解析或 ES mapping 已固化,需清理测试索引重试











