O que é Tracing e por que ele é necessário em Rust?
\n\nA biblioteca Tracing é um framework poderoso para registro estruturado e instrumentação (rastreamento) de aplicações em Rust. Diferente de loggers simples, o Tracing fornece o conceito de spans e eventos (events), que permitem rastrear a execução do código no contexto de operações assíncronas, sistemas distribuídos e chamadas aninhadas complexas.
\n\nO principal objetivo do Tracing é dar ao desenvolvedor uma visão completa do que acontece dentro do programa: quais funções são chamadas, quanto tempo elas levam para executar, quais erros ocorrem e como eles estão relacionados entre si. É uma ferramenta indispensável para depuração, criação de perfil e monitoramento de sistemas em produção.
\n\nA biblioteca faz parte do ecossistema Tokio e é ativamente usada em projetos como actix-web, axum, hyper e muitos outros.
Instalação do Tracing
\n\nPara adicionar Tracing ao seu projeto em Rust, abra o arquivo Cargo.toml e adicione as seguintes dependências:
[dependencies]\ntracing = "0.1"\ntracing-subscriber = "0.3" # Para exibir logs no console\ntracing-appender = "0.2" # Para gravar logs em arquivo (opcional)\n\nDepois disso, execute o comando cargo build para baixar e compilar as bibliotecas.
Início rápido: primeiro exemplo
\n\nVamos escrever um programa simples que registra uma mensagem usando Tracing:
\n\nuse tracing::{info, Level};\nuse tracing_subscriber::FmtSubscriber;\n\nfn main() {\n // Inicializamos o subscriber para exibir logs no stdout\n let subscriber = FmtSubscriber::builder()\n .with_max_level(Level::INFO)\n .finish();\n tracing::subscriber::set_global_default(subscriber)\n .expect("Falha ao definir o subscriber global");\n\n // Registramos uma mensagem simples\n info!("Aplicação iniciada!");\n\n // Chamada de função com rastreamento\n process_data("example.txt");\n}\n\nfn process_data(filename: &str) {\n // Criamos um span para rastrear a função\n let span = tracing::span!(Level::INFO, "process_data", filename = filename);\n let _guard = span.enter(); // Entramos no span\n\n info!("Iniciando processamento do arquivo");\n // ... algum trabalho ...\n std::thread::sleep(std::time::Duration::from_millis(100));\n info!("Processamento concluído");\n}\n\nAo executar, você verá uma saída estruturada com carimbos de data/hora, níveis e nomes de spans.
\n\nPrincipais métodos e funções do Tracing
\n\nAbaixo estão 10 funções e macros chave da biblioteca Tracing com descrição detalhada e exemplos.
\n\n1. tracing::span! — Criação de span
\nO que faz: Cria um novo span — uma unidade lógica de trabalho que pode ser aninhada. O span tem um nome, um nível e um conjunto de campos.
\nParâmetros:
\n- \n
Level— nível de registro (ERROR, WARN, INFO, DEBUG, TRACE) \n target(opcional) — string que identifica o módulo \n field = value— campos arbitrários para contexto \n
Exemplo:
\nuse tracing::Level;\n\nfn handle_request(id: u64) {\n let span = tracing::span!(Level::INFO, "handle_request", request_id = id);\n let _guard = span.enter();\n // Código dentro do span\n tracing::info!("Processando requisição");\n}\n\n2. tracing::info! — Registro no nível INFO
\nO que faz: Grava um evento no nível INFO. Um evento é uma mensagem única que pode estar associada ao span atual.
\nParâmetros:
\n- \n
- String de formatação (como em
format!) \n - Argumentos para formatação \n
- Campos via
field = value<