您可以使用追蹤功能記錄系統上的事件和計數器,並在時間軸上顯示每個項目。Android 的標準追蹤工具是 Perfetto。如要瞭解詳情,請參閱「追蹤 101」。
檢測程式碼
如要從應用程式取得事件,必須在程式碼中加入追蹤點,才能進行檢測。未經過插碼的區段不會顯示在追蹤記錄中。
SDV 追蹤範例是追蹤整合的試用版,內含操作說明和追蹤設定範例。位於 system/software_defined_vehicle/core_services/samples/tracing/。
Rust
建議您使用 Rust 的 tracing Crate 發出 ATrace 事件。Perfetto 支援 ATrace 做為資料來源。我們計畫在 Rust 繫結推出後,視用途演變情況改用 Perfetto SDK。
將追蹤預設值新增至 Android.bp:
rust_binary {
...
defaults: [
...
"sdv_tracing@rust_defaults",
],
...
}
初始化訂閱者。每個程序只能執行一次這項操作:
fn main() {
// Initialize the subscriber, panic if it fails.
// sdv_tracing::try_init_tracing() is the version that returns a Result.
sdv_tracing::init_tracing()
...
}
您可以省略初始化呼叫。這麼做會讓追蹤作業處於未初始化狀態,且 Perfetto 不會從應用程式收集插碼事件。
新增追蹤點。如需更多範例,請參閱 system/software_defined_vehicle/core_services/samples/tracing/rust_tracing_api_demo/tracing.rs。
use tracing::{instrument, info_span};
// #[tracing::instrument] wraps the method into a tracing span and records arguments.
// Use #[instrument(skip(num))] if you don't want to record the argument.
#[instrument]
fn mul_by_100(num: i32) -> i32 {
// Create and enter a span with INFO verbosity, name, and a debug field annotation.
// The span will exit when dropped.
let _span = info_span!("This is a span", var=123).entered();
let result = num * 100;
// Emit an instant INFO event that records the result value.
// We recommend to fully qualify the crate when using events to avoid confusion with log records.
tracing::info!(result, "Completed");
result
}
C++
C++ 追蹤功能會使用 Perfetto SDK 追蹤事件。請將追蹤預設值新增至 Android.bp:
cc_binary {
...
defaults: [
...
"sdv_tracing@cc_defaults",
],
...
}
定義類別。如果您在多個模組中使用類別,請將這些類別移至通用程式庫。例如 system/software_defined_vehicle/core_services/samples/tracing/cpp_service/tracing_categories.h。
在標頭中:
#include "perfetto/tracing/tracing.h"
#include "perfetto/tracing/track_event.h"
PERFETTO_DEFINE_CATEGORIES(
perfetto::Category("sample")
.SetTags("tag")
.SetDescription("Sample events"));
將靜態儲存空間巨集放在方法以外的 .cpp 來源檔案中。如要在元件之間共用類別,請使用與含有類別的標頭對應的來源檔案。
PERFETTO_TRACK_EVENT_STATIC_STORAGE();
int main() {
...
}
如要初始化 Perfetto,請初始化系統後端並註冊軌跡事件:
#include <sdv/tracing_init.h>
int main() {
...
android::sdv::InitPerfettoWithTrackEvents<perfetto::TrackEvent>();
...
}
新增檢測點。如需更多範例,請參閱 system/software_defined_vehicle/core_services/samples/tracing/cpp_service/client.cpp。
int32_t mulBy100(int32_t num) {
// Start a slice that will get closed at the end of the scope.
TRACE_EVENT("client", "mulBy100", "num", num);
TRACE_EVENT("client", "This is a slice", "var", 123);
int32_t result = num * 100;
// Instant events have zero duration. They are drawn as markers on the track.
TRACE_EVENT_INSTANT("client", "Completed", "result", result);
return result;
}
如同 Rust 範例,這段程式碼會產生兩個巢狀切片,以及 UI 中即時事件的標記。選取事件時,系統會顯示偵錯引數值。
收集追蹤記錄
使用 record\_android\_trace 指令列指令碼記錄追蹤記錄,並使用 Perfetto 網頁 UI 查看。
設定擷取作業
您需要以 textproto 格式提供 record_android_trace 的設定。詳情請參閱 Perfetto 文件。
SDV 存放區包含範例設定 (system/software_defined_vehicle/core_services/samples/tracing/config/trace_cfg.pbtx)。這個檔案包含多個資料來源,可自訂或直接使用。
使用 Perfetto UI 產生設定
您可以前往 Perfetto UI 中的「Record new trace」(記錄新追蹤記錄),調整記錄設定和探針,設定自訂設定並探索可用選項。接著開啟「Recording command」(錄音指令) 檢視畫面,查看產生的指令,並從中取得設定內容。
設定應用程式內檢測功能的可見度
Rust 檢測會使用 ATrace。這項功能是在文件的 ftrace_config 區段中設定。SDV 元件具有 ATRACE_TAG_APP 標記,且可針對每個應用程式啟用。範例設定會啟用所有應用程式。
data_sources: {
config {
name: "linux.ftrace"
ftrace_config {
# Setting atrace_apps to "*" enable ATrace events for all apps.
# You can set it to a pattern to match specific processes by name.
# Use multiple atrace_apps entries to enable multiple processes.
atrace_apps: "*"
}
}
}
我們在 C++ Perfetto SDK 中使用追蹤事件。這是
track_event 資料來源
(文件)。
您可以在 track_event_config 欄位中啟用或停用類別和標記。除了特殊 slow 和 debug 標記之外,系統預設會啟用每個類別的結尾標記。如果只想啟用特定類別,請停用所有其他類別,例如使用 disabled_categories: "*",如下所示:
data_sources: {
config {
name: "track_event"
track_event_config {
enabled_categories: "the_best_category_in_the_world"
disabled_categories: "*"
}
}
}錄製追蹤記錄
在 Android 存放區根目錄中開啟終端機。不需要執行 envsetup。錄製指令碼位於 external/perfetto/tools/record_android_trace 中。
使用範例設定執行指令碼:
external/perfetto/tools/record_android_trace --config system/software_defined_vehicle/core_services/samples/tracing/config/trace_cfg.pbtx
如要提早停止錄製,請選取 Ctrl + C。
這麼做會觸發 adb shell perfetto 記錄追蹤記錄,然後將追蹤記錄提取到主機,通常位於 ~/traces。收集追蹤記錄後,工具會開啟瀏覽器視窗,顯示追蹤記錄。
實用引數:
-s SERIAL,即可使用特定序號的裝置。 例如-s 0.0.0.0:6520--no-open-browser會建立用於提供追蹤記錄的網址,但不會開啟瀏覽器。如果您已設定通訊埠轉送 (通常是 9001),這項功能在遠端工作階段中會很有用。-n, --no-open不會在追蹤工作階段後開啟瀏覽器或建立網址來提供追蹤記錄。您還是可以點選「Open trace file」並選取檔案,在 Perfetto UI 中開啟檔案。-o <path>設定輸出路徑。
使用規則詳細說明
本節提供使用追蹤系統時可能有所助益的詳細資料。
SDV 元件中的追蹤檢測
在具有追蹤檢測的代理程式中,除非另有指定,否則追蹤功能預設會在可進行偵錯的版本 (-eng、-userdebug) 中啟用。收集追蹤記錄時,您應該會看到程序的事件,不需要額外設定。
程式庫通常不會自動初始化追蹤功能。在 Rust 中,使用程式庫的二進位檔需要使用 sdv_tracing::init_tracing() 初始化程序的追蹤記錄。詳情請參閱「檢測程式碼」。
中介軟體
發布/訂閱程式庫:libsdv_middleware_dt
活動:
- 發布者:發布及註冊主題。
- 訂閱者:訂閱及進行意見調查。
啟用:在二進位檔中呼叫 sdv_tracing::init_tracing() 或 sdv_tracing::try_init_tracing()。
gRPC 程式庫:libsdvmiddleware_rpc_grpc_transport
活動:
- RPC 用戶端:啟動、連線至伺服器,以及 RPC 方法呼叫。
- RPC 伺服器:啟動、向 Service Discovery 註冊、新增及呼叫 RPC 方法。
啟用:在二進位檔中呼叫 sdv_tracing::init_tracing() 或 sdv_tracing::try_init_tracing()。
SOME/IP
- 程序:
sdv_someip_broker_agent。\ - 事件:訊息處理和翻譯、事件訂閱。
生命週期管理工具
- 程序:
sdv_lifecycle_agent。\ - 事件:服務作業 - 啟動、停止、註冊、取消註冊。
車輛動力模式
- 程序:
sdv_vpm_agent。\ - 事件:電源狀態變更和訂閱。
資料通道
我們預計在日後支援追蹤整合。
追蹤的效能負擔
照常提醒,不同系統的負荷測量結果可能有所差異,模擬器和實際硬體之間的差異尤其明顯。
Rust
原始基準資料可在 AOSP 中取得。這些資料是在 Cuttlefish VM 上收集。
- 單一跨度:
tracing::info_span!()、#[tracing::instrument]和類似項目:- 追蹤未初始化:1 奈秒。
- 追蹤已初始化並停用 (未錄製任何追蹤記錄):30 奈秒。
- 已啟用追蹤:3 微秒。偵錯欄位註解可能會增加 1 到 2 微秒,視字串化複雜度而定。
- 單一事件:
tracing::info!()和類似事件:- 追蹤未初始化:1 奈秒。
- 追蹤功能已初始化並停用:30 奈秒。
- 已啟用追蹤:1.5 微秒。視
stringification複雜度而定,偵錯欄位註解可能會增加 0.5 到 1 微秒。
C++
效能數字來自 Perfetto 的「追蹤事件」文件效能部分。表中的 Pixel 3 時間與我們在 Cuttlefish VM 上的觀察結果一致。
單一配量:TRACE_EVENT() 和類似項目。追蹤:
- 已停用:2 秒。
- 已啟用:300 奈秒。使用偵錯欄位註解可能會增加 50 到 100 奈秒。