Fluentd 如何解析"字段值还是 JSON 字符串"的内嵌 JSON?
日志行是文本、其中某字段值是 JSON 字符串的场景:先用正则/JSON 解析外层,再用 parser 过滤器对指定字段二次解析。本文给出配置与多层嵌套的处理建议。
典型场景:日志行是 2024-01-15 INFO request={"order_id":123} 这样的混合格式——先解析外层拿到 request 字段,再用 parser 过滤器对 request 字段值做一次 JSON 解析,内层对象即展开为可检索字段。
配置示例
<source>
@type tail
path /var/log/app.log
tag app.mixed
<parse>
@type regexp
expression ^(?<time>\S+ \S+) (?<level>\w+) request=(?<request>.*)$
</parse>
</source>
<filter app.mixed>
@type parser
key_name request # 对这个字段的值再解析一次
reserve_data true # 解析失败保留原字段
<parse>
@type json
</parse>
</filter>
处理后 order_id、amount 等内层字段直接进入事件顶层。
注意三点
- 正则的最后一段用
(.*)贪心匹配到行尾,JSON 里含空格也不怕; - reserve_data true 保留原字段——解析失败时原始数据不丢;
- 多层嵌套:解析出来还是 JSON 字符串的话,可以再串一个 parser filter(实际中两层以内居多)。
观测云对照
观测云 DataKit Pipeline 处理这种混合日志只需两步函数:grok() 解析外层结构,json() 展开内层 JSON 字段,且解析失败可配置保留原文。
常见问题(FAQ)
Q:能直接把内层字段放到指定前缀下吗? parser filter 默认平铺到顶层;要前缀先用 record_transformer 归拢。
Q:内层 JSON 有转义(如 ")能解析吗? 可以,json 解析器会处理标准转义;双重转义的脏数据需要先用 replace 预处理。