如何在Kubernetes上为Java SpringBoot应用配置Fluent-Bit多行日志解析?
问题:Kubernetes上SpringBoot应用的Fluent-Bit多行日志配置
我正尝试为运行在Kubernetes上的Java SpringBoot应用配置Fluent-Bit多行日志功能。想先通过docker解析器将日志格式化为JSON,再使用自定义多行解析器拼接被\n拆分的日志。尝试以日期格式作为多行解析器的起始规则,并用This.*来捕获应归为同一条日志的后续行,而非拆分为不同事件。同时也在使用默认的Kubernetes日志过滤器。
当前配置文件:
[INPUT] Name tail Tag application.* Path /var/log/containers/test-container* 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 Read_from_Head On [FILTER] Name multiline Match application.* multiline.key_content log multiline.parser docker, multi_docker_java [MULTILINE_PARSER] name multi_docker_java type regex flush_timeout 1000 key_content log rule "start_state" "/\d{4}-\d{1,2}-\d{1,2}T\d{2}:\d{2}:\d{2}.\d{3}Z.*" "cont" rule "cont" "/This.*" "cont" [FILTER] Name kubernetes Match application.* Kube_URL https://kubernetes.default.svc:443 Kube_Tag_Prefix application.var.log.containers. Merge_Log On Merge_Log_Key log_processed K8S-Logging.Parser On K8S-Logging.Exclude Off Labels Off Annotations Off Use_Kubelet On Kubelet_Port 10250 Buffer_Size 0
测试日志(省略Kubernetes信息):
{ "log": "2023-05-05T13:46:47.628Z INFO 1 --- [nio-8080-exec-9] c.e.sampleApp.controller.MainController : This is line one of the log message.\n", "stream": "stdout", "kubernetes": { "pod_name": "", "namespace_name": "", "pod_id": "", "host": "", "container_name": "", "docker_id": "", "container_hash": "", "container_image": "" } } { "log": "This is line two of the log message.\n", "stream": "stdout", "kubernetes": { "pod_name": "", "namespace_name": "", "pod_id": "", "host": "", "container_name": "", "docker_id": "", "container_hash": "", "container_image": "" } } { "log": "Here I am!\n", "stream": "stdout", "kubernetes": { "pod_name": "", "namespace_name": "", "pod_id": "", "host": "", "container_name": "", "docker_id": "", "container_hash": "", "container_image": "" } }
解决方案
你的思路完全可行:先通过docker解析器将容器的JSON格式日志解析为结构化数据,再用自定义多行解析器拼接拆分的日志行。但当前配置存在两个关键问题:
- 多行解析器规则局限性:自定义的
multi_docker_java解析器仅匹配以This开头的后续行,导致第三行Here I am!无法被合并到前一条日志中。 - 过滤器顺序不合理:当前Kubernetes过滤器在多行处理之后执行,可能干扰已合并的日志结构,需要调整顺序。
修正后的完整配置
[INPUT] Name tail Tag application.* Path /var/log/containers/test-container* 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 Read_from_Head On # 先执行Kubernetes过滤器,解析原始JSON日志并获取元数据 [FILTER] Name kubernetes Match application.* Kube_URL https://kubernetes.default.svc:443 Kube_Tag_Prefix application.var.log.containers. Merge_Log On Merge_Log_Key log_processed K8S-Logging.Parser On K8S-Logging.Exclude Off Labels Off Annotations Off Use_Kubelet On Kubelet_Port 10250 Buffer_Size 0 # 基于解析后的日志内容执行多行合并 [FILTER] Name multiline Match application.* multiline.key_content log_processed multiline.parser multi_docker_java [MULTILINE_PARSER] name multi_docker_java type regex flush_timeout 1000 key_content log_processed # 匹配ISO8601日期开头的行作为日志起始 rule "start_state" "/^\d{4}-\d{1,2}-\d{1,2}T\d{2}:\d{2}:\d{2}.\d{3}Z/" "cont" # 匹配所有不以日期开头的行,作为当前日志的后续行 rule "cont" "/^(?!\d{4}-\d{1,2}-\d{1,2}T\d{2}:\d{2}:\d{2}.\d{3}Z)/" "cont"
配置说明
- 调整过滤器顺序:先运行Kubernetes过滤器,它会自动调用
docker解析器将原始JSON日志解析为结构化数据,并将纯日志内容存入log_processed字段(由Merge_Log_Key指定)。 - 优化多行解析规则:
- 起始规则精准匹配ISO8601格式的日期开头,确保只有日志的起始行被标记为新事件。
- 后续行使用反向匹配
^(?!...),捕获所有不以日期开头的行,覆盖Java日志中各种格式的续行(比如异常栈、普通文本行等),不再局限于This开头的内容。
- 统一key_content:多行过滤器和解析器的
key_content改为log_processed,确保基于解析后的纯日志内容进行合并,避免原始JSON结构的干扰。
调整后,测试日志会被合并为两条事件:
- 第一条包含
2023-05-05T13:46:47.628Z ... This is line one...和This is line two... - 第二条是
Here I am!(因无匹配的起始行,单独作为一条事件,符合日志本身的逻辑)
内容的提问来源于stack exchange,提问作者mmiara
相关产品推荐
相关产品推荐

