Fuchsia 组件检查概览

Fuchsia 中的组件可能会公开符合 Inspect API 的自身结构化信息。本文档介绍了组件检查、接口、接口的 C++ 语言实现以及用于与公开信息的组件交互的面向用户的工具的概念。

不知道从何处入手?

概念

组件可以公开一棵节点树,每个节点都有一组属性

图:节点树

节点

节点是组件中的一个导出实体,可能有 0 个或更多子项。每个节点都有一个名称,并且节点的每个子节点在子节点中都必须具有唯一的名称。

图:节点

属性

节点可以有任意数量的属性。属性具有字符串键和值,值可以是多种类型中的任意一种:

数字类型

  • UintProperty - 64 位无符号整数。
  • IntProperty - 64 位有符号整数。
  • DoubleProperty - 64 位浮点值。
  • BoolProperty - 布尔值。

字符串类型

  • StringProperty - UTF-8 字符串。
  • ByteVectorProperty - 字节矢量。

数组类型

  • UintArrayIntArrayDoubleArray - 相应数字类型的数组。

直方图类型

  • LinearUintHistogramLinearIntHistogramLinearDoubleHistogram

存储在数组中的固定大小分桶的直方图。

  • ExponentialUintHistogramExponentialIntHistogramExponentialDoubleHistogram

存储在数组中的大小呈指数级增长的分桶的直方图。

检查文件格式

Inspect 文件格式是一种二进制格式,支持在运行时高效插入、修改和删除节点和属性。读者可以获取内容的一致快照,而无需与写入器通信。

文件系统接口

顶级节点在组件的传出目录中以扩展名 .inspect 结尾的 VmoFile 的形式公开。通常,组件会将其主要树或根树公开为 out/diagnostics/root.inspect

语言库

C++

C++ Inspect 库为 Inspect 文件格式提供完整的写入读取支持。

写入检查数据的组件应避免读取这些数据。读取需要遍历整个缓冲区,这非常耗时。

Inspector 类提供了一个封装容器,用于创建一个包含一个可添加的根节点的新缓冲区。节点和属性具有类型化的封装容器,当它们超出范围时,会自动从缓冲区中删除底层数据。

inspect_component 库提供了一个简单的 ComponentInspector 单例接口,可帮助处理从组件中公开单个层次结构的常见情况。

health 功能支持以健康检查工具所知的格式公开结构化健康信息。

测试匹配器库提供了 GMock 匹配器,用于验证测试中从 Inspect 层次结构读取的数据。

阅读支持

读取库支持将检查文件解析为层次结构Hierarchy 包含 NodeValuePropertyValues,它们分别是 NodeProperty 的解析版本。

node() 会返回 HierarchyNodeValuechildren() 会以向量的形式返回子 HierarchyGetByPath 函数支持按路径读取特定的子层次结构。

您可以通过 properties() 访问器获取特定 NodeValue 的属性。您可以通过将相应的 PropertyValue 类型作为模板参数传递给 Contains<T>() 方法,来确定某个属性是否包含特定类型:

  // Returns true if the first property of the hierarchy's node is an INT value.
  if (hierarchy.node().properties()[0].Contains<IntPropertyValue>()) {
    // ...
  }

使用 Get<T>() 方法获取该属性:

  // Get the IntPropertyValue of the first property on the node.
  // Note: This causes a runtime exception if the property does not contain
  // the given type, crashing the program.
  hierarchy.node().properties()[0].Get<IntPropertyValue>();

您还可以根据不同的可能格式类型进行切换:

  const auto& property = hierarchy.node().properties()[0];
  switch (property.format()) {
    case FormatType::INT:
      const auto& value = property.Get<IntPropertyValue>();
      /* ... */
      break;
    /* ... */
  }

数组类型可以采用特殊格式,以包含直方图。GetBuckets() 方法支持从 {Int,Uint,Double}ArrayValue 类型返回直方图分桶数组。如果底层数组不是采用特殊格式的直方图,则该数组将为空。

Rust

Rust Inspect 库为 Inspect 文件格式提供完整的写入读取支持。

写入检查数据的组件应避免读取这些数据。读取需要遍历整个缓冲区,这非常耗时。

Inspector 类提供了一个封装容器,用于创建一个包含一个可添加的根节点的新缓冲区。节点和属性具有类型化的封装容器,当它们超出范围时,会自动从缓冲区中删除底层数据。

component 模块支持一个简单的 inspector 函数,用于处理从组件中公开单个层次结构的常见用法。

health 模块支持以健康检查工具所知的格式公开结构化健康信息。

testing 模块支持 assert_data_tree! 宏,以匹配要测试的 Inspect 数据。

测试

验证器架构介绍了 Inspect 语言库的集成测试框架。

用户空间工具

ffx inspect

如需检查组件的检查层次结构,您可以使用 ffx inspect show 命令:

  • 输出所有检查层次结构:

    ffx inspect show
  • 输出特定组件(例如 core/font_provider)的检查层次结构:

    ffx inspect show core/font_provider

ffx inspect show 还会对其输入进行模糊匹配。例如:

ffx inspect show archivist.cm

这会输出 bootstrap/archivist 的所有 Inspect,前提是它是系统中唯一公开 Inspect 且网址以 archivist.cm 结尾的组件。

如果输入信息不够具体,无法识别单个组件,模糊匹配将会失败;在这种情况下,该工具会输出与查询匹配的标识名列表。

一般来说,此命令接受以下参数:

  • 组件标识名,例如 core/network/netstack。如果仅传递标识名,则无需转义集合标记,但也可以选择转义。

  • 模糊搜索参数,对应于网址片段、清单片段或别名片段。例如,ffx inspect show archivist.cm 对应清单 archivist.cm 中的 bootstrap/archivist

  • 组件选择器,例如 core/network/*

  • 完整的诊断选择器,例如 core/network/netstack:root/path/to/*:property。在完整选择器的情况下,必须执行转义才能创建有效的选择器。

假设您有一个组件 bootstrap/driver-hosts:driver-host-337。当您需要特定属性时,为了尽可能避免转义,可以采用符合人体工学的方式,如下所示:

ffx inspect driver-host-337 --data root/stats:my_stat

ffx 目标快照

ffx target snapshot 会生成一个 ZIP 归档文件,其中包含系统的诊断信息,包括以下内容:

ffx target snapshot