诊断和监控

连接到组件中的 FIDL 协议是一种功能组合。 路由和目录传送这意味着诊断连接问题 涵盖几个不同的层:

  • 客户端在其清单中请求协议功能。
  • 提供程序在其清单中公开了协议功能。
  • 组件拓扑会将功能从提供程序路由到客户端。
  • 提供商使用正确的标识名传送了协议。
  • 客户端尝试连接到正确的协议句柄。

在本部分中,您将探索一些 API 和工具,以帮助您查找和修复 并监控组件的长期运行状况 组件。

监控 FIDL 连接

借助 fidlcat 工具,您可以监控和调试 FIDL 连接以跟踪记录 发送和接收的各个 FIDL 消息。类似于 Fuchsia 调试程序 (zxdb),fidlcat 连接到正在运行的 debug_agent 并监控正在运行的进程

显示“Fibitlcat”的与运行的 debug_agent 服务交互
在 Fuchsia 设备上用于监控和调试给定进程的 FIDL 调用。

设置监控会话需要执行以下高级步骤:

  1. 在目标设备上运行 debug_agent 组件。
  2. 运行 fidlcat 客户端并连接到目标设备。

启动 FIDL 调试会话的最简单方法是使用 ffx debug fidl 命令,该命令将在您的本地 Fuchsia 构建环境中执行所有这些操作。 不过,如果您需要对 Google Kubernetes Engine 。

以下是 FIDL 协议请求的 fidlcat 消息示例。跟踪记录 输出包含每项翻译的有用信息,包括:

  • 组件或进程名称
  • 调用的系统调用
  • FIDL 库、协议和方法名称
  • 包含参数或返回值的消息载荷
echo-client.cm 256109:256122 zx_channel_read(handle:handle: e4c7c57f, options:uint32: 0, num_bytes:uint32: 48, num_handles:uint32: 0)
  -> ZX_OK
    received response fidl.examples.echo/Echo.EchoString = {
      response: string = "hello world!"
    }

使用 Inspect

借助组件检查功能,Fuchsia 组件能够显示结构化诊断信息 使用 Inspect API。Fuchsia 提供了 来协助诊断 或监控性能。

组件以名为 Nodes 的树的形式公开检查指标, 包含一组作为键值对的 Properties。媒体资源支持 各种数字、字符串和数组数据类型。组件检查器 库提供了指向组件根节点的接口,您可以在其中 为您的应用添加感兴趣的其他属性。

显示组件检查如何提供结构化指标的树形图
将数据视为“节点”树其中每个节点可包含一个或多个键值对
“properties”

您可以使用 开发者工具:

  • ffx inspect:可让您使用 组件选择器。这有助于在调试组件 开发。
  • ffx target snapshot:捕获整个 SDK 的调试快照归档 系统,其中包含 JSON 格式的检查数据。
ffx inspect show core/foo-example
core/foo-example:
  metadata:
    filename = fuchsia.inspect.Tree
    component_url = fuchsia-pkg://fuchsia.com/foo-example#meta/foo-example.cm
    timestamp = 55457379176
  payload:
    root:
      version = 1.0
      request_metrics:
        request_count = 3
        error = timeout

练习:监控提供程序组件

在本部分中,您将使用诊断工具来监控 echo 服务器组件的行为。

启动模拟器

如果您尚未运行实例,请通过网络启动 FEMU 支持:

ffx emu start workstation_eng.x64 --headless

监控 FIDL 流量

创建包含服务器和客户端的 echo-realm 的新实例 组件:

ffx component run /core/ffx-laboratory:echo-realm fuchsia-pkg://fuchsiasamples.com/echo-realm#meta/echo_realm.cm

您可以使用 fidlcat 来监控和调试您的 组件。启动 ffx debug fidl 并将其配置为监控 echo 服务器 组件:

ffx debug fidl --remote-name echo_server.cm --fidl-ir-path bazel-out/
Checking for debug agent on [fe80::d6c5:4526:c282:fb6%qemu]:2345.
Debug agent not found. Starting one.
INFO: [main.cc(238)] Connected to symbol server gs://fuchsia-artifacts-release/debug
INFO: [main.cc(122)] Connecting to port 2345 on fe80::d6c5:4526:c282:fb6%qemu...
INFO: [main.cc(92)] Connected!
<ph type="x-smartling-placeholder">

通过启动 echo 客户端实例来启动与服务器的 FIDL 连接:

ffx component start /core/ffx-laboratory:echo-realm/echo_client

客户端绑定到服务器组件,并使用 Echo 进行通信 FIDL 协议。查看 ffx debug fidl 输出以查看 FIDL 列表 echo 服务器处理的事务:

Monitoring echo_server.cm

echo_server.cm 58694:58696 zx_channel_read_etc(handle: handle = fb9b5273, options: uint32 = 0, num_bytes: uint32 = 512, num_handles: uint32 = 4)
  -> ZX_OK
    received request fuchsia.io/Directory.Open = { flags: uint32 = 3, mode: uint32 = 493, path: string = "svc/examples.routing.echo.Echo", object: handle = Channel:f93b597b(ZX_RIGHT_TRANSFER | ZX_RIGHT_READ | ZX_RIGHT_WRITE | ZX_RIGHT_SIGNAL | ZX_RIGHT_SIGNAL_PEER | ZX_RIGHT_WAIT | ZX_RIGHT_INSPECT)(channel:0:svc/examples.routing.echo.Echo) }

echo_server.cm 58694:58696 zx_channel_read_etc(handle: handle = Channel:f93b597b(channel:0:svc/examples.routing.echo.Echo), options: uint32 = 0, num_bytes: uint32 = 512, num_handles: uint32 = 4)
  -> ZX_OK
    received request examples.routing.echo/Echo.EchoString = { value: string = "Hello, Fuchsia" }

echo_server.cm 58694:58696 zx_channel_write_etc(handle: handle = Channel:f93b597b(channel:0:svc/examples.routing.echo.Echo), options: uint32 = 0)
  sent response examples.routing.echo/Echo.EchoString = { response: string = "Hello, Fuchsia" }
  -> ZX_OK

echo_server.cm 58694:58696 zx_channel_read_etc(handle: handle = Channel:f93b597b(channel:0:svc/examples.routing.echo.Echo), options: uint32 = 0, num_bytes: uint32 = 512, num_handles: uint32 = 4)
  -> ZX_ERR_PEER_CLOSED

echo_server.cm 58694:58696 zx_handle_close(handle: handle = Channel:f93b597b(channel:0:svc/examples.routing.echo.Echo))
  -> ZX_OK

请注意事件的顺序:

  1. 该协议实现的渠道位于 svc/examples.routing.echo.Echo
  2. 服务器通过打开的通道收到 Echo.EchoString 请求。 包含客户端发送的字符串载荷。
  3. 服务器会发送具有相同字符串载荷的相应响应。
  4. 通道关闭。

通过跟踪组件之间的 FIDL 连接,fidlcat 可让您 以查找和诊断潜在问题,例如连接失败或 数据载荷。

<ph type="x-smartling-placeholder">

添加请求跟踪

借助组件检查功能,您可以通过 来协助调试您将使用 Inspect API 跟踪某些 echo 服务器组件的使用情况统计信息。

更新 echo_server 请求处理程序以接受包含 数值:检查请求计数和处理的字节数的属性。 处理程序会在每个传入请求上递增这些属性:

echo-server/main.cc

struct EchoConnectionStats {
  inspect::UintProperty bytes_processed;
  inspect::UintProperty total_requests;
};

// Handler for incoming FIDL protocol requests
class EchoImplementation : public fidl::Server<examples_routing_echo::Echo> {
public:
  // The handler for `examples.routing.echo/Echo.EchoString` requests.
  //
  // Replies back to the caller with the original request value.
  void EchoString(EchoStringRequest &request,
                  EchoStringCompleter::Sync &completer) override {
    // Increment connection stats on each request
    stats_->total_requests.Add(1);
    stats_->bytes_processed.Add(request.value()->size());
    completer.Reply({{request.value()}});
  }

  // Called when the FIDL connection is torn down.
  void OnUnbound(fidl::UnbindInfo info,
                 fidl::ServerEnd<examples_routing_echo::Echo> server_end) {
    if (info.is_user_initiated()) {
      return;
    }
    if (info.is_peer_closed()) {
      // The peer (the client) closed their endpoint.
      FX_LOG(DEBUG, "echo_server", "Client disconnected.");
    } else {
      // Treat other unbind causes as errors.
      FX_LOGF(ERROR, "echo_server", "Server error: %s", info.status_string());
    }
  }

  std::unique_ptr<EchoConnectionStats> stats_;
};

将以下代码添加到 main() 以初始化 Inspect 属性,并传递 传递给更新后的处理程序:

echo-server/main.cc

int main(int argc, const char** argv) {
  // ...

  // Serve the Echo protocol
  std::unique_ptr<EchoImplementation> echo_instance =
      std::make_unique<EchoImplementation>();

  // Create request tracking properties
  inspect::Node &root_node = inspector.root();
  auto total_requests = root_node.CreateUint("total_requests", 0);
  auto bytes_processed = root_node.CreateUint("bytes_processed", 0);
  echo_instance->stats_ =
      std::make_unique<EchoConnectionStats>(EchoConnectionStats{
          std::move(bytes_processed),
          std::move(total_requests),
      }); 

  // ...
}
<ph type="x-smartling-placeholder">

最后,更新导入文件以包含新的 Inspect 库:

echo-server/main.cc

#include <fidl/examples.routing.echo/cpp/fidl.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/component/outgoing/cpp/outgoing_directory.h>
#include <lib/inspect/component/cpp/component.h>
#include <lib/syslog/global.h>

构建更新后的软件包并将其发布到 fuchsiasamples.com 代码库:

bazel run //fuchsia-codelab/echo-realm:pkg.publish -- \
    --repo_name fuchsiasamples.com

验证检查数据

创建一个包含更新后的 echo-server 的新 echo-realm 组件:

ffx component run /core/ffx-laboratory:echo-realm fuchsia-pkg://fuchsiasamples.com/echo-realm#meta/echo_realm.cm \
    --recreate

多次运行 echo 客户端组件。这会导致 echo-server

ffx component start /core/ffx-laboratory:echo-realm/echo_client
ffx component start /core/ffx-laboratory:echo-realm/echo_client
ffx component start /core/ffx-laboratory:echo-realm/echo_client

使用以下命令查看 echo 服务器组件的可用检查数据: ffx inspect。您将在 root 节点下的树以及组件的运行状况:

ffx inspect show 'core/ffx-laboratory\:echo-realm/echo_server'
core/ffx-laboratory\:echo-realm/echo_server:
  metadata:
    filename = fuchsia.inspect.Tree
    component_url = #meta/echo_server.cm
    timestamp = 1476246046122
  payload:
    root:
      bytes_processed = 42
      total_requests = 3
      fuchsia.inspect.Health:
        start_timestamp_nanos = 1467828507317
        status = OK

通过使用“检查”功能发布健康状况和行为信息, 了解组件的当前状态,并诊断正式版设备上的问题。

<ph type="x-smartling-placeholder">

销毁实例

使用以下命令清理 echo-realm 实例:

ffx component destroy /core/ffx-laboratory:echo-realm

后续操作

恭喜!您已经使用 FIDL 成功构建了 Fuchsia IPC 接口, 并通过该接口将两个组件连接在一起。

您已完成本课程中的所有单元!带走您新发现的东西 进一步加深对我们的了解并深入了解:

Fuchsia 概念