连接到组件中的 FIDL 协议是一种功能组合。 路由和目录传送这意味着诊断连接问题 涵盖几个不同的层:
- 客户端在其清单中请求协议功能。
- 提供程序在其清单中公开了协议功能。
- 组件拓扑会将功能从提供程序路由到客户端。
- 提供商使用正确的标识名传送了协议。
- 客户端尝试连接到正确的协议句柄。
在本部分中,您将探索一些 API 和工具,以帮助您查找和修复 组件连接的问题,并监控您的 组件。
监控 FIDL 连接
借助 fidlcat
工具,您可以监控和调试 FIDL 连接以跟踪记录
发送和接收的各个 FIDL 消息。类似于
Fuchsia 调试程序 (zxdb
),fidlcat
连接到正在运行的 debug_agent
并监控正在运行的进程
设置监控会话需要执行以下高级步骤:
- 在目标设备上运行
debug_agent
组件。 - 运行
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。媒体资源支持 各种数字、字符串和数组数据类型。组件检查器 库提供了指向组件根节点的接口,您可以在其中 为您的应用添加感兴趣的其他属性。
您可以使用 开发者工具:
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 服务器组件的行为。
启动模拟器
如果您尚未运行实例,请启动模拟器:
启动新的模拟器实例:
ffx emu start --headless
启动完成后,模拟器将输出以下消息和 返回:
Logging to "$HOME/.local/share/Fuchsia/ffx/emu/instances/fuchsia-emulator/emulator.log" Waiting for Fuchsia to start (up to 60 seconds)........ Emulator is ready.
启动软件包服务器,使模拟器能够加载软件包:
fx serve
监控 FIDL 流量
您可以使用 fidlcat
来监控和调试您的
组件。启动 ffx debug fidl
并将其配置为监控 echo 服务器
组件:
ffx debug fidl --remote-name echo_server.cm
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/fidl.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/fidl.examples.routing.echo.Echo) }
echo_server.cm 58694:58696 zx_channel_read_etc(handle: handle = Channel:f93b597b(channel:0:svc/fidl.examples.routing.echo.Echo), options: uint32 = 0, num_bytes: uint32 = 512, num_handles: uint32 = 4)
-> ZX_OK
received request fidl.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/fidl.examples.routing.echo.Echo), options: uint32 = 0)
sent response fidl.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/fidl.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/fidl.examples.routing.echo.Echo))
-> ZX_OK
请注意事件的顺序:
- 该协议实现的渠道位于
svc/fidl.examples.routing.echo.Echo
。 - 服务器通过打开的通道收到
Echo.EchoString
请求。 包含客户端发送的字符串载荷。 - 服务器会发送具有相同字符串载荷的相应响应。
- 通道关闭。
通过 fidlcat
,您可以跟踪组件之间的 FIDL 连接,
来查找和诊断潜在问题,例如连接失败或
数据载荷。
添加请求跟踪
借助组件检查功能,您可以通过 来协助调试您将使用 Inspect API 跟踪某些 echo 服务器组件的使用情况统计信息。
更新 echo_server
请求处理程序以接受包含
数值:检查请求计数和处理的字节数的属性。
处理程序会在每个传入请求上递增这些属性:
Rust
echo-server/src/main.rs
:
// Inspect properties managed by the server
struct EchoConnectionStats {
total_requests: fuchsia_inspect::UintProperty,
bytes_processed: fuchsia_inspect::UintProperty,
}
// Handler for incoming service requests
async fn handle_echo_request(mut stream: EchoRequestStream, stats: &EchoConnectionStats) {
while let Some(event) = stream.try_next().await.expect("failed to serve echo service") {
let EchoRequest::EchoString { value, responder } = event;
responder.send(value.as_ref().map(|s| &**s)).expect("failed to send echo response");
if let Some(message) = value {
// Update Inspect property values
stats.total_requests.add(1);
stats.bytes_processed.add(message.len() as u64);
}
}
}
C++
echo-server/main.cc
:
struct EchoConnectionStats {
inspect::UintProperty bytes_processed;
inspect::UintProperty total_requests;
};
// Handler for incoming service requests
class EchoImplementation : public fidl::examples::routing::echo::Echo {
public:
void EchoString(fidl::StringPtr value, EchoStringCallback callback) override {
stats_->total_requests.Add(1);
stats_->bytes_processed.Add(value->size());
callback(std::move(value));
}
fidl::examples::routing::echo::Echo_EventSender* event_sender_;
std::unique_ptr<EchoConnectionStats> stats_;
};
将以下代码添加到 main()
以初始化 Inspect 属性,并传递
传递给更新后的处理程序:
Rust
echo-server/src/main.rs
:
async fn main() -> Result<(), anyhow::Error> {
// ...
// Component is serving and ready to handle incoming requests
component::health().set_ok();
// Create request tracking properties
let root_node = component::inspector().root();
let stats = EchoConnectionStats {
total_requests: root_node.create_uint("total_requests", 0),
bytes_processed: root_node.create_uint("bytes_processed", 0),
};
// Attach request handler for incoming requests
service_fs
.for_each_concurrent(None, |request: IncomingRequest| async {
match request {
IncomingRequest::Echo(stream) => handle_echo_request(stream, &stats).await,
}
})
.await;
Ok(())
}
C++
echo-server/main.cc
:
int main(int argc, const char** argv) {
// ...
// Serve the Echo protocol
EchoImplementation echo_instance;
fidl::Binding<fidl::examples::routing::echo::Echo> binding(&echo_instance);
echo_instance.event_sender_ = &binding.events();
// 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),
});
fidl::InterfaceRequestHandler<fidl::examples::routing::echo::Echo> handler =
[&](fidl::InterfaceRequest<fidl::examples::routing::echo::Echo> request) {
binding.Bind(std::move(request));
};
context->outgoing()->AddPublicService(std::move(handler));
// ...
}
最后,更新导入文件以包含新的 Inspect 库:
Rust
echo-server/src/main.rs
:
use anyhow::{self, Context};
use fidl_fidl_examples_routing_echo::{EchoRequest, EchoRequestStream};
use fuchsia_component::server::ServiceFs;
use fuchsia_inspect::{component, health::Reporter};
use fuchsia_inspect::NumericProperty;
use futures::prelude::*;
C++
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/fidl/cpp/binding.h>
#include <lib/inspect/cpp/inspect.h>
#include <lib/sys/cpp/component_context.h>
#include <lib/inspect/component/cpp/component.h>
再次运行 fx build
以重新构建组件:
fx build
验证检查数据
停止当前的 echo-server
组件实例。这样,该组件就可以
下次启动时从软件包服务器解析最新版本。
ffx component stop /core/ffx-laboratory:echo-realm/echo_server
多次运行 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 接口, 并通过该接口将两个组件连接在一起。
您已完成本课程中的所有单元!带走您新发现的东西 进一步加深对我们的了解并深入了解: