2

我有来自某些服务的某些 JSON 格式的日志消息;然后这个流利的过滤器能够正确地解析它。然而有了这个;它会丢弃来自消息字段不是正确 JSON 的其他组件的所有其他日志。

 <source>
      @type tail
      @id in_tail_container_logs
      path /var/log/containers/*.log
      pos_file /var/log/fluentd-containers.log.pos
      tag "#{ENV['FLUENT_CONTAINER_TAIL_TAG'] || 'kubernetes.*'}"
      exclude_path "#{ENV['FLUENT_CONTAINER_TAIL_EXCLUDE_PATH'] || use_default}"
      read_from_head true
      #https://github.com/fluent/fluentd-kubernetes-daemonset/issues/434#issuecomment-752813739
      #<parse>
      #  @type "#{ENV['FLUENT_CONTAINER_TAIL_PARSER_TYPE'] || 'json'}"
      #  time_format %Y-%m-%dT%H:%M:%S.%NZ
      #</parse>
      #https://github.com/fluent/fluentd-kubernetes-daemonset/issues/434#issuecomment-831801690
      <parse>
        @type cri
        <parse> # this will parse the neseted feilds properly - like message in JSON; but if mesage is not in json then this is lost
          @type json 
        </parse>
      </parse>
      #emit_invalid_record_to_error # when nested logging fails, see if we can parse via JSON
      #tag backend.application
    </source>

在此处输入图像描述

但是所有其他没有正确 JSON 格式的消息都会丢失;

如果我注释掉类型 cri 中的嵌套解析部分;然后我得到所有日志;但是消息为 JSON 格式的日志不会被进一步解析。特别是严重性字段。请参阅下面屏幕截图中的最后两行

  <parse>
        @type cri
   </parse>

在此处输入图像描述

克服这一点;如果某些日志的嵌套解析失败,我会尝试使用 LABEL @ERROR;其消息不是 JSON 格式 - 我仍然需要在 Kibana 中以文本形式查看 pod 名称和其他详细信息和消息;但是使用以下配置,它只能解析消息为正确 JSON 格式的日志

    <source>
      @type tail
      @id in_tail_container_logs
      path /var/log/containers/*.log
      pos_file /var/log/fluentd-containers.log.pos
      tag "#{ENV['FLUENT_CONTAINER_TAIL_TAG'] || 'kubernetes.*'}"
      exclude_path "#{ENV['FLUENT_CONTAINER_TAIL_EXCLUDE_PATH'] || use_default}"
      read_from_head true
      #https://github.com/fluent/fluentd-kubernetes-daemonset/issues/434#issuecomment-752813739
      #<parse>
      #  @type "#{ENV['FLUENT_CONTAINER_TAIL_PARSER_TYPE'] || 'json'}"
      #  time_format %Y-%m-%dT%H:%M:%S.%NZ
      #</parse>
      #https://github.com/fluent/fluentd-kubernetes-daemonset/issues/434#issuecomment-831801690
      <parse>
        @type cri
        <parse> # this will parse the neseted feilds properly - like message in JSON; but if mesage is not in json then this is lost
          @type json 
        </parse>
      </parse>
      #emit_invalid_record_to_error # when nested logging fails, see if we can parse via JSON
      #tag backend.application
    </source>


    <label @ERROR> # when nested logs fail this is not working
      <filter **>
        @type parser
        key_name message
        <parse>
          @type none
        </parse>
      </filter>
      <match kubernetes.var.log.containers.elasticsearch-kibana-**> #ignore from this container
        @type null
      </match>
    </label>

在此处输入图像描述

如何获取消息为 JSON 格式解析的日志;并且其消息是文本的;原样不会迷路?

在此处配置(最后提交)https://github.com/alexcpn/grpc_templates.git

4

1 回答 1

1

One way to solve this issue is to prepare the logs before parsing them with cir plugin, to do so you need to perform the following steps

  • collect container logs and tag them with a given tag.
  • classify the logs to JSON and none JSON logs using rewrite_tag_filter. and regex.
  • parse JSON logs with cri
  • parse none JSON Logs

example of configs (not tested)

## collect row logs from files 
<source>
  @type tail
  @id in_tail_container_logs
  path /var/log/containers/*.log
  pos_file /var/log/fluentd-containers.log.pos
  tag kubernetes.*
  exclude_path "#{ENV['FLUENT_CONTAINER_TAIL_EXCLUDE_PATH'] || use_default}"
  read_from_head true
  format json
</source>

# add metadata to the records (container_name, image etc..)
<filter kubernetes.**>
  @type kubernetes_metadata
</filter>

# classify the logs to different categories 
<match kubernetes.**>
 @type rewrite_tag_filter
 <rule>
   key message
   pattern /^\{.+\}$/
   tag json.${tag}
 </rule>
 <rule>
   key message
   pattern /^\{.+\}$/
   tag nonejson.${tag}
   invert true
 </rule>
</match>

# filter or match logs that match the json tag
<filter json.**>
</filter>
<match json.**>
</match>

# filter or match logs that match the none json tag
<filter nonejson.**>
</filter>
<match nonejson.**>
</match>
于 2021-07-06T06:04:23.453 回答