记录日志

Fuchsia 组件可通过多种方式生成日志消息:

  • fuchsia.logger.LogSink 协议。
  • 内核的 debuglog
  • 上述广告格式的组合,通过 stdoutstderr 投放。

LogSink/syslog

想要生成日志消息的组件应连接到 fuchsia.logger.LogSink 协议,然后处理 fuchsia.logger.LogSink/OnInit 事件。fuchsia.logger.LogSink 协议必须在组件清单中use。此协议作为 diagnostics 字典的一部分进行路由。组件必须具有直接路由到它的 fuchsia.logger.LogSink 协议,以便它可以从 parent 使用该协议;或者更常见的是,组件必须具有路由到它的完整 diagnostics 字典,在这种情况下,它可以从 parent/diagnostics 使用 fuchsia.logger.LogSink 协议。

OnInit 事件包含一个 IOBuffer,用于实际发送日志消息。如果 IOBuffer 已满,则会丢弃日志。如果写入器端有任何丢弃的日志消息,系统会对其进行计数,并在下一条成功发送的消息中发送该计数,然后重置计数器。当它检测到丢弃的消息时,会ffx log 打印警告LogSink 服务器必须确保 IOBuffer 有足够的空间,以防止在写入器端丢弃消息。

不同的语言使用不同的机制来连接到 LogSink

debuglog 句柄

内核允许组件从根资源创建 debuglog 句柄。每个句柄都允许其所有者将消息写入内核的共享环形缓冲区。每条消息的限制为 ZX_LOG_RECORD_DATA_MAX 字节,超出限制的内容会被截断。

除了可绑定到文件描述符之外,debuglog 句柄还可以传递给 debuglog_writedebuglog_read 系统调用。

如果某个组件需要将其标准流发送到 debuglog,则必须将 fuchsia.boot.WriteOnlyLog 路由到该组件。

写入到 debuglog 句柄的大多数日志都是通过 stdio 转发写入的。

标准信息流:stdoutstderr

虽然您可能在其他操作系统中熟悉这些概念,但由于它们在系统的不同部分以不同的方式路由,因此在 Fuchsia 中使用这些概念可能难以理解。

驱动程序

驱动程序使用 LogSink 协议进行日志记录,但通过使用自己的库来实现。此库提供了一个 syslog 库的封装容器,以便每个驱动程序都有自己的记录器。

此外,driver_managerstdoutstderr 绑定到 debuglog。这样一来,driver_manager 就可以将关键信息输出到 debuglog,或者回退到 debuglog

组件

默认情况下,只有当组件有权访问用于转发的 LogSink 协议时,才会捕获其 stdoutstderr 流。如需了解详情,请参阅有关转发 stdout 和 stderr 流的 ELF 运行程序部分。

klog 转发到 syslog

归档器会持续从 klog 中读取消息,并将这些消息转发到 syslog 日志。如果来自 klog 的消息在 Archivist 将其读入 syslog 之前从 klog 缓冲区中滚出,则流水线可能会丢弃这些消息。

所有内核日志消息都以 INFO 严重程度发送到系统日志,因为 debuglog 系统调用无法表达消息的严重程度。