Inspect 是 Fuchsia 组件的一项强大的诊断功能。
本文档详细介绍了组件如何托管其 Inspect 数据,以及各种工具如何发现这些数据。
Hosting 检查数据
组件可以通过以下方式公开 Inspect 数据:
fuchsia.inspect.Tree(C++、Rust)VmoFile(Dart)
组件无需与其他服务联系即可公开 Inspect 数据。
组件通常不需要关注正在使用的方法,客户端库会抽象出托管的具体机制。几乎所有实现最终都会使用 Tree。
| 功能 | fuchsia.inspect.Tree |
VmoFile |
说明 |
|---|---|---|---|
| 非延迟值 | 是 | 是 | 组件可能会记录字符串和整数等值。 |
| 延迟值 | 是 | 否 | 组件可能会在读取时动态生成值。 |
| 可变树 | 是 | 是 | 组件可以修改存储在其输出中的值。 |
| 宰后检验 | 是 | 是 | 组件记录的值在组件退出后可用。 |
| 低延迟快照 | 是 | 是 | 可以低延迟获取数据的完整快照。 |
| 一致性快照 | 是* | 是 | 树的快照可保证表示其在某个时间点的状态。 |
(*:每个树的快照都是一致的,但无法保证树间一致性)
fuchsia.inspect.Tree
fuchsia.inspect.Tree 支持 Inspect API 的所有功能,并且是推荐的从组件公开 Inspect 数据的方式。
组件使用 fuchsia.inspect.InspectSink 协议发布 fuchsia.inspect.Tree。
实现
fuchsia.inspect.Tree FIDL 文件定义了由组件托管以公开其 Inspect 数据的协议。
Tree 协议将多个检查 VMO 链接在一起,形成一个“树中树”。

在上图中,名为“root”的树处理 fuchsia.inspect.Tree 下托管的顶级服务上的连接的协议 fuchsia.inspect.Tree。您可以使用协议上的方法枚举和打开子树。例如,“子 B”在打开和读取之前可能不存在于内存中。
该协议通过以下方式支持此行为:
GetContent此方法会获取树的内容,目前采用 Inspect VMO 的形式。按照惯例,在根树上调用此方法应返回一个 VMO,该 VMO 将不断更新新数据。客户端应该不需要重新读取树的内容来读取新值。
ListChildNames此方法接受一个迭代器,该迭代器将返回树的子级名称。例如,在根树上运行时,上图中的树将返回名称“child A”和“child B”。
OpenChild此方法接受对
fuchsia.inspect.Tree的请求,该请求将绑定到由给定名称指定的树。使用此方法,客户端可以遍历通过根接口公开的所有树。
读取 Inspect 数据
读取 Inspect 数据的两种主要方式如下:
iquery
iquery(检查查询)是用于与检查数据进行交互的 CLI。
iquery 的主要操作模式是获取 Inspect 数据的选择器列表,并输出所包含的信息。选择器由三个部分组成,各部分之间用 : 分隔:
- 组件选择器:这是 v2 中的名字对象或领域路径加上 v1 中的组件名称。
- 节点路径:检查层次结构中节点的路径。
- 属性路径:属性的名称。
对于 iquery,只有 (1) 是必需的。如果仅提供 (1)(例如 realm/component),则 iquery 将使用选择器 realm/component:* 提取所有检查数据。
iquery 包含两个实用程序命令,用于了解哪些组件可用以及可以使用哪些选择器:
list:iquery 将输出所有可用的组件选择器,即所有 v2 名字对象和所有带有组件名称的 v1 领域路径。selectors:iquery 将输出所提供选择器位置下的所有可用选择器。
这些模式可以结合使用,如下所示:
iquery show component_name或者,iquery 还允许在某个位置输出检查数据。位置由 .inspect 文件的路径或包含 fuchsia.inspect.Tree 的目录的路径组成。iquery 包含一个实用程序命令,用于列出包含检查数据 (list-files) 的所有文件。
iquery 的辅助操作模式(由 list-files 触发)会以递归方式从给定目录路径中识别 Inspect 数据的位置。这两种模式可以结合使用,如下所示:
iquery list-files [component_moniker] bootstrap/driver_manager class/display-coordinator/000.inspect ... additional outputiquery show --file 'class/display-coordinator/000.inspect'
在上面的示例中,运行 iquery list-files 可查找检查位置列表。然后,对其中一个输出运行 iquery,以递归方式列出匹配位置中的数据。您可以改为编写以下代码:
iquery show component_name档案管理员
Fuchsia 诊断平台由 Archivist 托管,负责按需监控和汇总 Inspect 数据。
在组件管理器下运行时,诊断数据通过事件功能提供给 Archivist。
根领域会向 Archivist 提供事件。因此,它会看到来自整个系统的事件。它允许查看和订阅的事件如下:
- CapabilityRequested:当组件连接到
InspectSink或LogSink时,发送到 Archivist 而不是常规 Directory 连接。这样,Archivist 就可以知道连接到这些协议的组件的名称和网址。
希望公开 Inspect 的组件需要使用 fuchsia.inspect.InspectSink 协议。组件通常会将 diagnostics 字典路由到它们,因此通常如下所示:
{
use: [
{
protocol: "fuchsia.inspect.InspectSink",
from: "parent/diagnostics",
},
],
}
有一个实用的清单包含项可以简化此过程,并且是 Inspect 库所必需的:
{
include: [
"inspect/client.shard.cml",
]
}
如果组件没有路由到它的 diagnostics 字典,并且组件只有路由到它的协议,那么使用它通常如下所示:
{
use: [
{
protocol: "fuchsia.inspect.InspectSink",
from: "parent",
},
],
}
从 Archivist 读取 Inspect
Archivist 托管 fuchsia.diagnostics.ArchiveAccessor,后者提供 StreamDiagnostics 方法,用于从正在运行的组件获取 Inspect 数据。