Logstash 中如何解析 JSON 格式的日志?
Logstash 处理 JSON 日志两种方式:input 的 codec => json 整个事件按 JSON 解析,或 filter 的 json 插件解析 message 字段。本文给出配置示例及常见问题。
JSON 日志两种接法:如果每行日志整体就是一个 JSON 对象,在 input 中设 codec => json { target => "[app]" } 一步到位;如果 JSON 嵌在 message 字段里(混合格式),用 filter 的 json 插件解析。
方式一:codec => json(整行都是 JSON)
input {
file {
type => "json"
path => "/var/log/mylogs.log"
start_position => "beginning"
codec => json { target => "[app]" }
}
}
假设日志内容:
{"status": 200, "ip": "127.0.0.1", "level": 30, "msg": "Connected to database", "timestamp": 1696150204}
解析后 JSON 字段放在 [app] 命名空间,避免覆盖 @timestamp 等元数据。此 file 示例要求一行一个完整JSON对象;start_position 仅影响首次发现,已有 sincedb 会续读。
方式二:filter json 插件(JSON 在字段里)
filter {
json {
source => "message"
target => "[app]"
}
}
解析失败会给事件打上 _jsonparsefailure 标签,可按标签分流处理。
以下是使用 plain 输入、再经 json filter 的替代路径,不要与前面的 json codec 重复解析。UNIX 读取秒,毫秒时间戳使用 UNIX_MS。
解析后常用操作
filter {
json { source => "message" target => "[app]" }
# 用 JSON 里的时间字段作为事件时间
date {
match => ["[app][timestamp]", "UNIX"]
}
# 字段类型转换
mutate {
convert => { "[app][status]" => "integer" }
}
}
常见问题(FAQ)
Q:日志是"前缀文本 + JSON"的混合格式?
A:先用 grok 把 JSON 部分提取到单独字段,再用 json 插件解析该字段。
Q:JSON 里有嵌套对象会怎么处理?
A:嵌套结构原样保留,Logstash 里用 [parent][child] 语法访问子字段。
Q:codec json 解析失败会丢数据吗?
A:json codec 通常回退为原始 message 并标记 _jsonparsefailure,但后续过滤器、输出失败和存储拒绝仍可能丢弃;需验证隔离或错误处理路径,不能保证端到端保留。