Logging Profissional Python Rust
Logging Profissional Python Rust
Claro — vamos fazer isso do jeito certo, com profundidade e com paralelo constante com
Python.
[Link] 1/37
11/03/2026, 12:49 Logging Profissional Python Rust
diagnosticar bugs
entender fluxo da aplicação
auditar eventos importantes
investigar falhas em produção
medir comportamento do sistema
correlacionar erros entre módulos/threads/requests
enviar logs para arquivos, terminal, Elastic, Loki, Datadog, etc.
Diferença prática
Python
Python Executar
print("Usuário autenticado")
Rust
Rust
println!("Usuário autenticado");
[Link] 2/37
11/03/2026, 12:49 Logging Profissional Python Rust
Python Executar
import logging
[Link](level=[Link])
logger = [Link](__name__)
[Link]("Aplicação iniciada")
[Link]("Falha ao conectar no banco")
Rust
fn main() {
env_logger::init();
info!("Aplicação iniciada");
error!("Falha ao conectar no banco");
}
Ideia central
Conceito Python Rust
Exemplo
Rust
fn main() {
env_logger::init();
error!("Erro crítico");
warn!("Recurso em degradação");
info!("Servidor iniciado");
debug!("Valor de x = {}", 42);
trace!("Entrando na função processar()");
}
Paralelo em Python
Python Executar
import logging
[Link](level=[Link])
logger = [Link](__name__)
[Link]("Erro crítico")
[Link]("Recurso em degradação")
[Link]("Servidor iniciado")
[Link]("Valor de x = %s", 42)
[Link]
[Link] 4/37
11/03/2026, 12:49 Logging Profissional Python Rust
TOML
[dependencies]
log = "0.4"
env_logger = "0.11"
Exemplo básico
Rust
fn main() {
env_logger::init();
info!("Aplicação iniciada");
debug!("Esse log só aparece se o nível permitir");
warn!("Uso de configuração padrão");
error!("Falha ao processar requisição");
}
Como executar
Windows CMD
bat
set RUST_LOG=debug
cargo run
PowerShell
PowerShell
$env:RUST_LOG="debug"
cargo run
Resultado
Você controla o nível por variável de ambiente.
PowerShell
$env:RUST_LOG="info"
[Link] 5/37
11/03/2026, 12:49 Logging Profissional Python Rust
cargo run
ou
PowerShell
$env:RUST_LOG="meu_crate=debug"
cargo run
ou
PowerShell
$env:RUST_LOG="meu_crate=trace,hyper=warn"
cargo run
info!
debug!
warn!
error!
trace!
Rust
env_logger::init();
Python Executar
logger = [Link](__name__)
Exemplo
Rust
mod banco {
use log::info;
pub fn conectar() {
info!("Conectando no banco");
}
}
mod api {
use log::info;
pub fn iniciar() {
info!("API iniciada");
}
}
fn main() {
env_logger::init();
banco::conectar();
api::iniciar();
}
Exemplo:
PowerShell
$env:RUST_LOG="meu_projeto::banco=debug,meu_projeto::api=info"
cargo run
Rust
use env_logger::Builder;
use log::{LevelFilter, info};
use std::io::Write;
fn main() {
let mut builder = Builder::new();
builder
.filter_level(LevelFilter::Info)
.format(|buf, record| {
writeln!(
buf,
"[{} {} {}] {}",
buf.timestamp_millis(),
[Link](),
[Link](),
[Link]()
)
});
[Link]();
info!("Aplicação iniciada");
}
Paralelo em Python
Isso equivale a customizar um Formatter .
Python Executar
formatter = [Link](
"[%(asctime)s %(levelname)s %(name)s] %(message)s"
[Link] 8/37
11/03/2026, 12:49 Logging Profissional Python Rust
arquivo rotativo
retenção
múltiplas saídas
log separado por nível
compressão/rotação
TOML
[dependencies]
log = "0.4"
fern = "0.7"
chrono = "0.4"
Rust
.chain(fern::log_file("[Link]")?)
.apply()?;
Ok(())
}
info!("Aplicação iniciada");
debug!("Modo debug ativo");
warn!("Configuração padrão em uso");
error!("Erro ao abrir recurso");
Ok(())
}
Vantagens do fern
muito flexível
escreve em arquivo
múltiplos destinos
filtro por módulo
bom para aplicações CLI/serviços
Paralelo Python
Isso lembra usar mais de um handler:
Python Executar
stream_handler = [Link]()
file_handler = [Link]("[Link]")
[Link]
TOML
[dependencies]
log = "0.4"
flexi_logger = "0.29"
[Link] 10/37
11/03/2026, 12:49 Logging Profissional Python Rust
Exemplo
Rust
info!("Sistema iniciado");
error!("Falha simulada");
Ok(())
}
Python equivalente
Isso corresponde a algo como:
Python Executar
[Link] 11/37
11/03/2026, 12:49 Logging Profissional Python Rust
APIs
microserviços
sistemas distribuídos
observabilidade
integração com OpenTelemetry
correlação de request ID
tracing
tracing-subscriber
eventos estruturados
spans (escopos de execução)
contexto entre funções
instrumentação assíncrona
excelente para tokio , axum , warp , tonic
Analogia em Python
O equivalente conceitual seria uma mistura de:
logging
structlog
tracing distribuído
APM / observabilidade
TOML
[dependencies]
tracing = "0.1"
[Link] 12/37
11/03/2026, 12:49 Logging Profissional Python Rust
Código
Rust
fn main() {
tracing_subscriber::fmt::init();
info!("Aplicação iniciada");
debug!("Detalhe de depuração");
warn!("Aviso importante");
error!("Erro de processamento");
}
PowerShell
PowerShell
$env:RUST_LOG="debug"
cargo run
PowerShell
$env:RUST_LOG="trace"
cargo run
Rust
[Link] 13/37
11/03/2026, 12:49 Logging Profissional Python Rust
fn main() {
let subscriber = FmtSubscriber::builder()
.with_max_level(tracing::Level::TRACE)
.finish();
tracing::subscriber::set_global_default(subscriber)
.expect("falha ao registrar subscriber");
Diferença essencial
Aqui não é só uma string.
Você tem:
mensagem
user_id
email
code
Esses campos podem ser exportados para JSON e consumidos por observabilidade.
Python Executar
[Link](
"Usuário autenticado",
extra={"user_id": 42, "email": "usuario@[Link]"}
)
Exemplo
[Link] 14/37
11/03/2026, 12:49 Logging Profissional Python Rust
Rust
use tracing::info;
use tracing_subscriber::fmt;
fn main() {
fmt()
.json()
.with_max_level(tracing::Level::INFO)
.init();
Exemplo de saída
JSON
{
"timestamp":"2026-03-11T12:00:00.000Z",
"level":"INFO",
"fields":{
"message":"evento de autenticação",
"user_id":10,
"action":"login",
"success":true
},
"target":"meu_app"
}
[Link] 15/37
11/03/2026, 12:49 Logging Profissional Python Rust
desenvolvimento
debugging manual
Exemplo
Rust
fn main() {
fmt().init();
info!("Validando pedido");
info!("Calculando frete");
info!("Pedido concluído");
}
contextvars
structlog
middleware
[Link] 16/37
11/03/2026, 12:49 Logging Profissional Python Rust
Exemplo
Rust
#[instrument]
fn somar(a: i32, b: i32) -> i32 {
info!("Executando soma");
a + b
}
fn main() {
fmt().init();
O que acontece
O #[instrument] cria automaticamente um span com os argumentos da função.
nome da função
parâmetros
tempo de execução potencialmente observável
rastreabilidade
TOML
[dependencies]
tracing = { version = "0.1", features = ["attributes"] }
tracing-subscriber = "0.3"
Paralelo em Python
Seria parecido com criar um decorator que loga:
[Link] 17/37
11/03/2026, 12:49 Logging Profissional Python Rust
Python Executar
def log_calls(fn):
def wrapper(*args, **kwargs):
[Link]("Chamando %s args=%s kwargs=%s", fn.__name__, args, kwargs)
return fn(*args, **kwargs)
return wrapper
Exemplo
Rust
use tracing::instrument;
#[instrument(skip(password))]
fn autenticar(usuario: &str, password: &str) -> bool {
usuario == "admin" && password == "123"
}
Rust
Regra profissional
Nunca logue:
senha
token JWT completo
chave de API
CPF completo
cartão
[Link] 18/37
11/03/2026, 12:49 Logging Profissional Python Rust
Exemplo simples
Rust
use log::error;
use std::fs::File;
fn abrir_arquivo() {
match File::open("[Link]") {
Ok(_) => {}
Err(e) => error!("Falha ao abrir arquivo: {}", e),
}
}
Paralelo Python
Python Executar
try:
open("[Link]")
except Exception as e:
[Link]("Falha ao abrir arquivo: %s", e)
Rust
[Link] 19/37
11/03/2026, 12:49 Logging Profissional Python Rust
Ok(a / b)
}
fn main() {
tracing_subscriber::fmt::init();
let a = 10;
let b = 0;
match dividir(a, b) {
Ok(resultado) => info!(resultado = resultado, "Divisão realizada"),
Err(e) => error!(a = a, b = b, erro = %e, "Falha na divisão"),
}
}
Atenção ao % e ?
No tracing , você pode escrever:
21. % e ? em tracing
Exemplo
Rust
use tracing::info;
#[derive(Debug)]
struct Usuario {
id: u32,
nome: String,
}
fn main() {
tracing_subscriber::fmt::init();
[Link] 20/37
11/03/2026, 12:49 Logging Profissional Python Rust
Resumo
?campo → formato Debug
%campo → formato Display
Python Executar
[Link]("valor=%s", valor)
e não:
Python Executar
[Link](f"valor={valor}")
Em Rust
As macros de logging também ajudam a evitar custo desnecessário quando o nível está
desabilitado.
Rust
Mas atenção: dependendo do caso, a função pode ser avaliada para formar os
argumentos.
Quando a computação é muito cara, você pode proteger explicitamente.
Exemplo
Rust
[Link] 21/37
11/03/2026, 12:49 Logging Profissional Python Rust
fn main() {
env_logger::init();
if log_enabled!(Level::Debug) {
debug!("valor = {}", calculo_caro());
}
}
Paralelo Python
Python Executar
if [Link]([Link]):
[Link]("valor=%s", calculo_caro())
Rust
use log::info;
pub fn processar() {
info!("Processando operação da biblioteca");
}
Aplicação final
Rust
[Link] 22/37
11/03/2026, 12:49 Logging Profissional Python Rust
fn main() {
env_logger::init();
minha_lib::processar();
}
Rust
#[instrument]
async fn tarefa(id: u32) {
info!("Iniciando tarefa");
}
#[tokio::main]
async fn main() {
tracing_subscriber::fmt()
.with_env_filter(EnvFilter::from_default_env())
.init();
tarefa(1).await;
}
[Link]
TOML
[dependencies]
tokio = { version = "1", features = ["full"] }
tracing = { version = "0.1", features = ["attributes"] }
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
[Link] 23/37
11/03/2026, 12:49 Logging Profissional Python Rust
contexto assíncrono
spans em futures
rastreamento de request
instrumentação por tarefa
actix-web
warp
logging
middleware do FastAPI/Flask/Django
structlog
observabilidade APM
[Link] 24/37
11/03/2026, 12:49 Logging Profissional Python Rust
Rust
fn main() {
tracing_subscriber::fmt().init();
processar_requisicao("req-123", 42);
}
JSON
Bom para:
produção
coleta centralizada
dashboards
alertas
parsing automático
Estratégia profissional
Uma prática excelente é:
dev local → formato bonito/colorido
produção → JSON estruturado
[Link] 25/37
11/03/2026, 12:49 Logging Profissional Python Rust
Rust
tracing_subscriber::fmt()
.with_env_filter("debug")
.pretty()
.init();
Produção
Rust
tracing_subscriber::fmt()
.json()
.with_env_filter("info")
.init();
Exemplo
Rust
use log::info;
fn main() {
env_logger::init();
info!(target: "auth", "Usuário autenticado");
}
Ou com tracing :
Rust
use tracing::info;
fn main() {
tracing_subscriber::fmt().init();
info!(target: "auth", user_id = 10, "Login realizado");
}
[Link] 26/37
11/03/2026, 12:49 Logging Profissional Python Rust
auth
db
http
payment
Estratégia
Desenvolvimento
debug ou trace
Homologação
info + alguns módulos em debug
Produção
info / warn / error
Exemplo
PowerShell
$env:RUST_LOG="info,my_app::db=debug"
cargo run
Exemplo problemático
Rust
env_logger::init();
env_logger::init(); // erro/panic dependendo do caso
Rust
let _ = env_logger::builder().is_test(true).try_init();
Exemplo
Rust
#[cfg(test)]
mod tests {
use log::info;
#[test]
fn teste_exemplo() {
let _ = env_logger::builder().is_test(true).try_init();
info!("Executando teste");
assert_eq!(2 + 2, 4);
}
}
PowerShell
$env:RUST_LOG="info"
cargo test -- --nocapture
Paralelo Python
Seria como habilitar logging dentro de testes pytest ou unittest .
println!
saída simples
sem nível
[Link] 28/37
11/03/2026, 12:49 Logging Profissional Python Rust
sem metadata
útil para CLI simples
dbg!
depuração rápida
mostra arquivo e linha
ótimo durante desenvolvimento
não substitui logging
Exemplo
Rust
fn main() {
let x = 10;
dbg!(x * 2);
}
Saída típica:
Rust
[src/[Link]] x * 2 = 20
Logging
persistente
controlável
filtrável
profissional
Regra prática
dbg! → depuração temporária
biblioteca genérica
você quer compatibilidade ampla
logging textual já resolve
Isso é comum.
[Link]
TOML
[dependencies]
tracing = { version = "0.1", features = ["attributes"] }
tracing-subscriber = { version = "0.3", features = ["env-filter", "fmt", "json"]
[Link] 30/37
11/03/2026, 12:49 Logging Profissional Python Rust
Código
Rust
#[instrument(skip(senha))]
fn autenticar(usuario: &str, senha: &str) -> Result<u64, String> {
info!("Iniciando autenticação");
if usuario.is_empty() {
warn!("Usuário vazio");
return Err("usuário inválido".into());
}
fn main() {
fmt()
.with_env_filter(EnvFilter::from_default_env())
.with_target(true)
.init();
Executando
PowerShell
$env:RUST_LOG="info"
cargo run
[Link] 31/37
11/03/2026, 12:49 Logging Profissional Python Rust
Python Executar
import logging
[Link](
level=[Link],
format="%(asctime)s %(levelname)s %(name)s %(message)s"
)
logger = [Link]("auth")
if not usuario:
[Link]("Usuário vazio")
raise ValueError("usuário inválido")
try:
user_id = autenticar("admin", "123")
[Link]("Login concluído user_id=%s", user_id)
except Exception as e:
[Link]("Falha no login: %s", e)
Diferença filosófica
Em Python, o logging textual é padrão.
Em Rust, rapidamente você percebe o valor de:
spans
fields estruturados
instrumentação forte
integração com async
[Link] 32/37
11/03/2026, 12:49 Logging Profissional Python Rust
Rust
error!("Deu erro");
Melhor:
trate o erro
propague com Result
logue no ponto certo
Rust
Pior:
Rust
7. Adicione correlação
Use:
request id
user id
job id
trace id
Rust
info!("erro no sistema");
Melhor
Rust
error!(
request_id = "req-123",
user_id = 42,
operation = "criar_pedido",
reason = "timeout no banco",
"Falha ao criar pedido"
);
log
env_logger
para entender:
[Link] 34/37
11/03/2026, 12:49 Logging Profissional Python Rust
níveis
filtros
targets
configuração por ambiente
tracing
tracing-subscriber
para entender:
campos estruturados
spans
#[instrument]
async
JSON
Rust
fn main() {
env_logger::init();
info!("Programa iniciado");
warn!("Exemplo de aviso");
}
Rust
use tracing::info;
use tracing_subscriber::{fmt, EnvFilter};
fn main() {
fmt()
.with_env_filter(EnvFilter::from_default_env())
.json()
.init();
Rust
abordagem modular por crates
log resolve logging clássico
tracing resolve logging/telemetria modernos muito melhor
Se pensar em Rust:
println! → saída simples
[Link] 36/37
11/03/2026, 12:49 Logging Profissional Python Rust
[Link]
módulos
configuração de logger
logs em terminal
logs em JSON
logs em arquivo
#[instrument]
tratamento de erros
paralelo linha a linha com Python
[Link] 37/37