You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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格式日志解析为结构化数据,再用自定义多行解析器拼接拆分的日志行。但当前配置存在两个关键问题:

  1. 多行解析器规则局限性:自定义的multi_docker_java解析器仅匹配以This开头的后续行,导致第三行Here I am!无法被合并到前一条日志中。
  2. 过滤器顺序不合理:当前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"

配置说明

  1. 调整过滤器顺序:先运行Kubernetes过滤器,它会自动调用docker解析器将原始JSON日志解析为结构化数据,并将纯日志内容存入log_processed字段(由Merge_Log_Key指定)。
  2. 优化多行解析规则:
    • 起始规则精准匹配ISO8601格式的日期开头,确保只有日志的起始行被标记为新事件。
    • 后续行使用反向匹配^(?!...),捕获所有不以日期开头的行,覆盖Java日志中各种格式的续行(比如异常栈、普通文本行等),不再局限于This开头的内容。
  3. 统一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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 09:17:08