在程式碼中加入追蹤記錄

本頁說明如何在 Fuchsia 元件的程式碼中新增追蹤功能。

必要條件

開始之前,請先完成下列工作:

此外,請務必在程式碼中使用相關程式庫:

C

#include <lib/trace/event.h>

C++

#include <lib/trace/event.h>

荒漠油廠

use fuchsia_trace::{ArgValue, Scope, ...};

在程式碼中使用追蹤巨集

將元件註冊為追蹤記錄供應器後,即可在元件的程式碼中新增追蹤記錄。

下列動作通常很有用,而且可以使用追蹤巨集輕鬆在程式碼中新增:

如需所有可用追蹤巨集的清單,請參閱

追蹤即時事件

以下範例會寫入代表單一時間點的即時事件:

荒漠油廠

fuchsia_trace::instant!(c"helloworld", c"hello_world_test", fuchsia_trace::Scope::Process, "message" => "Hello, World!");

這個範例指定了 helloworld 類別、hello_world_test 名稱、TRACE_SCOPE_PROCESS 範圍,以及鍵/值配對。

如要進一步瞭解 instant! 巨集,請參閱 instant!

C++

TRACE_INSTANT("helloworld", "hello_world_test", TRACE_SCOPE_PROCESS, "message", "Hello, World!");

這個範例指定了 helloworld 類別、hello_world_test 名稱、TRACE_SCOPE_PROCESS 範圍,以及鍵/值配對。

如要進一步瞭解 TRACE_INSTANT 巨集,請參閱 TRACE_INSTANT

C

TRACE_INSTANT("helloworld", "hello_world_test", TRACE_SCOPE_PROCESS, "message", TA_STRING("Hello, World!"));

這個範例指定了 helloworld 類別、hello_world_test 名稱、TRACE_SCOPE_PROCESS 範圍,以及鍵/值配對。

如要進一步瞭解 TRACE_INSTANT 巨集,請參閱 TRACE_INSTANT

安排活動時間

這個範例說明如何為函式或程序計時:

荒漠油廠

fn InitCompressed() {
    fuchsia_trace::duration!(c"helloworld", c"hello_world_test", fuchsia_trace::Scope::Process, "message" => "Hello, World!");
    ...
    // Duration ends due to RAII
}

這個範例會記錄建構函式中耗費的時間長度,以及區塊的大小和數量。

如要進一步瞭解 duration! 巨集,請參閱 duration!

C++

zx_status_t VnodeBlob::InitCompressed() {
    TRACE_DURATION("blobfs", "Blobfs::InitCompressed", "size", inode_.blob_size,
                   "blocks", inode_.num_blocks);
    ...
    // Duration ends due to RAII
}

這個範例會記錄建構函式中耗費的時間長度,以及區塊的大小和數量。由於這是 C++ 範例,編譯器可以推斷資料型別。

如要進一步瞭解 TRACE_DURATION 巨集,請參閱 TRACE_DURATION

C

zx_status_t VnodeBlob_InitCompressed(inode_t inode) {
    TRACE_DURATION_BEGIN("blobfs", "Blobfs_InitCompressed", "size", inode.blob_size, "blocks",
    inode.num_blocks);
    ...
    TRACE_DURATION_END("blobfs", "Blobfs_InitCompressed");
}

這個範例會記錄建構函式中耗費的時間長度,以及區塊的大小和數量。

如要進一步瞭解 TRACE_DURATION_BEGINTRACE_DURATION_END 巨集,請參閱TRACE_DURATION_BEGINTRACE_DURATION_END

停用追蹤

在某些情況下,您可能會想完全停用追蹤功能 (例如即將將元件發布至正式環境時)。如果程式碼中已加入 NTRACE 巨集,追蹤巨集就不會產生任何程式碼。

以下範例 (適用於 C 和 C++) 顯示 NTRACE 巨集:

#define NTRACE  // disable tracing
#include <lib/trace/event.h>

請務必在 #include 陳述式之前定義 NTRACE 巨集。

在下方範例中,rx_counttx_count 欄位只會用於追蹤,因此如果斷言 NTRACE (表示追蹤功能已停用),這些欄位就不會佔用 my_statistics_t 結構中的空間。

typedef struct {
#ifndef NTRACE  // reads as "if tracing is not disabled"
    uint64_t    rx_count;
    uint64_t    tx_count;
#endif
    uint64_t    npackets;
} my_statistics_t;

不過,如果確實需要有條件地編譯程式碼來管理統計資料記錄作業,可以使用 TRACE_INSTANT 巨集:

#ifndef NTRACE
    status.tx_count++;
    TRACE_INSTANT("bandwidth", "txpackets", TRACE_SCOPE_PROCESS,
                  "count", TA_UINT64(status.tx_count));
#endif  // NTRACE

如要進一步瞭解 NTRACE 巨集,請參閱 NTRACE

判斷追蹤功能是否已開啟

在某些情況下,您可能需要在執行階段判斷追蹤是否開啟。

荒漠油廠

if fuchsia_trace::is_enabled() {
  let v = do_something_expensive();
  fuchsia_trace::instant!(...
}

如果追蹤功能已停用,Rust 追蹤繫結就不支援編譯時間檢查。 不過,如果在編譯時停用追蹤功能,檢查 is_enabled 不會耗用大量效能。

如要進一步瞭解 is_enabled,請參閱is_enabled

C++

如果程式碼中編譯了追蹤功能 (因為未定義 NTRACE),TRACE_ENABLED() 巨集會判斷追蹤供應商的追蹤功能是否已開啟。如果追蹤功能已編譯完成,TRACE_ENABLED() 一律會傳回 false。

#ifndef NTRACE
    if (TRACE_ENABLED()) {
        int v = do_something_expensive();
        TRACE_INSTANT(...
    }
#endif  // NTRACE

上述範例同時使用 #ifndefTRACE_ENABLED() 巨集,因為 do_something_expensive() 函式可能不存在於停用追蹤功能的程式碼版本中。

如要進一步瞭解 TRACE_ENABLED 巨集,請參閱 TRACE_ENABLED

C

如果程式碼中編譯了追蹤功能 (因為未定義 NTRACE),TRACE_ENABLED() 巨集會判斷追蹤供應商的追蹤功能是否已開啟。如果追蹤功能已編譯完成,TRACE_ENABLED() 一律會傳回 false。

#ifndef NTRACE
    if (TRACE_ENABLED()) {
        int v = do_something_expensive();
        TRACE_INSTANT(...
    }
#endif  // NTRACE

上述範例同時使用 #ifndefTRACE_ENABLED() 巨集,因為 do_something_expensive() 函式可能不存在於停用追蹤功能的程式碼版本中。

如要進一步瞭解 TRACE_ENABLED 巨集,請參閱 TRACE_ENABLED

將追蹤程式碼新增至元件後,您現在可以從元件收集追蹤記錄。詳情請參閱下一節「記錄及顯示追蹤記錄」頁面。