Użyj śledzenia, aby rejestrować zdarzenia i liczniki w systemie oraz wizualizować je na osi czasu. Standardowym narzędziem do śledzenia w Androidzie jest Perfetto. Więcej informacji znajdziesz w artykule Śledzenie – podstawy.
Instrumentacja kodu
Aby otrzymywać zdarzenia z aplikacji, musisz dodać do kodu punkty śledzenia. Sekcje, które nie są instrumentowane, nie będą widoczne w logach czasu.
Przykładowy log czasu SDV to demonstracja integracji śledzenia, która zawiera instrukcje i przykład konfiguracji śledzenia. Znajduje się on w system/software_defined_vehicle/core_services/samples/tracing/.
Rdza
W przypadku języka Rust zalecamy używanie pakietu tracing do emitowania zdarzeń ATrace. Perfetto obsługuje ATrace jako źródło danych. Planujemy przejść na pakiet SDK Perfetto, gdy będą dostępne powiązania z językiem Rust, i w zależności od tego, jak będą się rozwijać przypadki użycia.
Dodaj domyślne ustawienia śledzenia do pliku Android.bp:
rust_binary {
...
defaults: [
...
"sdv_tracing@rust_defaults",
],
...
}
Zainicjuj subskrybenta. Możesz to zrobić tylko raz na proces:
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()
...
}
Możesz pominąć wywołanie inicjujące. Spowoduje to, że śledzenie nie zostanie zainicjowane, a Perfetto nie będzie zbierać zdarzeń instrumentacji z aplikacji.
Dodaj punkty śledzenia. Więcej przykładów znajdziesz w 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++
Śledzenie w C++ używa pakietu SDK Perfetto do śledzenia zdarzeń. Dodaj domyślne ustawienia śledzenia do pliku Android.bp:
cc_binary {
...
defaults: [
...
"sdv_tracing@cc_defaults",
],
...
}
Zdefiniuj kategorie. Jeśli używasz kategorii w wielu modułach, przenieś je do wspólnej biblioteki. Na przykład system/software_defined_vehicle/core_services/samples/tracing/cpp_service/tracing_categories.h.
W nagłówku:
#include "perfetto/tracing/tracing.h"
#include "perfetto/tracing/track_event.h"
PERFETTO_DEFINE_CATEGORIES(
perfetto::Category("sample")
.SetTags("tag")
.SetDescription("Sample events"));
Umieść makro statycznej pamięci masowej w pliku źródłowym .cpp, a nie w metodzie. Jeśli udostępniasz kategorie między komponentami, użyj pliku źródłowego odpowiadającego nagłówkowi z kategoriami.
PERFETTO_TRACK_EVENT_STATIC_STORAGE();
int main() {
...
}
Aby zainicjować Perfetto, zainicjuj backend systemu i zarejestruj zdarzenia śledzenia:
#include <sdv/tracing_init.h>
int main() {
...
android::sdv::InitPerfettoWithTrackEvents<perfetto::TrackEvent>();
...
}
Dodaj instrumentację. Więcej przykładów znajdziesz w 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;
}
Podobnie jak w przykładzie w języku Rust ten kod tworzy 2 zagnieżdżone wycinki i znacznik zdarzenia natychmiastowego w interfejsie. Gdy wybierzesz zdarzenie, wyświetlą się wartości argumentów debugowania.
Zbieranie logu czasu
Aby zarejestrować log czasu i wyświetlić go w
internetowym interfejsie Perfetto, użyj skryptu wiersza poleceń record\_android\_trace.
Konfigurowanie przechwytywania
Musisz podać konfigurację dla record_android_trace w formacie textproto. Więcej informacji znajdziesz w dokumentacji
Perfetto.
Repozytorium SDV zawiera przykładową konfigurację (system/software_defined_vehicle/core_services/samples/tracing/config/trace_cfg.pbtx). Ten plik zawiera kilka źródeł danych i można go dostosować lub użyć w takiej postaci.
Generowanie konfiguracji za pomocą interfejsu Perfetto
Możesz skonfigurować niestandardową konfigurację i poznać dostępne opcje, otwierając opcję Record new trace (Zarejestruj nowy log czasu) w interfejsie Perfetto UI, dostosowując ustawienia nagrywania i sondy. Następnie możesz otworzyć widok „Recording command” (Polecenie nagrywania), aby zobaczyć wygenerowane polecenie i uzyskać zawartość konfiguracji.
Konfigurowanie widoczności instrumentacji w aplikacji
Instrumentacja w języku Rust używa
ATrace. Jest ona
skonfigurowana w sekcji ftrace_config dokumentu. Komponenty SDV
mają tag ATRACE_TAG_APP i można je włączyć w przypadku poszczególnych
aplikacji. Przykładowa konfiguracja włącza wszystkie aplikacje.
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: "*"
}
}
}
W pakiecie SDK Perfetto w C++ używamy zdarzeń śledzenia. Jest to
track_event źródło danych
(dokumentacja).
Kategorie i tagi możesz włączać i wyłączać w polu
track_event_config Domyślnie włączony jest każdy tag końca kategorii, z wyjątkiem specjalnych tagów slow i debug.
Jeśli chcesz włączyć tylko określone kategorie, musisz wyłączyć wszystkie
inne, na przykład za pomocą disabled_categories: "*" jak tutaj:
data_sources: {
config {
name: "track_event"
track_event_config {
enabled_categories: "the_best_category_in_the_world"
disabled_categories: "*"
}
}
}Rejestrowanie logu czasu
Otwórz terminal w katalogu głównym repozytorium Androida. Nie musisz wykonywać envsetup. Skrypt nagrywania znajduje się w external/perfetto/tools/record_android_trace.
Uruchom skrypt z przykładową konfiguracją:
external/perfetto/tools/record_android_trace --config system/software_defined_vehicle/core_services/samples/tracing/config/trace_cfg.pbtx
Aby wcześniej zatrzymać nagrywanie, naciśnij Ctrl + C.
Spowoduje to, że adb shell perfetto zarejestruje log czasu, a następnie pobierze
go na hosta, zwykle do katalogu ~/traces. Gdy log czasu zostanie zebrany, narzędzie otworzy okno przeglądarki, aby go wyświetlić.
Przydatne argumenty:
-s SERIAL– użycie urządzenia o danym numerze seryjnym. Na przykład-s 0.0.0.0:6520--no-open-browser– utworzenie adresu URL do udostępniania logu czasu, ale nieotwieranie przeglądarki. Jest to przydatne w przypadku sesji zdalnych, gdy masz skonfigurowane przekierowanie portów (zwykle 9001).-n, --no-open– po sesji śledzenia nieotwieranie przeglądarki ani nieutworzenie adresu URL do udostępniania logu czasu. Możesz nadal otwierać pliki w interfejsie Perfetto, klikając „Open trace file” (Otwórz plik śledzenia) i wybierając plik.-o <path>– ustawienie ścieżki wyjściowej.
Dane o wykorzystaniu
W tej sekcji znajdziesz informacje, które mogą być przydatne podczas korzystania z systemu śledzenia.
Instrumentacja śledzenia w komponentach SDV
W agentach z instrumentacją śledzenia śledzenie jest domyślnie dostępne w kompilacjach z możliwością debugowania (-eng, -userdebug), chyba że określono inaczej. Gdy zbierzesz log czasu, powinny być widoczne zdarzenia procesów bez dodatkowej konfiguracji.
Biblioteki zwykle nie inicjują śledzenia automatycznie. W języku Rust plik binarny, który używa biblioteki, musi zainicjować śledzenie procesu za pomocą sdv_tracing::init_tracing(). Więcej informacji znajdziesz w sekcji Instrumentacja kodu.
Oprogramowanie pośredniczące
Biblioteka publikowania/subskrybowania: libsdv_middleware_dt
Wydarzenia:
- Wydawca: publikowanie i rejestrowanie tematów.
- Subskrybent: subskrybowanie i odpytywanie.
Włączanie: w pliku binarnym wywołaj sdv_tracing::init_tracing() lub sdv_tracing::try_init_tracing().
Biblioteka gRPC: libsdvmiddleware_rpc_grpc_transport
Wydarzenia:
- Klient RPC: uruchamianie, łączenie się z serwerem i wywoływanie metod RPC.
- Serwer RPC: uruchamianie, rejestrowanie w Service Discovery, dodawanie i wywoływanie metod RPC.
Włączanie: w pliku binarnym wywołaj sdv_tracing::init_tracing() lub sdv_tracing::try_init_tracing().
SOME/IP
- Proces:
sdv_someip_broker_agent. Example Source: This is a test Example Translation: Dies ist ein Test Source: This is a test with another placeholder Translation: Dies ist ein Test mit einem anderen Platzhalter - Wydarzenia: przetwarzanie i tłumaczenie wiadomości, subskrypcja zdarzeń.
Menedżer cyklu życia
- Proces:
sdv_lifecycle_agent. Example Source: This is a test Example Translation: Dies ist ein Test Source: This is a test with another placeholder Translation: Dies ist ein Test mit einem anderen Platzhalter - Wydarzenia: operacje na usługach – uruchamianie, zatrzymywanie, rejestrowanie, wyrejestrowywanie.
Tryb zasilania pojazdu
- Proces:
sdv_vpm_agent. Example Source: This is a test Example Translation: Dies ist ein Test Source: This is a test with another placeholder Translation: Dies ist ein Test mit einem anderen Platzhalter - Wydarzenia: zmiany stanu zasilania i subskrypcje.
Tunel danych
Planujemy wprowadzić integrację śledzenia w przyszłości.
Obciążenie wydajności związane ze śledzeniem
Pomiary obciążenia są obarczone zwykłym zastrzeżeniem, że wydajność może się różnić w zależności od systemu, a zwłaszcza między emulatorem a rzeczywistym sprzętem.
Rdza
Nieprzetworzone dane testów porównawczych są dostępne w AOSP. Dane zostały zebrane na maszynie wirtualnej Cuttlefish.
- Pojedynczy zakres:
tracing::info_span!(),#[tracing::instrument]i podobne:- Śledzenie nie zostało zainicjowane: 1 ns.
- Śledzenie zostało zainicjowane i wyłączone (nie jest rejestrowany żaden log czasu): 30 ns.
- Śledzenie jest włączone: 3 µs. Adnotacje pola debugowania mogą dodać 1–2 µs, w zależności od złożoności konwersji na ciąg znaków.
- Pojedyncze zdarzenie:
tracing::info!()i podobne:- Śledzenie nie zostało zainicjowane: 1 ns.
- Śledzenie zostało zainicjowane i wyłączone: 30 ns.
- Śledzenie jest włączone: 1,5 µs. Adnotacje pola debugowania mogą dodać 0,5–1 µs,
w zależności od
stringificationzłożoności.
C++
Dane o wydajności pochodzą z sekcji Performance (Wydajność) w dokumentacji Track events (Zdarzenia śledzenia) w Perfetto. Czasy dla Pixela 3 w tabeli są zgodne z naszymi obserwacjami na maszynie wirtualnej Cuttlefish.
Pojedynczy wycinek: TRACE_EVENT() i podobne. Śledzenie:
- Wyłączone: 2 ns.
- Włączone: 300 ns. Używanie adnotacji pola debugowania może dodać 50–100 ns.