本頁說明如何在 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_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
上述範例同時使用 #ifndef
和 TRACE_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
上述範例同時使用 #ifndef
和 TRACE_ENABLED()
巨集,因為 do_something_expensive()
函式可能不存在於停用追蹤功能的程式碼版本中。
如要進一步瞭解 TRACE_ENABLED
巨集,請參閱 TRACE_ENABLED
。
將追蹤程式碼新增至元件後,您現在可以從元件收集追蹤記錄。詳情請參閱下一節「記錄及顯示追蹤記錄」頁面。