Fluentd 如何解析"字段值还是 JSON 字符串"的内嵌 JSON?
日志行是文本、其中某字段值是 JSON 字符串的场景:先用正则/JSON 解析外层,再用 parser 过滤器对指定字段二次解析。本文给出配置与多层嵌套的处理建议。
典型场景:日志行是 2024-01-15 10:30:00 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>.*)$/
time_format %Y-%m-%d %H:%M:%S
</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 保留原字段——缺字段/不匹配等部分失败可保留正常路由原记录,同时送往 @ERROR;其他异常行为需核对,双路收集还可能重复;
- 多层嵌套:解析出来还是 JSON 字符串的话,可以再串一个 parser filter(实际中两层以内居多)。
常见问题(FAQ)
Q:能直接把内层字段放到指定前缀下吗? parser filter 默认平铺到顶层;可用 hash_value_field 放入对象,或 inject_key_prefix 为字段名加前缀,不必额外 transformer。
Q:内层 JSON 有转义(如 ")能解析吗? 可以,json 解析器会处理标准转义;若值本身又是一个 JSON 字符串,应按编码层级再次解析;不能通用地替换反斜杠,否则会破坏合法转义。