Use o rastreamento para registrar eventos e contadores no sistema e visualizar cada um em uma linha do tempo. A ferramenta de rastreamento padrão no Android é o Perfetto. Para saber mais, consulte Rastreamento 101.
Instrumentar o código
Para receber eventos do app, é necessário instrumentá-lo adicionando tracepoints ao código. As seções não instrumentadas não aparecem nos rastreamentos.
A amostra de rastreamento do SDV é uma demonstração da integração de rastreamento, com instruções e um exemplo de configuração de rastreamento. Ele está localizado em
system/software_defined_vehicle/core_services/samples/tracing/.
Rust
A abordagem recomendada para Rust é usar a crate tracing para emitir eventos ATrace. O Perfetto é compatível com o ATrace como uma fonte de dados. Planejamos mudar para o SDK do Perfetto quando as vinculações do Rust estiverem disponíveis e dependendo da evolução dos casos de uso.
Adicione os padrões de rastreamento a Android.bp:
rust_binary {
...
defaults: [
...
"sdv_tracing@rust_defaults",
],
...
}
Inicialize o assinante. Isso só pode ser feito uma vez por processo:
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()
...
}
Você pode omitir a chamada de inicialização. Isso deixa o rastreamento não inicializado e o Perfetto não coleta eventos de instrumentação do app.
Adicione tracepoints. Encontre mais exemplos em
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++
O rastreamento em C++ usa o SDK do Perfetto para rastrear eventos. Adicione os padrões de rastreamento a Android.bp:
cc_binary {
...
defaults: [
...
"sdv_tracing@cc_defaults",
],
...
}
Defina as categorias. Se você usar as categorias em vários módulos, mova
para uma biblioteca comum. Por exemplo, system/software_defined_vehicle/core_services/samples/tracing/cpp_service/tracing_categories.h.
No cabeçalho:
#include "perfetto/tracing/tracing.h"
#include "perfetto/tracing/track_event.h"
PERFETTO_DEFINE_CATEGORIES(
perfetto::Category("sample")
.SetTags("tag")
.SetDescription("Sample events"));
Coloque a macro de armazenamento estático em um arquivo de origem .cpp, não em um método. Se você estiver compartilhando as categorias entre componentes, use o arquivo de origem que corresponde ao cabeçalho com categorias.
PERFETTO_TRACK_EVENT_STATIC_STORAGE();
int main() {
...
}
Para inicializar o Perfetto, inicialize o back-end do sistema e registre os eventos de rastreamento:
#include <sdv/tracing_init.h>
int main() {
...
android::sdv::InitPerfettoWithTrackEvents<perfetto::TrackEvent>();
...
}
Adicione instrumentação. Veja mais exemplos em
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;
}
Assim como no exemplo em Rust, esse código produz duas fatias aninhadas e um marcador para o evento instantâneo na interface. Os valores do argumento de depuração são mostrados quando um evento é selecionado.
Coletar um trace
Use o script de linha de comando record\_android\_trace para gravar um rastreamento e
a interface da Web do Perfetto para visualizá-lo.
Configurar a captura
Você precisa fornecer uma configuração para record_android_trace no formato textproto. Consulte a
documentação do Perfetto para saber mais.
O repositório do SDV contém uma configuração de amostra (system/software_defined_vehicle/core_services/samples/tracing/config/trace_cfg.pbtx). Esse arquivo inclui várias fontes de dados e pode ser personalizado ou usado no estado em que se encontra.
Usar a interface do Perfetto para gerar uma configuração
Para configurar uma configuração personalizada e conferir as opções disponíveis, acesse Registrar novo rastreamento na interface do Perfetto, ajustando as configurações de gravação e as sondagens. Em seguida, abra a visualização "Comando de gravação" para conferir o comando gerado e acessar o conteúdo da configuração.
Configurar a visibilidade da instrumentação no app
A instrumentação do Rust usa o
ATrace. Ela é
configurada na seção ftrace_config do documento. Os componentes
do SDV têm a tag ATRACE_TAG_APP e podem ser ativados por
app. A configuração de exemplo ativa todos os apps.
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: "*"
}
}
}
Usamos eventos de rastreamento no SDK do Perfetto em C++. Esta é uma fonte de dados track_event (documento).
É possível ativar ou desativar categorias e tags no campo
track_event_config. Todas as tags finais de categoria são ativadas por padrão, exceto as tags especiais slow e debug.
Se você quiser ativar apenas categorias específicas, desative todas as outras. Por exemplo, com disabled_categories: "*", como aqui:
data_sources: {
config {
name: "track_event"
track_event_config {
enabled_categories: "the_best_category_in_the_world"
disabled_categories: "*"
}
}
}Gravar um rastro
Abra um terminal na raiz do repositório Android. Não é necessário fazer envsetup. O
script de gravação está em external/perfetto/tools/record_android_trace.
Execute o script com a configuração de exemplo:
external/perfetto/tools/record_android_trace --config system/software_defined_vehicle/core_services/samples/tracing/config/trace_cfg.pbtx
Para interromper a gravação antes, selecione Ctrl + C.
Isso aciona adb shell perfetto para gravar um rastreamento e extrair o
rastreamento para o host, geralmente em ~/traces. Quando o trace é coletado, a ferramenta
abre uma janela do navegador para mostrar o trace.
Argumentos úteis:
-s SERIALpara usar o dispositivo com um determinado número de série. Por exemplo,-s 0.0.0.0:6520--no-open-browsercria um URL para veicular o rastreamento, mas não abre o navegador. É útil para sessões remotas quando você tem o encaminhamento de portas configurado (geralmente 9001).O
-n, --no-opennão vai abrir o navegador nem criar o URL para veicular o rastreamento depois da sessão de rastreamento. Você ainda pode abrir arquivos na interface do Perfetto clicando em "Abrir arquivo de rastreamento" e selecionando o arquivo.-o <path>para definir o caminho de saída.
Detalhes de uso
Esta seção fornece detalhes que podem ser úteis ao usar o sistema de rastreamento.
Instrumentação de rastreamento em componentes do SDV
Em agentes com instrumentação de rastreamento, o rastreamento está disponível por padrão em
builds depuráveis (-eng, -userdebug), a menos que especificado de outra forma. Ao coletar um rastreamento, você vai ver os eventos dos processos sem configuração extra.
Normalmente, as bibliotecas não inicializam o rastreamento automaticamente. Em Rust, o binário
que usa a biblioteca precisa inicializar o rastreamento do processo usando
sdv_tracing::init_tracing(). Consulte Instrumentar seu código para saber mais.
Middleware
Biblioteca de publicação/assinatura: libsdv_middleware_dt
Eventos:
- Publisher: publicação e registro de tópicos.
- Inscrito: inscrição e sondagem.
Ativação: chame sdv_tracing::init_tracing() ou
sdv_tracing::try_init_tracing() no binário.
Biblioteca gRPC: libsdvmiddleware_rpc_grpc_transport
Eventos:
- Cliente RPC: inicialização, conexão com o servidor e chamadas de método RPC.
- Servidor RPC: iniciando, registrando com a descoberta de serviços, adicionando e chamando métodos RPC.
Ativação: chame sdv_tracing::init_tracing() ou
sdv_tracing::try_init_tracing() em binário.
SOME/IP
- Processo:
sdv_someip_broker_agent. \ - Eventos: processamento e tradução de mensagens, inscrição em eventos.
Gerenciador do ciclo de vida
- Processo:
sdv_lifecycle_agent. \ - Eventos: operações de serviço (início, interrupção, registro e cancelamento de registro).
Modo de energia do veículo
- Processo:
sdv_vpm_agent. \ - Eventos: mudanças no estado de energia e assinaturas.
Data Tunnel
Planejamos oferecer suporte à integração de rastreamento no futuro.
Sobrecarga de desempenho do rastreamento
As medições de sobrecarga vêm com a ressalva usual de que o desempenho pode variar entre diferentes sistemas e, principalmente, entre o emulador e o hardware real.
Rust
Os dados brutos de comparativo de mercado estão disponíveis no AOSP. Os dados foram coletados em uma VM do Cuttlefish.
- Intervalo único:
tracing::info_span!(),#[tracing::instrument]e semelhantes:- Rastreamento não inicializado: 1 ns.
- Rastreamento inicializado e desativado (nenhuma gravação de rastreamento em andamento): 30 ns.
- Rastreamento ativado: 3 µs. Anotações de campo de depuração podem adicionar de 1 a 2 µs, dependendo da complexidade da conversão em string.
- Evento único:
tracing::info!()e semelhantes:- Rastreamento não inicializado: 1 ns.
- Rastreamento inicializado e desativado: 30 ns.
- Rastreamento ativado: 1,5 µs. As anotações de campo de depuração podem adicionar de 0,5 a 1 µs,
dependendo da complexidade de
stringification.
C++
Os números de performance são da seção "Performance" do documento "Rastrear eventos" no Perfetto. Os tempos do Pixel 3 na tabela são consistentes com nossas observações na VM do Cuttlefish.
Única fração: TRACE_EVENT() e semelhantes. Rastreamento:
- Desativado: 2ns.
- Ativado: 300 ns. O uso de anotações de campo de depuração pode adicionar de 50 a 100 ns.