Registro para Rust: melhores soluções
O registro é um componente criticamente importante de qualquer aplicação séria em Rust. Ele ajuda a rastrear a execução do código, identificar erros, monitorar o desempenho e analisar o comportamento do sistema em produção. Neste artigo, veremos as principais bibliotecas para registro no ecossistema Rust, suas características, vantagens e exemplos de uso.
Por que o registro é importante em Rust?
Rust, sendo uma linguagem de sistema, impõe altos requisitos de confiabilidade e previsibilidade. O registro permite:
- Rastrear o fluxo de execução em aplicações multithread.
- Registrar estados inesperados e panics.
- Realizar auditoria de segurança.
- Coletar métricas para otimização de desempenho.
Principais bibliotecas para registro
1. log — fachada para registro
log é a fachada padrão (camada abstrata) para registro em Rust. Ela define as macros info!, warn!, error!, debug!, trace! e a trait Log. Por si só, ela não gera logs — para isso, é necessário um backend (por exemplo, env_logger ou slog).
// Cargo.toml[dependencies]log = "0.4"
// main.rsuse log::{info, warn, error};
fn main() { // Inicialização do backend é obrigatória env_logger::init(); info!("Aplicação iniciada"); warn!("Nível baixo de memória: {}%", 15); error!("Erro crítico: {}", "falha de conexão");}2. env_logger — backend simples e rápido
env_logger é o backend mais popular para log. É configurado através da variável de ambiente RUST_LOG. Suporta filtragem por módulos e níveis.
// Instalação// cargo add env_logger
// Exemplo de configuraçãouse log::LevelFilter;
fn main() { env_logger::Builder::from_env( env_logger::Env::default().default_filter_or("info") ).init();
log::info!("Iniciando com nível INFO"); log::debug!("Esta mensagem não será exibida");}
// Execução com variável:// RUST_LOG=debug cargo run3. slog — registro estruturado
slog é uma biblioteca poderosa para registro estruturado. Suporta chave-valor, cadeias de loggers, gravação assíncrona e drivers personalizados. Ideal para sistemas complexos onde o contexto é importante.
// Cargo.toml[dependencies]slog = "2.7"slog-term = "2.9"slog-json = "2.6"
// main.rsuse slog::{o, Drain, Logger, info};
fn main() { let decorator = slog_term::TermDecorator::new().build(); let drain = slog_term::FullFormat::new(decorator).build().fuse(); let drain = slog_async::Async::new(drain).build().fuse();
let logger = Logger::root(drain, o!("version" => "1.0"));
info!(logger, "Servidor iniciado"; "port" => 8080, "env" => "production");}4. tracing — instrumentação e rastreamento
tracing é uma biblioteca moderna da equipe Tokio, projetada para registro estruturado e rastreamento. Permite criar spans — intervalos de tempo com contexto, essenciais para aplicações assíncronas e multithread.
// Cargo.toml[dependencies]tracing = "0.1"tracing-subscriber = "0.3"
// main.rsuse tracing::{info, span, Level};use tracing_subscriber::fmt;
fn main() { // Inicialização do subscriber fmt::init();
let span = span!(Level::INFO, "main", "app" = "my_service"); let _guard = span.enter();
info!("Processando requisição"); // Logs dentro do span contêm automaticamente o contexto}Comparação das bibliotecas
- log + env_logger: Simplicidade, minimalismo, adequado para projetos pequenos