如何用Logstash的Grok插件从日志行解析JSON对象?
解决Logstash Grok解析日志为指定JSON结构的问题
嘿,我来帮你搞定这个Grok解析的问题!你的日志格式很清晰,只是之前的Grok模式没有精准匹配到各个部分,咱们一步步来调整:
问题分析
你的每行日志结构是:[数字时间戳] I access [合法JSON串],目标是提取时间戳到accessing字段,跳过中间的I access,把后面的JSON解析为message对象。
正确的Grok模式+配套过滤器
单纯用Grok只能捕获字符串,要把后面的JSON串转成结构化对象,还需要配合json过滤器。这里是完整的配置示例:
filter { # 第一步:用Grok拆分日志的各个部分 grok { match => { "message" => "%{NUMBER:accessing}\s+I\s+access\s+%{GREEDYDATA:message_raw}" } # 如果需要把accessing转成数字类型,添加下面这行 convert => { "accessing" => "integer" } } # 第二步:把捕获到的JSON字符串解析为结构化对象 json { source => "message_raw" # 源字段是Grok捕获的临时字符串 target => "message" # 解析后存入message字段 } # 第三步:清理不需要的临时字段 mutate { remove_field => ["message_raw"] } }
模式详解
咱们拆解一下Grok模式的每个部分:
%{NUMBER:accessing}:精准匹配开头的数字序列,存入accessing字段(NUMBER比WORD更适合匹配纯数字,WORD会包含字母/下划线,不符合你的需求)\s+I\s+access\s+:匹配中间的空格、I、access以及前后的空格,这部分内容会被直接忽略,不会存入任何字段%{GREEDYDATA:message_raw}:捕获从access之后到行尾的所有内容(也就是完整的JSON串),存入临时字段message_raw
为什么之前的模式不行?
你之前用的%{WORD:accesing} %{GREEDYDATA:message}有两个核心问题:
- 虽然
WORD能匹配纯数字,但用NUMBER是更精准的选择;更关键的是,这个模式没有跳过中间的I access,导致message字段开头会包含I access,无法直接解析为合法JSON - 没有拆分出中间需要忽略的内容,导致捕获的字段不符合预期
验证效果
用你的测试日志行:
1570519737247 I access {"date":"2019-10-08T09:28:57.247","rootTitle":"title1","rootModel":"model1","dcTitle":"[1a]"}
经过上面的过滤器处理后,最终得到的事件结构就是你想要的:
{ "accessing": 1570519737247, "message": { "date":"2019-10-08T09:28:57.247", "rootTitle":"title1", "rootModel":"model1", "dcTitle":"[1a]" } }
内容的提问来源于stack exchange,提问作者Michael
相关产品推荐
相关产品推荐

