本頁說明如何在 Fuchsia 元件的程式碼中加入追蹤功能。
必要條件
開始之前,請確認您已完成下列工作:
在程式碼中使用追蹤巨集
將元件註冊為追蹤記錄提供者後,您就可以在元件的程式碼中加入追蹤記錄。
下列動作通常很實用,只要使用追蹤記錄巨集,就能輕鬆加入程式碼中:
- 追蹤即時事件。
- 設定事件時間。
- 停用追蹤。
- 判斷是否已開啟追蹤功能。
如需所有可用的追蹤巨集清單,請參閱
追蹤即時事件
以下範例會寫入代表單一時間點的即時事件:
荒漠油廠
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_BEGIN
和 TRACE_DURATION_END
巨集,請參閱 TRACE_DURATION_BEGIN
和 TRACE_DURATION_END
。
停用追蹤
在某些情況下,您可能會想要完全停用追蹤功能 (例如,當您準備將元件發布至實際環境時)。如果程式碼中新增了 NTRACE
巨集,追蹤巨集就不會產生任何程式碼。
以下範例 (適用於 C 和 C++) 會顯示 NTRACE
巨集:
#define NTRACE // disable tracing
#include <lib/trace/event.h>
請務必在 #include
陳述式之前定義 NTRACE
巨集。
在下方範例中,rx_count
和 tx_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
由於函式 do_something_expensive()
可能不存在於程式碼的追蹤停用版本中,因此上述範例會同時使用 #ifndef
和 TRACE_ENABLED()
巨集。
如要進一步瞭解 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
由於函式 do_something_expensive()
可能不存在於程式碼的追蹤停用版本中,因此上述範例會同時使用 #ifndef
和 TRACE_ENABLED()
巨集。
如要進一步瞭解 TRACE_ENABLED
巨集,請參閱 TRACE_ENABLED
。
在元件中加入追蹤程式碼後,您現在可以從元件收集追蹤記錄。詳情請參閱下一篇「記錄及顯示追蹤記錄」頁面。