Fuchsia 组件检查概览

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

不知道从何处入手?

概念

组件可能会公开一个 Node 树,每个节点都有一组 Property

图:节点树

节点

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

图:一个节点

属性

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

数值类型

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

字符串类型

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

数组类型

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

直方图类型

  • LinearUintHistogramLinearIntHistogramLinearDoubleHistogram

以数组形式存储的具有固定大小区间的直方图。

  • ExponentialUintHistogramExponentialIntHistogramExponentialDoubleHistogram

一种以指数级大小的分桶存储在数组中的直方图。

检查文件格式

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

文件系统接口

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

语言库

C++

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

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

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

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

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

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

阅读支持

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

HierarchyNodeValuenode() 返回,子 Hierarchychildren() 以向量形式返回。GetByPath 函数支持按路径读取特定的子层次结构。

特定 NodeValue 的属性可通过 properties() 访问器获取。您可以通过将相应的 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 函数,用于处理从组件公开单个层次结构的常见用法。

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

测试模块支持 assert_data_tree! 宏,以匹配用于测试的检查数据。

测试

验证器架构介绍了 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

只要这是系统中唯一一个网址以 archivist.cm 结尾的公开检查功能的组件,此命令就会输出所有 bootstrap/archivist 的检查结果。

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

一般来说,此命令接受以下内容:

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

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

  • 组件选择器,例如 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