kind: ConfigMap
apiVersion: v1
metadata:
  name: fluentd-es-config-v0.2.0
  namespace: kube-system
  labels:
    addonmanager.kubernetes.io/mode: Reconcile
data:
  ###### 系统配置，默认即可 #######
  system.conf: |-
    <system>
      root_dir /tmp/fluentd-buffers/
    </system>

  ###### 容器日志—收集配置 #######
  containers.input.conf: |-
    # ------采集 Kubernetes 容器日志-------
    <source>
      @id fluentd-containers.log
      @type tail                              #---Fluentd 内置的输入方式，其原理是不停地从源文件中获取新的日志。
      path /var/log/containers/*.log          #---挂载的服务器Docker容器日志地址
      pos_file /var/log/es-containers.log.pos
      tag raw.kubernetes.*                    #---设置日志标签
      read_from_head true
      <parse>                                 #---多行格式化成JSON
        @type multi_format                    #---使用multi-format-parser解析器插件
        <pattern>
          format json                         #---JSON解析器
          time_key time                       #---指定事件时间的时间字段
          time_format %Y-%m-%dT%H:%M:%S.%NZ   #---时间格式
        </pattern>
        <pattern>
          format /^(?<time>.+) (?<stream>stdout|stderr) [^ ]* (?<log>.*)$/
          time_format %Y-%m-%dT%H:%M:%S.%N%:z
        </pattern>
      </parse>
    </source>

    # -----检测Exception异常日志连接到一条日志中------
    # 关于插件请查看地址：https://github.com/GoogleCloudPlatform/fluent-plugin-detect-exceptions
    <match raw.kubernetes.**>     #---匹配tag为raw.kubernetes.**日志信息
      @id raw.kubernetes
      @type detect_exceptions     #---使用detect-exceptions插件处理异常栈信息，放置异常只要一行而不完整
      remove_tag_prefix raw       #---移出raw前缀
      message log                 #---JSON记录中包含应扫描异常的单行日志消息的字段的名称。
                                  #   如果将其设置为''，则插件将按此顺序尝试'message'和'log'。
                                  #   此参数仅适用于结构化（JSON）日志流。默认值：''。
      stream stream               #---JSON记录中包含“真实”日志流中逻辑日志流名称的字段的名称。
                                  #   针对每个逻辑日志流单独处理异常检测，即，即使逻辑日志流 的
                                  #   消息在“真实”日志流中交织，也将检测到异常。因此，仅组合相
                                  #   同逻辑流中的记录。如果设置为''，则忽略此参数。此参数仅适用于
                                  #   结构化（JSON）日志流。默认值：''。
      multiline_flush_interval 5  #---以秒为单位的间隔，在此之后将转发（可能尚未完成）缓冲的异常堆栈。
                                  #   如果未设置，则不刷新不完整的异常堆栈。
      max_bytes 500000
      max_lines 1000
    </match>

    # -------日志拼接-------
    <filter **>
      @id filter_concat
      @type concat                #---Fluentd Filter插件，用于连接多个事件中分隔的多行日志。
      key message
      multiline_end_regexp /\n$/  #---以换行符“\n”拼接
      separator ""
    </filter>

    # ------过滤Kubernetes metadata数据使用pod和namespace metadata丰富容器日志记录-------
    # 关于插件请查看地址：https://github.com/fabric8io/fluent-plugin-kubernetes_metadata_filter
    <filter kubernetes.**>
      @id filter_kubernetes_metadata
      @type kubernetes_metadata
    </filter>

    # ------修复ElasticSearch中的JSON字段------
    # 关于插件请查看地址：https://github.com/repeatedly/fluent-plugin-multi-format-parser
    <filter kubernetes.**>
      @id filter_parser
      @type parser                #---multi-format-parser多格式解析器插件
      key_name log                #---在要解析的记录中指定字段名称。
      reserve_data true           #---在解析结果中保留原始键值对。
      remove_key_name_field true  #---key_name解析成功后删除字段。
      <parse>
        @type multi_format
        <pattern>
          format json
        </pattern>
        <pattern>
          format none
        </pattern>
      </parse>
    </filter>

  ###### Kuberntes集群节点机器上的日志收集 ######
  system.input.conf: |-
    # ------Kubernetes minion节点日志信息，可以去掉------
    #<source>
    #  @id minion
    #  @type tail
    #  format /^(?<time>[^ ]* [^ ,]*)[^\[]*\[[^\]]*\]\[(?<severity>[^ \]]*) *\] (?<message>.*)$/
    #  time_format %Y-%m-%d %H:%M:%S
    #  path /var/log/salt/minion
    #  pos_file /var/log/salt.pos
    #  tag salt
    #</source>

    # ------启动脚本日志，可以去掉------
    # <source>
    #   @id startupscript.log
    #   @type tail
    #   format syslog
    #   path /var/log/startupscript.log
    #   pos_file /var/log/es-startupscript.log.pos
    #   tag startupscript
    # </source>

    # ------Docker 程序日志，可以去掉------
    # <source>
    #   @id docker.log
    #   @type tail
    #   format /^time="(?<time>[^)]*)" level=(?<severity>[^ ]*) msg="(?<message>[^"]*)"( err="(?<error>[^"]*)")?( statusCode=($<status_code>\d+))?/
    #   path /var/log/docker.log
    #   pos_file /var/log/es-docker.log.pos
    #   tag docker
    # </source>

    #------ETCD 日志，因为ETCD现在默认启动到容器中，采集容器日志顺便就采集了，可以去掉------
    # <source>
    #   @id etcd.log
    #   @type tail
    #   # Not parsing this, because it doesn't have anything particularly useful to
    #   # parse out of it (like severities).
    #   format none
    #   path /var/log/etcd.log
    #   pos_file /var/log/es-etcd.log.pos
    #   tag etcd
    # </source>

    #------Kubelet 日志------
    # <source>
    #   @id kubelet.log
    #   @type tail
    #   format multiline
    #   multiline_flush_interval 5s
    #   format_firstline /^\w\d{4}/
    #   format1 /^(?<severity>\w)(?<time>\d{4} [^\s]*)\s+(?<pid>\d+)\s+(?<source>[^ \]]+)\] (?<message>.*)/
    #   time_format %m%d %H:%M:%S.%N
    #   path /var/log/kubelet.log
    #   pos_file /var/log/es-kubelet.log.pos
    #   tag kubelet
    # </source>

    #------Kube-proxy 日志------
    # <source>
    #   @id kube-proxy.log
    #   @type tail
    #   format multiline
    #   multiline_flush_interval 5s
    #   format_firstline /^\w\d{4}/
    #   format1 /^(?<severity>\w)(?<time>\d{4} [^\s]*)\s+(?<pid>\d+)\s+(?<source>[^ \]]+)\] (?<message>.*)/
    #   time_format %m%d %H:%M:%S.%N
    #   path /var/log/kube-proxy.log
    #   pos_file /var/log/es-kube-proxy.log.pos
    #   tag kube-proxy
    # </source>

    #------kube-apiserver日志------
    # <source>
    #   @id kube-apiserver.log
    #   @type tail
    #   format multiline
    #   multiline_flush_interval 5s
    #   format_firstline /^\w\d{4}/
    #   format1 /^(?<severity>\w)(?<time>\d{4} [^\s]*)\s+(?<pid>\d+)\s+(?<source>[^ \]]+)\] (?<message>.*)/
    #   time_format %m%d %H:%M:%S.%N
    #   path /var/log/kube-apiserver.log
    #   pos_file /var/log/es-kube-apiserver.log.pos
    #   tag kube-apiserver
    # </source>

    #------Kube-controller日志------
    # <source>
    #   @id kube-controller-manager.log
    #   @type tail
    #   format multiline
    #   multiline_flush_interval 5s
    #   format_firstline /^\w\d{4}/
    #   format1 /^(?<severity>\w)(?<time>\d{4} [^\s]*)\s+(?<pid>\d+)\s+(?<source>[^ \]]+)\] (?<message>.*)/
    #   time_format %m%d %H:%M:%S.%N
    #   path /var/log/kube-controller-manager.log
    #   pos_file /var/log/es-kube-controller-manager.log.pos
    #   tag kube-controller-manager
    # </source>

    #------Kube-scheduler日志------
    # <source>
    #   @id kube-scheduler.log
    #   @type tail
    #   format multiline
    #   multiline_flush_interval 5s
    #   format_firstline /^\w\d{4}/
    #   format1 /^(?<severity>\w)(?<time>\d{4} [^\s]*)\s+(?<pid>\d+)\s+(?<source>[^ \]]+)\] (?<message>.*)/
    #   time_format %m%d %H:%M:%S.%N
    #   path /var/log/kube-scheduler.log
    #   pos_file /var/log/es-kube-scheduler.log.pos
    #   tag kube-scheduler
    # </source>

    #------glbc日志------
    # <source>
    #   @id glbc.log
    #   @type tail
    #   format multiline
    #   multiline_flush_interval 5s
    #   format_firstline /^\w\d{4}/
    #   format1 /^(?<severity>\w)(?<time>\d{4} [^\s]*)\s+(?<pid>\d+)\s+(?<source>[^ \]]+)\] (?<message>.*)/
    #   time_format %m%d %H:%M:%S.%N
    #   path /var/log/glbc.log
    #   pos_file /var/log/es-glbc.log.pos
    #   tag glbc
    # </source>

    #------Kubernetes 伸缩日志------
    # <source>
    #   @id cluster-autoscaler.log
    #   @type tail
    #   format multiline
    #   multiline_flush_interval 5s
    #   format_firstline /^\w\d{4}/
    #   format1 /^(?<severity>\w)(?<time>\d{4} [^\s]*)\s+(?<pid>\d+)\s+(?<source>[^ \]]+)\] (?<message>.*)/
    #   time_format %m%d %H:%M:%S.%N
    #   path /var/log/cluster-autoscaler.log
    #   pos_file /var/log/es-cluster-autoscaler.log.pos
    #   tag cluster-autoscaler
    # </source>

    # -------来自system-journal的日志------
    <source>
      @id journald-docker
      @type systemd
      matches [{ "_SYSTEMD_UNIT": "docker.service" }]
      <storage>
        @type local
        persistent true
        path /var/log/journald-docker.pos
      </storage>
      read_from_head true
      tag docker
    </source>

    # -------Journald-container-runtime日志信息------
    <source>
      @id journald-container-runtime
      @type systemd
      matches [{ "_SYSTEMD_UNIT": "{{ fluentd_container_runtime_service }}.service" }]
      <storage>
        @type local
        persistent true
        path /var/log/journald-container-runtime.pos
      </storage>
      read_from_head true
      tag container-runtime
    </source>

    # -------Journald-kubelet日志信息------
    <source>
      @id journald-kubelet
      @type systemd
      matches [{ "_SYSTEMD_UNIT": "kubelet.service" }]
      <storage>
        @type local
        persistent true
        path /var/log/journald-kubelet.pos
      </storage>
      read_from_head true
      tag kubelet
    </source>

    # -------journald节点问题检测器------
    #关于插件请查看地址：https://github.com/reevoo/fluent-plugin-systemd
    #systemd输入插件，用于从systemd日志中读取日志
    <source>
      @id journald-node-problem-detector
      @type systemd
      matches [{ "_SYSTEMD_UNIT": "node-problem-detector.service" }]
      <storage>
        @type local
        persistent true
        path /var/log/journald-node-problem-detector.pos
      </storage>
      read_from_head true
      tag node-problem-detector
    </source>

    # -------kernel日志------
    <source>
      @id kernel
      @type systemd
      matches [{ "_TRANSPORT": "kernel" }]
      <storage>
        @type local
        persistent true
        path /var/log/kernel.pos
      </storage>
      <entry>
        fields_strip_underscores true
        fields_lowercase true
      </entry>
      read_from_head true
      tag kernel
    </source>

  ###### 监听配置，一般用于日志聚合用 ######
  forward.input.conf: |-
    #监听通过TCP发送的消息
    <source>
      @id forward
      @type forward
    </source>

  ###### Prometheus metrics 数据收集 ######
  monitoring.conf: |-
    # input plugin that exports metrics
    # 输出 metrics 数据的 input 插件
    <source>
      @id prometheus
      @type prometheus
    </source>
    <source>
      @id monitor_agent
      @type monitor_agent
    </source>
    # 从 MonitorAgent 收集 metrics 数据的 input 插件
    <source>
      @id prometheus_monitor
      @type prometheus_monitor
      <labels>
        host ${hostname}
      </labels>
    </source>
    # ------为 output 插件收集指标的 input 插件------
    <source>
      @id prometheus_output_monitor
      @type prometheus_output_monitor
      <labels>
        host ${hostname}
      </labels>
    </source>
    # ------为in_tail 插件收集指标的input 插件------
    <source>
      @id prometheus_tail_monitor
      @type prometheus_tail_monitor
      <labels>
        host ${hostname}
      </labels>
    </source>

  ###### 输出配置，在此配置输出到ES的配置信息 ######
  # ElasticSearch fluentd插件地址：https://docs.fluentd.org/v1.0/articles/out_elasticsearch
  output.conf: |-
    <match **>
      @id elasticsearch
      @type elasticsearch
      @log_level info     #---指定日志记录级别。可设置为fatal，error，warn，info，debug，和trace，默认日志级别为info。
      type_name _doc
      include_tag_key true              #---将 tag 标签的 key 到日志中。
      host elasticsearch-logging        #---指定 ElasticSearch 服务器地址。
      port 9200                         #---指定 ElasticSearch 端口号。
      #index_name fluentd.${tag}.%Y%m%d #---要将事件写入的索引名称（默认值:) fluentd。
      logstash_format true              #---使用传统的索引名称格式logstash-%Y.%m.%d，此选项取代该index_name选项。
      #logstash_prefix logstash         #---用于logstash_format指定为true时写入logstash前缀索引名称，默认值:logstash。
      <buffer>
        @type file                      #---Buffer 插件类型，可选file、memory
        path /var/log/fluentd-buffers/kubernetes.system.buffer
        flush_mode interval
        retry_type exponential_backoff  #---重试模式，可选为exponential_backoff、periodic。
                                        #   exponential_backoff 模式为等待秒数，将在每次失败时成倍增长
        flush_thread_count 2
        flush_interval 10s
        retry_forever
        retry_max_interval 30           #---丢弃缓冲数据之前的尝试的最大间隔。
        chunk_limit_size 5M             #---每个块的最大大小：事件将被写入块，直到块的大小变为此大小。
        queue_limit_length 8            #---块队列的长度。
        overflow_action block           #---输出插件在缓冲区队列已满时的行为方式，有throw_exception、block、
                                        #   drop_oldest_chunk，block方式为阻止输入事件发送到缓冲区。
      </buffer>
    </match>