診斷與監控

在元件內連線至 FIDL 通訊協定是由能力組合而成 轉送和目錄提供這表示診斷連線問題 涵蓋幾個不同的圖層

  • 用戶端在資訊清單中要求通訊協定能力。
  • 提供者會在資訊清單中公開通訊協定能力。
  • 元件拓撲會將能力從供應器轉送至用戶端。
  • 供應商是透過正確的帳號代碼提供通訊協定。
  • 用戶端嘗試連線至正確的通訊協定控制代碼。

本節將介紹一些能協助您找出並修正的 API 和工具 以及監控元件的長期健康狀態 元件。

監控 FIDL 連線

fidlcat 工具可讓你監控要追蹤的 FIDL 連線並進行偵錯 您的元件傳送及接收的個別 FIDL 訊息。類似於 Fuchsia 偵錯工具 (zxdb),fidlcat 會連線至執行中的 debug_agent 元件,並監控執行中的程序。

顯示「fidlcat」方式的圖表會與執行中的 debug_agent 服務互動
,可監控特定程序的 FIDL 呼叫並進行偵錯。

如要設定監控工作階段,您必須完成下列高階步驟:

  1. 在目標裝置上執行 debug_agent 元件。
  2. 執行 fidlcat 用戶端,並連線至目標裝置。

如要啟動 FIDL 偵錯工作階段,最簡單的方法就是使用 ffx debug fidl 指令,上述所有操作都會在您的 Fuchsia 本機版本環境中執行。 不過,如果您需要設定 所以需要分開管理

以下是 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!"
    }

使用檢查功能

元件檢查功能可讓 Fuchsia 元件顯示結構化診斷 對自己的相關資訊 使用 Inspect APIFuchsia 提供這項功能 提供資訊以利診斷 或監控成效

元件會以名為「節點」的樹狀結構顯示檢查指標,每個元件 其中包含一組屬性做為鍵/值組合。屬性支援 各種數值、字串和陣列資料類型。元件檢查器 程式庫會提供元件根節點的介面,您可以在其中 將其他相關屬性附加至應用程式。

顯示元件檢查如何提供結構化指標的樹狀圖
以「節點」樹狀架構的形式儲存資料,每個節點可包含一或多個鍵/值
「properties」

您可以使用 開發人員工具:

  • ffx inspect:可讓您使用 元件選取器在過程中對元件進行偵錯時 。
  • ffx target snapshot:擷取整個偵錯快照封存檔 系統,提供 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 伺服器元件的行為。

啟動模擬器

如果您還沒有執行中的執行個體,請啟動模擬器:

  1. 啟動新的模擬器執行個體:

    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.
    
  2. 啟動套件伺服器,讓模擬器載入軟體套件:

    fx serve
    

監控 FIDL 流量

您可以使用 fidlcat 監控及偵錯應用程式的 FIDL 連線 元件。啟動 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!

啟動 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

請注意事件序列:

  1. 通訊協定實作的管道: svc/fidl.examples.routing.echo.Echo
  2. 伺服器透過開放管道收到 Echo.EchoString 要求, 包含用戶端傳送的字串酬載。
  3. 伺服器傳送含有相同字串酬載的對應回應。
  4. 頻道隨即關閉。

透過追蹤元件之間的 FIDL 連線,fidlcat 可讓您 找出並診斷潛在問題,例如連線失敗或無效問題 資料酬載

新增要求追蹤

元件檢查功能可讓您 協助偵錯您將使用 Inspect API 追蹤 echo 伺服器元件的使用統計資料。

更新 echo_server 要求處理常式以接受包含以下內容的新結構體 numeric 檢查要求數與已處理的位元組的屬性。 處理常式會在每個傳入的要求上遞增下列屬性:

荒漠油廠

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(),以便初始化「檢查屬性」並傳遞 新增到更新的處理常式:

荒漠油廠

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));

  // ...
}

最後,更新匯入項目以納入新的檢查程式庫:

荒漠油廠

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

使用檢查功能發布健康狀態和行為資訊,方便您觀察相關資訊 元件的目前狀態,並在正式版裝置上診斷問題。

刪除執行個體

使用下列指令清除 echo-realm 執行個體:

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

後續步驟

恭喜!您已成功使用 FIDL 建立 Fuchsia IPC 介面。 並透過該介面將兩個元件連接在一起

你已完成本課程中的所有單元!展現全新發現 深入瞭解以下主題:

Fuchsia 概念