Docker 日志驱动插件

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

日志记录驱动程序使用户能够将容器日志转发到另一个服务进行处理。 Docker 包含多个内置日志记录驱动程序,但永远不可能希望使用内置驱动程序支持所有用例。插件允许 Docker 支持广泛的日志服务,而无需在主 Docker 代码库中嵌入这些服务的客户端库。请参阅 插件文档以获取更多信息。

创建一个日志插件

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

日志驱动协议

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

日志插件必须实现两个 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 流时发生阻塞。

日志流消息被编码为协议缓冲区。 protobuf 定义位于 moby 存储库中。

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

[size][message]

其中size是 4 字节大端二进制编码的 uint32。size在这种情况下定义下一条消息的大小。message是实际的日志条目。

可以 在此处找到流编码器/解码器的参考 golang 实现

/LogDriver.StopLogging

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

此端点上的请求并不意味着容器已被删除,只是容器已停止。

要求:

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

回复:

{
  "Err": ""
}

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

可选端点

日志插件可以实现两个额外的日志端点:

/LogDriver.Capability

定义日志驱动程序的功能。您必须实现此端点,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 消耗的消息相同。