Docker 日志驱动程序插件

本文档描述了 Docker 的日志驱动程序插件。

日志驱动程序允许用户将容器日志转发到另一个服务进行处理。Docker 内置了几个日志驱动程序,但无法期望用内置驱动程序支持所有用例。插件允许 Docker 支持广泛的日志服务,而无需在主要的 Docker 代码库中嵌入这些服务的客户端库。有关更多信息,请参阅插件文档

创建日志插件

日志插件的主要接口使用与其他插件类型相同的 JSON+HTTP RPC 协议。请参阅示例插件作为日志插件的参考实现。该示例封装了内置的 jsonfilelog 日志驱动程序。

LogDriver 协议

日志插件必须在插件激活期间注册为 LogDriver。激活后,用户可以将该插件指定为日志驱动程序。

日志插件必须实现两个 HTTP 端点:

/LogDriver.StartLogging

向插件发出信号,指示容器正在启动,插件应开始接收其日志。

日志将通过请求中定义的文件进行流式传输。在 Linux 上,此文件是 FIFO。日志插件目前不支持 Windows。

请求

{
  "File": "/path/to/file/stream",
  "Info": {
          "ContainerID": "123456"
  }
}

File 是需要消费的日志流的路径。每次调用 StartLogging 都应该提供不同的文件路径,即使是插件之前已经接收过日志的容器。该文件由 Docker 使用随机生成的名称创建。

Info 是正在记录日志的容器的详细信息。这相当自由,但由以下结构定义:

type Info struct {
	Config              map[string]string
	ContainerID         string
	ContainerName       string
	ContainerEntrypoint string
	ContainerArgs       []string
	ContainerImageID    string
	ContainerImageName  string
	ContainerCreated    time.Time
	ContainerEnv        []string
	ContainerLabels     map[string]string
	LogPath             string
	DaemonName          string
}

此结构将始终提供 ContainerID,但其他字段可能为空或缺失。

响应

{
  "Err": ""
}

如果在请求期间发生错误,请在响应的 Err 字段中添加错误消息。如果没有错误,您可以发送空响应 ({}) 或 Err 字段的空值。

此时,驱动程序应正在消费从传入文件中获取的日志消息。如果消息未被消费,可能会导致容器在尝试写入其 stdio 流时阻塞。

日志流消息被编码为协议缓冲区 (protocol buffers)。protobuf 定义位于moby 仓库中。

由于协议缓冲区不是自定界 (self-delimited) 的,您必须使用以下流格式从流中解码它们:

[size][message]

其中 size 是一个 4 字节大端二进制编码的 uint32。此处的 size 定义了下一条消息的大小。message 是实际的日志条目。

可以在这里找到流编码器/解码器的 Golang 参考实现。

/LogDriver.StopLogging

向插件发出信号,指示停止从指定文件收集日志。收到响应后,文件将被 Docker 删除。您必须确保在响应此请求之前收集流中的所有日志,否则可能会丢失日志数据。

对此端点的请求并不意味着容器已被移除,仅表示它已停止。

请求

{
  "File": "/path/to/file/stream"
}

响应

{
  "Err": ""
}

如果在请求期间发生错误,请在响应的 Err 字段中添加错误消息。如果没有错误,您可以发送空响应 ({}) 或 Err 字段的空值。

可选端点

日志插件可以实现另外两个日志记录端点:

/LogDriver.Capabilities

定义日志驱动程序的功能。您必须实现此端点,Docker 才能利用任何定义的功能。

请求

{}

响应

{
  "ReadLogs": true
}

支持的功能

  • ReadLogs - 这告诉 Docker,插件能够将日志读回给客户端。报告支持 ReadLogs 的插件必须实现 /LogDriver.ReadLogs 端点。

/LogDriver.ReadLogs

将日志读回给客户端。在调用 docker logs <container> 时使用此功能。

为了让 Docker 使用此端点,插件在调用 /LogDriver.Capabilities 时必须明确指定支持此功能。

请求

{
  "ReadConfig": {},
  "Info": {
    "ContainerID": "123456"
  }
}

ReadConfig 是读取选项列表,它由以下 Golang 结构定义:

type ReadConfig struct {
	Since  time.Time
	Tail   int
	Follow bool
}
  • Since 定义了应发送的最早日志。
  • Tail 定义了要读取的行数(例如,类似于命令 tail -n 10)。
  • Follow 表示客户端希望保持连接,以便在读取现有日志后接收新的日志消息。

Info/LogDriver.StartLogging 中定义的类型相同。它应该用于确定要读取哪些日志。

响应

{{ log stream }}

响应应是编码的日志消息,使用与插件从 Docker 消费的消息相同的格式。

页面选项