Logtail支持将容器的标准输出流作为输入源,并附加容器的相关元数据信息一起上传到日志服务。

功能特点

  • 支持采集stdout、stderr
  • 支持label指定采集的容器
  • 支持label排除特定容器
  • 支持environment指定采集的容器
  • 支持environment指定排除的容器
  • 支持多行日志(例如java stack日志等)
  • 支持container数据自动打标
  • 支持Kubernetes容器自动打标

实现原理

如下图所示,Logtail会与Docker的Domain Socket进行通信,查询该Docker上运行的所有container,并根据container配置的label和environment信息定位需要被采集的container。随后Logtail会通过docker的log命令获取指定container的日志。

Logtail在采集容器的标准输出时,会定期将采集的点位信息保存到checkpoint文件中,若Logtail停止后再次启动,会从上一次保存的点位开始采集日志。

图 1. 实现原理


使用限制

  • 此功能目前仅支持Linux,依赖Logtail 0.16.0及以上版本,版本查看与升级参见Linux
  • Logtail默认通过/var/run/docker.sock访问docker engine,请确保该Domain Socket存在且具备访问权限。
  • 多行日志限制。为保证多行组成的一条日志不因为输出延迟而被分割成多条,多行日志情况下,采集的最后一条日志默认都会缓存一段时间。默认缓存时间为3秒,可通过BeginLineTimeoutMs设置,但此值不能低于1000,否则容易出现误判。
  • 采集停止策略。当container被停止后,Logtail监听到容器die的事件后会停止采集该container的标准输出,若此时采集出现延迟,则可能丢失停止前的部分输出。
  • Docker日志驱动类型限制。目前标准输出采集仅支持JSON类型的日志驱动。
  • 上下文限制。默认一个采集配置在同一上下文中,若需要每种类型的container一个上下文,请单独配置。
  • 数据处理。采集到的数据默认字段为content,支持通用的处理配置。请参考自定义插件配置一种或多种采集方式。
  • Label。 此处的label为docker inspect中的label信息,并不是Kubernetes配置中的label。
  • Environment。此处的environment为容器启动中配置的environment信息。

配置流程

  1. 部署并配置Logtail容器。
  2. 设置服务端采集配置。

步骤1 Logtail部署和配置

步骤2 设置数据源

  1. Logstore列表单击数据接入向导图标,进入配置流程。
  2. 选择数据类型。

    单击自建软件中的Docker标准输出,并单击下一步

  3. 设置数据源。

    输入源配置页面,填写您的采集配置。示例如下,配置项说明请查看本文档中配置项说明部分。

    {
     "inputs": [
         {
             "type": "service_docker_stdout",
             "detail": {
                 "Stdout": true,
                 "Stderr": true,
                 "IncludeLabel": {
                     "io.kubernetes.container.name": "nginx"
                 },
                 "ExcludeLabel": {
                     "io.kubernetes.container.name": "nginx-ingress-controller"
                 },
                 "IncludeEnv": {
                     "NGINX_SERVICE_PORT": "80"
                 },
                 "ExcludeEnv": {
                     "POD_NAMESPACE": "kube-system"
                 }
             }
         }
     ]
    }
  4. 应用到机器组。

    进入应用到机器组页面。请在此处勾选需要采集的Logtail机器组。如您之前没有创建过机器组,单击+创建机器组以创建一个新的机器组。

配置项说明

该输入源类型为: service_docker_stdout

说明 Logtail支持对采集的数据进行处理加工后上传,处理方式参见插件-处理采集数据
配置项 类型 是否必选 说明
IncludeLabel map类型,其中key为string,value为string 必选 默认为空,为空时代表采集所有Container数据;当key非空,value为空时,代表包含label中所有包含此key的container。
说明
  1. 多个键值对间为或关系,即只要容器的label满足任一键值对即可被采集。
  2. 此处的label为docker inspect中的label信息。
ExcludeLabel map类型,其中key为string,value为string 可选 默认为空,为空时不排除任何Container;当key非空,value为空时,代表排除label中所有包含此key的container。
说明
  1. 多个键值对间为或关系,即只要容器的label满足任一键值对即被排除。
  2. 此处的label为docker inspect中的label信息。
IncludeEnv map类型,其中key为string,value为string 可选 默认为空,为空时代表采集所有Container数据;当key非空,value为空时,代表包含environment中所有包含此key的container。
说明
  1. 多个键值对间为或关系,即只要容器的environment满足任一键值对即可被采集。
  2. 此处的environment为容器启动中配置的environment信息。
ExcludeEnv map类型,其中key为string,value为string 可选 默认为空,为空时不排除任何Container;当key非空,value为空时,代表排除Environment中所有包含此key的container。
说明
  1. 多个键值对间为或关系,即只要容器的environment满足任一键值对即被排除。
  2. 此处的environment为容器启动中配置的environment信息。
Stdout bool 可选 默认为true,为false时不采集stdout数据。
Stderr bool 可选 默认为true,为false时不采集stderr数据。
BeginLineRegex string 可选 默认为空,非空时为行首匹配的正则表达式。若该表达式匹配某行,则将该行作为新的一条日志;否则将此行数据连接到上一条日志。
BeginLineTimeoutMs int 可选 行首匹配超时时间,默认为3000,单位为毫秒。若3秒内没有新日志出现,则将最后一条日志输出。
BeginLineCheckLength int 可选 行首匹配的长度,默认为10×1024,单位为字节。若行首规则在前N个字节即可体现,可设置此参数,以此提升行首匹配效率。
MaxLogSize int 可选 日志最大长度,默认为512×1024,单位为字节。若日志超过该项配置,则不继续查找行首,直接上传。
说明
  1. 本文档中IncludeLabel、ExcludeLabel和Kubernetes中定义的label不是同一概念,本文档中的label为docker inspect中的label信息。
  2. Kubernetes中的namespace和容器名会映射到docker的label中,分别为io.kubernetes.pod.namespaceio.kubernetes.container.name。例如您创建的pod所属namespace为backend-prod,容器名为 worker-server,则IncludeLabel中可以配置2个键值对来指定只采集该容器的日志,分别为 io.kubernetes.pod.namespace : backend-prodio.kubernetes.container.name : worker-server
  3. Kubernetes不建议使用除io.kubernetes.pod.namespaceio.kubernetes.container.name之外的其他label。其他情况请使用IncludeEnv/ExcludeEnv。

默认字段

普通Docker

每条日志默认上传以下字段:

字段名 说明
_time_ 数据时间,样例为2018-02-02T02:18:41.979147844Z
_source_ 输入源类型,stdout 或 stderr
_image_name_ 镜像名
_container_name_ 容器名
_container_ip_ 容器IP
Kubernetes

若该集群为Kubernetes,则默认每条日志上传以下字段:

字段名 说明
_time_ 数据时间,样例为2018-02-02T02:18:41.979147844Z
_source_ 输入源类型,stdout 或 stderr
_image_name_ 镜像名
_container_name_ 容器名
_pod_name_ pod名
_namespace_ pod所在命名空间
_pod_uid_ pod的唯一标识
_container_id_ pod的IP地址

配置示例

常规配置

  • environment 配置方式

    采集environment为NGINX_PORT_80_TCP_PORT=80且environment不为POD_NAMESPACE=kube-system的stdout以及stderr日志:

    说明 此处的environment为容器启动中配置的environment信息。
    图 2. environment 配置方式示例


    采集配置:
    {
        "inputs": [
            {
                "type": "service_docker_stdout",
                "detail": {
                    "Stdout": true,
                    "Stderr": true,
                    "IncludeEnv": {
                        "NGINX_PORT_80_TCP_PORT": "80"
                    },
                    "ExcludeEnv": {
                        "POD_NAMESPACE": "kube-system"
                    }
                }
            }
        ]
    }
  • label 配置方式

    采集label为io.kubernetes.container.name=nginx且label不为type=pre的stdout以及stderr日志:

    说明 此处的label为docker inspect中的label信息,并不是Kubernetes配置中的label。
    图 3. label配置方式示例


    {
        "inputs": [
            {
                "type": "service_docker_stdout",
                "detail": {
                    "Stdout": true,
                    "Stderr": true,
                    "IncludeLabel": {
                        "io.kubernetes.container.name": "nginx"
                    },
                    "ExcludeLabel": {
                        "type": "pre"
                    }
                }
            }
        ]
    }

多行日志采集配置

多行日志采集对于Java异常堆栈输出的采集尤为重要,这里介绍一种标准的Java标准输出日志的采集配置。

  • 日志示例
    2018-02-03 14:18:41.968  INFO [spring-cloud-monitor] [nio-8080-exec-4] c.g.s.web.controller.DemoController : service start
    2018-02-03 14:18:41.969 ERROR [spring-cloud-monitor] [nio-8080-exec-4] c.g.s.web.controller.DemoController : java.lang.NullPointerException
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
    ...
    2018-02-03 14:18:41.968  INFO [spring-cloud-monitor] [nio-8080-exec-4] c.g.s.web.controller.DemoController : service start done
  • 采集配置

    采集label为app=monitor输入的日志,行首为日期类型(为提高匹配效率,这里只判断行首的10个字节)。

    {
    "inputs": [
      {
        "detail": {
          "BeginLineCheckLength": 10,
          "BeginLineRegex": "\\d+-\\d+-\\d+.*",
          "IncludeLabel": {
            "app": "monitor"
          }
        },
        "type": "service_docker_stdout"
      }
    ]
    }

采集数据处理

Logtail对于采集到的Docker标准输出,支持通用数据处理方式。建议使用基于上一节的多行日志格式,使用正则表达式将日志解析成time、module、thread、class、info。

  • 采集配置
    采集label为 app=monitor输入的日志,行首为日期类型(为提高匹配效率,这里只判断行首的10个字节)。
    {
    "inputs": [
      {
        "detail": {
          "BeginLineCheckLength": 10,
          "BeginLineRegex": "\\d+-\\d+-\\d+.*",
          "IncludeLabel": {
            "app": "monitor"
          }
        },
        "type": "service_docker_stdout"
      }
    ],
    "processors": [
        {
            "type": "processor_regex",
            "detail": {
                "SourceKey": "content",
                "Regex": "(\\d+-\\d+-\\d+ \\d+:\\d+:\\d+\\.\\d+)\\s+(\\w+)\\s+\\[([^]]+)]\\s+\\[([^]]+)]\\s+:\\s+([\\s\\S]*)",
                "Keys": [
                    "time",
                    "module",
                    "thread",
                    "class",
                    "info"
                ],
                "NoKeyError": true,
                "NoMatchError": true,
                "KeepSource": false
            }
        }
    ]
    }
  • 样例输出

    对于日志2018-02-03 14:18:41.968 INFO [spring-cloud-monitor] [nio-8080-exec-4] c.g.s.web.controller.DemoController : service start done处理后的输出为:

    __tag__:__hostname__:logtail-dfgef
    _container_name_:monitor
    _image_name_:registry.cn-hangzhou.aliyuncs.xxxxxxxxxxxxxxx
    _namespace_:default
    _pod_name_:monitor-6f54bd5d74-rtzc7
    _pod_uid_:7f012b72-04c7-11e8-84aa-00163f00c369
    _source_:stdout
    _time_:2018-02-02T14:18:41.979147844Z
    time:2018-02-02 02:18:41.968
    level:INFO
    module:spring-cloud-monitor
    thread:nio-8080-exec-4
    class:c.g.s.web.controller.DemoController
    message:service start done