记录日志

您可以通过以下几种方式看到 Fuchsia 程序生成日志消息:

  • LogSink 服务
  • 内核的调试日志
  • 这些对象的组合,通过 stdoutstderr 进行路由

LogSink/syslog

要生成日志消息的组件会调用 fuchsia.logger/LogSink.Connectfuchsia.logger.LogSink 服务必须在组件清单中进行 used

Connect 会接受一个套接字,实际日志消息由 syslog 库写入。

如果套接字的缓冲区已满,写入线程将丢弃日志。写入器端丢弃的消息会计算在内,该计数会在下一条成功消息中发送,之后会重置计数器。log_listener 检测到邮件丢失时,会输出警告

LogSink 服务必须足够快地排空它收到的所有套接字,以防止消息在写入者端被丢弃。LogSink 负责排空这些套接字以填充内部缓冲区(TODO(https://fxbug.dev/42124432):自 https://fxrev.dev/490158 以来不再为 true)。在进行大量日志记录时,这可能会导致写入组件和 LogSink 中的 CPU 使用率较高。

不同的语言使用不同的机制与 LogSink 通信。如需了解详情,请参阅相关页面:

调试日志句柄

内核允许程序从根资源创建调试日志句柄,每个句柄都允许其所有者将消息写入到内核的共享环缓冲区中。每条消息的上限为 ZX_LOG_RECORD_DATA_MAX 字节,超出的内容会被截断。

除了可绑定到文件描述符之外,调试日志句柄还可以传递给 debuglog_writedebuglog_read 系统调用。读取系统调用用于从调试日志传输到系统日志。

需要将其标准流发送到调试日志的组件可以通过 fuchsia.boot.WriteOnlyLog 协议获得访问权限。

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

标准视频流:stdoutstderr

其他操作系统中的许多人都很熟悉这些概念,但是它们在 Fuchsia 中的使用可能非常复杂,因为它们在系统的不同部分以不同的方式路由。

驱动程序

驱动程序会记录到 LogSink 接收器服务,但要使用 zxlogf 执行此操作。此函数提供了一个 syslog 库的封装容器,以便每个驱动程序都有自己的日志消息套接字。

此外,driver_manager 会将 stdoutstderr 绑定到调试日志。这样一来,driver_manager 便可将关键信息输出到调试日志,或者在无法使用 LogSink 服务的某些产品配置时回退到调试日志。

组件

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

将 klog 转发到 syslog

存档人员不断从 klog 中读取数据,并将这些消息转发到主日志。如果来自 klog 的消息在存档人员将其读取到 syslog 之前从 klog 缓冲区推出,那么这些消息可能会被流水线丢弃。

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