升级EKS集群后Fluentbit日志新增time stdout F破坏JSON格式
EKS升级后Fluentbit收集的日志JSON格式异常
现象
升级前日志是正常的嵌套JSON结构:
{ "log": { "level": "INFO", "timestamp": "2024-06-28T03:58:22.248Z" } }
升级后日志格式被破坏,开头多了时间 stdout F前缀,原本的JSON内容变成转义字符串:
{ "log": "2024-06-28T03:58:22.24854688Z stdout F {\"timestamp\":\"2024-06-28T03:58:22.248Z\",\"level\":\"INFO\"}" }
当前环境
- Kubernetes 1.29(基于containerd)
- Fluentbit 1.9.0
当前Fluentbit配置
解析器配置
[PARSER] Name docker Format json Time_Key timestamp Time_Keep Off Time_Format %Y-%m-%dT%H:%M:%S.%LZ
输入配置
[INPUT] Name tail Tag application.* Exclude_Path /var/log/containers/cloudwatch-agent*, /var/log/containers/fluent-bit*, /var/log/containers/aws-node*, /var/log/containers/kube-proxy* Path /var/log/containers/*.log Docker_Mode On Docker_Mode_Flush 5 Docker_Mode_Parser container_firstline Parser docker DB /var/fluent-bit/state/flb_container.db Mem_Buf_Limit 50MB Skip_Long_Lines On Refresh_Interval 10 Rotate_Wait 30 storage.type filesystem
问题根源
升级到基于containerd的K8s 1.29后,containerd的日志输出格式和旧版docker不一样,每条日志前会自动加上时间 流类型(stdout/stderr) 日志类型(F/P)的前缀。而你的Fluentbit还在用docker模式和docker解析器,没法识别这种新格式,直接把整条带前缀的内容当成log字段的字符串值,导致JSON结构被破坏。
解决办法
调整Fluentbit的解析器和输入配置,适配containerd的日志格式:
1. 新增containerd日志解析器
在解析器配置里加一段:
[PARSER] Name containerd Format regex Regex ^(?<time>[^ ]+) (?<stream>stdout|stderr) (?<logtag>[FP]) (?<log>.*)$ Time_Key time Time_Format %Y-%m-%dT%H:%M:%S.%LZ Time_Keep On
这个正则会拆分containerd的日志前缀,把时间、流类型、日志标签和实际日志内容分别提取出来。
2. 修改输入配置
把原来的INPUT配置改成下面这样:
[INPUT] Name tail Tag application.* Exclude_Path /var/log/containers/cloudwatch-agent*, /var/log/containers/fluent-bit*, /var/log/containers/aws-node*, /var/log/containers/kube-proxy* Path /var/log/containers/*.log Docker_Mode Off Parser containerd Parser_Second docker DB /var/fluent-bit/state/flb_container.db Mem_Buf_Limit 50MB Skip_Long_Lines On Refresh_Interval 10 Rotate_Wait 30 storage.type filesystem
- 关闭
Docker_Mode:不用再兼容docker的日志格式 Parser设为containerd:先解析掉日志前缀Parser_Second设为docker:对提取出的实际日志内容再做JSON解析,还原成嵌套结构
3. 验证效果
重启Fluentbit后,日志会恢复成类似升级前的结构,还会多几个containerd相关的字段(如果不需要可以用filter删掉):
{ "log": { "level": "INFO", "timestamp": "2024-06-28T03:58:22.248Z" }, "stream": "stdout", "logtag": "F", "time": "2024-06-28T03:58:22.24854688Z" }
内容的提问来源于stack exchange,提问作者uylmz
相关产品推荐
相关产品推荐

