트레이싱을 사용하여 시스템의 이벤트와 카운터를 기록하고 타임라인에서 각 이벤트를 시각화합니다. Android의 표준 트레이싱 도구는 Perfetto입니다. 자세한 내용은 트레이싱 101을 참고하세요.
코드 계측
앱에서 이벤트를 가져오려면 코드에 트레이스포인트를 추가하여 계측해야 합니다. 계측되지 않은 섹션은 트레이스에 표시되지 않습니다.
SDV 트레이싱 샘플은 트레이싱 구성의 안내 및 예와 함께 트레이싱 통합 데모입니다. system/software_defined_vehicle/core_services/samples/tracing/에 있습니다.
Rust
Rust의 권장되는 접근 방식은 트레이싱 크레이트를 사용하여 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에서 새 트레이스 기록으로 이동하여 기록 설정 및 프로브를 조정하여 맞춤 구성을 구성하고 사용 가능한 옵션을 탐색할 수 있습니다. 그런 다음 '기록 명령어' 뷰를 열어 생성된 명령어를 확인하고 여기에서 구성 콘텐츠를 가져올 수 있습니다.
인앱 계측 공개 상태 구성
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는 트레이스를 제공하는 URL을 만들지만 브라우저를 열지 않습니다. 포트 전달이 설정된 원격 세션 (일반적으로 9001)에 유용합니다.-n, --no-open은 트레이싱 세션 후 브라우저를 열거나 트레이스를 제공하는 URL을 만들지 않습니다. '추적 파일 열기'를 클릭하고 파일을 선택하여 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 서버: 시작, 서비스 디렉터리에 등록, RPC 메서드 추가 및 호출
사용 설정: 바이너리에서 sdv_tracing::init_tracing() 또는 sdv_tracing::try_init_tracing()을 호출합니다.
SOME/IP
- 프로세스:
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 - 이벤트: 메시지 처리 및 변환, 이벤트 구독
수명 주기 관리자
- 프로세스:
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 - 이벤트: 서비스 작업(실행, 중지, 등록, 등록 취소)
차량 전원 모드
- 프로세스:
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 - 이벤트: 전원 상태 변경 및 구독
데이터 터널
향후 트레이싱 통합을 지원할 계획입니다.
트레이싱의 성능 오버헤드
오버헤드 측정에는 성능이 시스템마다, 특히 에뮬레이터와 실제 하드웨어 간에 다를 수 있다는 일반적인 주의사항이 적용됩니다.
Rust
원시 벤치마크 데이터는 AOSP에서 사용할 수 있습니다. 데이터는 Cuttlefish VM에서 수집되었습니다.
- 단일 스팬:
tracing::info_span!(),#[tracing::instrument]등:- 트레이싱 초기화되지 않음: 1ns
- 트레이싱 초기화 및 사용 중지됨 (트레이스 기록 없음): 30ns
- 트레이싱 사용 설정됨: 3µs. 디버그 필드 주석은 문자열화 복잡성에 따라 1~2µs를 추가할 수 있습니다.
- 단일 이벤트:
tracing::info!()등:- 트레이싱 초기화되지 않음: 1ns
- 트레이싱 초기화 및 사용 중지됨: 30ns
- 트레이싱 사용 설정됨: 1.5µs. 디버그 필드 주석은
stringification복잡성에 따라 0.5~1µs를 추가할 수 있습니다.
C++
성능 수치는 Perfetto의 트랙 이벤트 문서의 성능 섹션에서 가져온 것입니다. 표의 Pixel 3 시간은 Cuttlefish VM의 관찰과 일치합니다.
단일 슬라이스: TRACE_EVENT() 등. 트레이싱:
- 사용 중지됨: 2ns
- 사용 설정됨: 300ns. 디버그 필드 주석을 사용하면 50~100ns를 추가할 수 있습니다.