记录日志

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

  • fuchsia.logger.LogSink 协议。
  • 内核的 debuglog
  • 上述各项的组合,通过 stdoutstderr 进行路由。

LogSink/syslog

想要生成日志消息的组件会调用 fuchsia.logger.LogSink/ConnectStructured。必须在组件清单中use fuchsia.logger.LogSink 协议。此协议会作为 diagnostics 字典的一部分进行路由。组件必须将 fuchsia.logger.LogSink 协议直接路由到它,以便它能够从 parent 使用该协议,或者更常见的是,将完整的 diagnostics 字典路由到它,在这种情况下,它可以使用 parent/diagnostics 中的 fuchsia.logger.LogSink 协议。

ConnectStructured 会接受一个套接字,syslog 库会在该套接字中写入实际的日志消息。如果套接字缓冲区已满,默认情况下写入线程会丢弃日志。如果写入端有任何丢弃的日志消息,系统会对其进行统计,并在下一条成功发送的消息中发送该统计结果,然后重置计数器。ffx log 在检测到丢弃的消息时,会输出警告LogSink 服务器必须足够快地耗尽它收到的所有套接字,以防止在写入端丢弃消息。

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

debuglog 句柄

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

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

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

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

标准串流:stdoutstderr

虽然这些概念可能与您在其他操作系统中看到的类似,但在 Fuchsia 中使用它们可能很难理解,因为它们在系统的不同部分的路由方式不同。

驱动程序

驱动程序使用 LogSink 协议进行日志记录,但会通过使用 zxlogf 来实现日志记录。此函数会为 syslog 库提供封装容器,以便每个驱动程序都有自己的日志消息套接字。

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

组件

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

klog 转发到 syslog

归档程序会持续从 klog 读取数据,并将这些消息转发到 syslog 日志。如果 klog 中的邮件在归档程序将其读取到 syslog 之前从 klog 缓冲区滚出,流水线可能会丢弃这些邮件。

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