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