您可以通过以下几种方式看到 Fuchsia 程序生成日志消息:
- LogSink 服务
- 内核的调试日志
- 这些对象的组合,通过
stdout
或stderr
进行路由
LogSink
/syslog
要生成日志消息的组件会调用 fuchsia.logger/LogSink.Connect
。fuchsia.logger.LogSink
服务必须在组件清单中进行 use
d。
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_write
和 debuglog_read
系统调用。读取系统调用用于从调试日志传输到系统日志。
需要将其标准流发送到调试日志的组件可以通过 fuchsia.boot.WriteOnlyLog
协议获得访问权限。
写入调试日志句柄的大多数日志都是通过 stdio 转发写入的。
标准视频流:stdout
和 stderr
其他操作系统中的许多人都很熟悉这些概念,但是它们在 Fuchsia 中的使用可能非常复杂,因为它们在系统的不同部分以不同的方式路由。
驱动程序
驱动程序会记录到 LogSink
接收器服务,但要使用 zxlogf
执行此操作。此函数提供了一个 syslog 库的封装容器,以便每个驱动程序都有自己的日志消息套接字。
此外,driver_manager
会将 stdout
和 stderr
绑定到调试日志。这样一来,driver_manager
便可将关键信息输出到调试日志,或者在无法使用 LogSink
服务的某些产品配置时回退到调试日志。
组件
默认情况下,只有当组件有权访问 LogSink
服务进行转发时,系统才会捕获其 stdout
和 stderr
流。如需了解详情,请参阅有关转发 stdout 和 stderr 流的 ELF 运行程序部分。
将 klog 转发到 syslog
存档人员不断从 klog 中读取数据,并将这些消息转发到主日志。如果来自 klog 的消息在存档人员将其读取到 syslog 之前从 klog 缓冲区推出,那么这些消息可能会被流水线丢弃。
所有内核日志消息都会发送到具有 INFO 严重级别的系统日志,因为调试日志系统调用无法表示消息严重性。