添加 LogSink 连接属性
当 Fuchsia 组件希望撰写日志时,它必须获得对其环境中fuchsia.logger.LogSink
的连接,通常由归档器实例提供。
典型的 Fuchsia 服务连接是匿名的,因此服务器和客户端没有对于彼此的识别信息。客户端只是在其命名空间看到服务,例如 /svc/fuchsia.logger.LogSink
,而服务器看到的是对其传入命名空间的匿名 Open()
请求。
与此同时,了解日志的来源也很重要,因为可信来源的元数据带来更好的监控、存储、查询和日志呈现。系统通过名为“附带属性记录(attributed logging)”的特性来解决这个问题,这一特性能够识别 LogSink
(“日志槽”)传入连接的来源。
appmgr:日志连接器(LogConnector)
归档器服务 fuchsia.sys.internal/LogConnectionListener
以接收 LogSink
连接和 fuchsia.sys.internal/SourceIdentity
元数据。
为界初始化 LogConnectionListener
归档器连接至由 appmgr 提供的 fuchsia.sys.internal/LogConnector
。归档器接下来调用 TakeLogConnectionListener()
检索通道的服务器端,该通道为建立连接的界(realm)实现了 fuchsia.sys.internal/LogConnectionListener
。该行为可通过带 --disable-log-connector
标记运行归档器禁用。
在生产中,[归档器]在 appmgr “之上”运行,并且通过 sys
界连接,针对 appmgr 的根界采用 LogConnectionListener
(日志连接侦听器),并捕捉所有 LogSink
连接。
如果界的调用者已经显式地为 fuchsia.logger.LogSink
提供了记录(entry),允许测试环境拦截和读取其自身的日志,那么 appmgr 不会向该界提供事先添加的 LogSink
属性。
建立日志槽连接
当 appmgr 启动一个组件时,它会实例化一个 ServiceProviderDirImpl,用组件命名空间进行填充。每个目录在创建前,需要先获取父/封闭环境的服务,并将它们过滤到在 sandbox.services
下组件的 .cmx
文件中列出的条目中。
如果组件在其清单中列出了 fuchsia.logger.LogSink
,那么其环境不提供实现,appmgr 为该界初始化一个 LogConnectionListener
,在该组件的命名空间中提供“事先添加的 LogSink
属性”从组件的角度来看,它的行为如同普通的 LogSink
实例。当与它建立连接时,发送的通道和 SourceIdentity
(源身份)一同转发至相应的 LogConnectionListener
。
组件管理器:CapabilityRequested(功能需求)事件
归档器的清单同其他服务功能一样公开(expose
) fuchsia.logger.LogSink
,但它也使用(use
)来自框架的事件,将其绑定至其命名空间的服务:
{
event: "capability_requested",
from: "framework",
filter: { name: "fuchsia.logger.LogSink" },
},
{
event_stream: "EventStream",
subscriptions: [
{
event: "capability_requested",
mode: "async",
}
],
},
这导致组件管理器(Component Manager)将传入请求从默认的 fuchsia.io
命名空间协议重定向至 fuchsia.sys2.EventStream
协议。归档器类似于 LogConnectionListener
接收该协议上的事件,从由组件管理器发送的 ComponentDescriptor 检索属性元数据和 LogSink
通道的句柄。描述符(descriptor)中包含的昵称(moniker)是在功能路由(capability routing)时建构的。
为 LogSink
配置 capability_requested
(功能需求)事件并不影响功能路由本身,只是将通道作为事件代替 Open() 传递给归档器。这意味着用于传递事先添加的 LogSink
属性的 CML 将对于组件拓扑的剩余部分保持不变。
要获取更多信息,请参阅 Life of a protocol open 和 cm-事件。