Fuchsia 组件可以通过以下几种方式生成日志消息:
fuchsia.logger.LogSink
协议。- 内核的
debuglog
。 - 上述各项的组合,通过
stdout
或stderr
进行路由。
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_write
和 debuglog_read
系统调用。
如果某个组件需要将其标准数据流发送到 debuglog
,则必须将 fuchsia.boot.WriteOnlyLog
路由到该组件。
写入 debuglog
句柄的大多数日志都是通过 stdio 转发写入的。
标准串流:stdout
和 stderr
虽然这些概念可能与您在其他操作系统中看到的类似,但在 Fuchsia 中使用它们可能很难理解,因为它们在系统的不同部分的路由方式不同。
驱动程序
驱动程序使用 LogSink
协议进行日志记录,但会通过使用 zxlogf
来实现日志记录。此函数会为 syslog
库提供封装容器,以便每个驱动程序都有自己的日志消息套接字。
此外,driver_manager
会将 stdout
和 stderr
绑定到 debuglog
。这样,driver_manager
就可以将关键信息输出到 debuglog
,或回退到 debuglog
。
组件
默认情况下,只有当组件有权访问用于转发的 LogSink
协议时,系统才会捕获其 stdout
和 stderr
数据流。如需了解详情,请参阅有关转发标准输出和标准错误流的 ELF 运行程序部分。
将 klog
转发到 syslog
归档程序会持续从 klog
读取数据,并将这些消息转发到 syslog
日志。如果 klog
中的邮件在归档程序将其读取到 syslog
之前从 klog
缓冲区滚出,流水线可能会丢弃这些邮件。
所有内核日志消息都会以 INFO
严重级别发送到系统日志,因为 debuglog
系统调用无法表达消息的严重级别。