0% acharam este documento útil (0 voto)
6 visualizações37 páginas

Logging Profissional Python Rust

O documento aborda o logging profissional em Rust, comparando-o com a abordagem em Python. Em Rust, o logging é modular e utiliza crates como log, env_logger, e tracing para diferentes níveis de complexidade e funcionalidades. O texto detalha a configuração, os níveis de log e exemplos práticos, destacando a importância do logging estruturado para aplicações modernas.
Direitos autorais
© All Rights Reserved
Levamos muito a sério os direitos de conteúdo. Se você suspeita que este conteúdo é seu, reivindique-o aqui.
Formatos disponíveis
Baixe no formato PDF, TXT ou leia on-line no Scribd
0% acharam este documento útil (0 voto)
6 visualizações37 páginas

Logging Profissional Python Rust

O documento aborda o logging profissional em Rust, comparando-o com a abordagem em Python. Em Rust, o logging é modular e utiliza crates como log, env_logger, e tracing para diferentes níveis de complexidade e funcionalidades. O texto detalha a configuração, os níveis de log e exemplos práticos, destacando a importância do logging estruturado para aplicações modernas.
Direitos autorais
© All Rights Reserved
Levamos muito a sério os direitos de conteúdo. Se você suspeita que este conteúdo é seu, reivindique-o aqui.
Formatos disponíveis
Baixe no formato PDF, TXT ou leia on-line no Scribd

11/03/2026, 12:49 Logging Profissional Python Rust

ChatGPT 5.4 Thinking Memória desativada

Sou programador Python aprendendo Rust, tenha ótima


didática e faça correlação entre as linguagens, mostre
como o rust trabalha comSou programador Python
aprendendo Rust, tenha ótima didática e faça correlação
entre as linguagens, mostre como o rust trabalha com
Logging Profissional (faça bem detalhado, com todas as
possibilidades, tipos diferente de executar esse tipo de
verificação, mostre muitos exemplos com paralelos em
python)

Pensou por dois segundos

Claro — vamos fazer isso do jeito certo, com profundidade e com paralelo constante com
Python.

Logging profissional em Rust para quem vem de Python


Se você já programa em Python, a melhor forma de entender logging em Rust é pensar
assim:
Python: logging já vem bem pronto na biblioteca padrão.
Rust: a filosofia é mais modular.
Normalmente você usa:
log → interface padrão de logging

env_logger → backend simples

tracing → logging estruturado e observabilidade moderna

fern , flexi_logger , slog → outras opções mais avançadas

Então, em Rust, você quase sempre separa:


1. API de log
2. implementação do logger
3. configuração de saída/formato/nível

1. O que é logging profissional


Logging profissional não é só fazer println!() .

[Link] 1/37
11/03/2026, 12:49 Logging Profissional Python Rust

Ele serve para:

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");

Isso é apenas saída de texto.

Logging profissional adiciona:

nível ( debug , info , warn , error , trace )


timestamp
módulo
thread
contexto
campos estruturados
filtro por ambiente
saída para múltiplos destinos

2. O paralelo mental Python x Rust


Python tradicional

[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 tradicional com log + env_logger

Rust

use log::{info, error};

fn main() {
env_logger::init();

info!("Aplicação iniciada");
error!("Falha ao conectar no banco");
}

Ideia central
Conceito Python Rust

API de log logging log

Configuração básica basicConfig() env_logger::init()

Logger nomeado [Link](__nam geralmente pelo módulo ( module_path!


e__) () )

Níveis DEBUG, INFO, WARNING, trace, debug, info, warn, error


ERROR, CRITICAL

Estruturado structlog , logging tracing


extra

Backends handlers crates como env_logger , tracing-


subscriber , fern

3. Principais níveis de log em Rust


[Link] 3/37
11/03/2026, 12:49 Logging Profissional Python Rust

Rust normalmente usa:

error! → falha séria

warn! → algo inesperado, mas o sistema continua

info! → eventos normais importantes


debug! → detalhes úteis para desenvolvimento

trace! → detalhamento extremo

Exemplo

Rust

use log::{error, warn, info, debug, trace};

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)

4. Primeira forma profissional: log + env_logger


Essa é a porta de entrada mais comum.

[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

use log::{info, warn, error, debug};

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.

Exemplo mais fino

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

5. Como o env_logger funciona internamente


O crate log define as macros:

info!

debug!
warn!

error!
trace!

Mas ele não escreve nada sozinho.


Ele precisa de um backend registrado globalmente.

Quando você faz:

Rust

env_logger::init();

você está dizendo:

“Use env_logger como implementação global do logger”.

Isso é parecido com configurar um StreamHandler no Python.

6. Filtro por módulo em Rust


[Link] 6/37
11/03/2026, 12:49 Logging Profissional Python Rust

Em Python, você costuma usar logger por módulo:

Python Executar

logger = [Link](__name__)

Em Rust, o módulo do código já entra naturalmente.

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();
}

Você pode filtrar por módulo com RUST_LOG .

Exemplo:

PowerShell

$env:RUST_LOG="meu_projeto::banco=debug,meu_projeto::api=info"
cargo run

Isso é muito poderoso em sistemas grandes.

7. Inicialização customizada do env_logger


[Link] 7/37
11/03/2026, 12:49 Logging Profissional Python Rust

Você não precisa usar só init() .

Exemplo com builder

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");
}

O que isso permite


mudar formato
definir timestamp
incluir target/módulo
alterar nível padrão
usar parse_env("RUST_LOG")
direcionar saída

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

8. Logging em arquivo com crates mais avançados


O env_logger é bom para terminal, mas para produção muitas vezes você quer:

arquivo rotativo
retenção
múltiplas saídas
log separado por nível
compressão/rotação

Para isso, fern e flexi_logger são ótimos.

9. Logging com fern


[Link]

TOML

[dependencies]
log = "0.4"
fern = "0.7"
chrono = "0.4"

Exemplo: terminal + arquivo

Rust

use log::{debug, error, info, warn};

fn setup_logger() -> Result<(), fern::InitError> {


fern::Dispatch::new()
.format(|out, message, record| {
[Link](format_args!(
"[{}][{}][{}] {}",
chrono::Local::now().format("%Y-%m-%d %H:%M:%S"),
[Link](),
[Link](),
message
))
})
.level(log::LevelFilter::Debug)
.chain(std::io::stdout())
[Link] 9/37
11/03/2026, 12:49 Logging Profissional Python Rust

.chain(fern::log_file("[Link]")?)
.apply()?;

Ok(())
}

fn main() -> Result<(), Box<dyn std::error::Error>> {


setup_logger()?;

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]")

10. Logging com rotação de arquivos: flexi_logger


Esse é excelente para produção.

[Link]

TOML

[dependencies]
log = "0.4"
flexi_logger = "0.29"

[Link] 10/37
11/03/2026, 12:49 Logging Profissional Python Rust

Exemplo

Rust

use flexi_logger::{Cleanup, Criterion, Duplicate, FileSpec, Logger, Naming};


use log::{error, info};

fn main() -> Result<(), Box<dyn std::error::Error>> {


Logger::try_with_str("info")?
.log_to_file(FileSpec::default().directory("logs"))
.duplicate_to_stdout(Duplicate::Info)
.rotate(
Criterion::Size(10_000_000),
Naming::Numbers,
Cleanup::KeepLogFiles(5),
)
.start()?;

info!("Sistema iniciado");
error!("Falha simulada");

Ok(())
}

O que esse exemplo faz


grava em logs/
também duplica info+ no terminal
rotaciona por tamanho
mantém 5 arquivos antigos

Python equivalente
Isso corresponde a algo como:

Python Executar

from [Link] import RotatingFileHandler

11. Logging estruturado: o caminho mais profissional em


Rust
Aqui entramos no nível realmente moderno.

Em vez de gravar só texto, você registra campos estruturados.

[Link] 11/37
11/03/2026, 12:49 Logging Profissional Python Rust

Isso é muito útil para:

APIs
microserviços
sistemas distribuídos
observabilidade
integração com OpenTelemetry
correlação de request ID

A crate mais importante aqui é:

tracing
tracing-subscriber

12. Por que tracing é tão importante


O log é ótimo, mas tracing vai além:

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

13. Primeiro exemplo com tracing


[Link]

TOML

[dependencies]
tracing = "0.1"

[Link] 12/37
11/03/2026, 12:49 Logging Profissional Python Rust

tracing-subscriber = { version = "0.3", features = ["env-filter", "fmt"] }

Código

Rust

use tracing::{debug, error, info, warn};


use tracing_subscriber;

fn main() {
tracing_subscriber::fmt::init();

info!("Aplicação iniciada");
debug!("Detalhe de depuração");
warn!("Aviso importante");
error!("Erro de processamento");
}

Executando com filtro

PowerShell

PowerShell

$env:RUST_LOG="debug"
cargo run

ou, com tracing , geralmente:

PowerShell

$env:RUST_LOG="trace"
cargo run

Muitas configurações modernas usam RUST_LOG com EnvFilter .

14. Logging estruturado de verdade com campos


Exemplo

Rust

use tracing::{info, error};


use tracing_subscriber::FmtSubscriber;

[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");

let user_id = 42;


let email = "usuario@[Link]";

info!(user_id = user_id, email = email, "Usuário autenticado");


error!(user_id = user_id, code = 500, "Erro interno");
}

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.

Paralelo em Python com extra

Python Executar

[Link](
"Usuário autenticado",
extra={"user_id": 42, "email": "usuario@[Link]"}
)

Mas em Rust com tracing , isso fica mais natural e poderoso.

15. Saída em JSON


Produção moderna frequentemente usa JSON.

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();

info!(user_id = 10, action = "login", success = true, "evento de autenticação


}

 

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"
}

Quando usar JSON


Use quando o log vai para:
Docker
Kubernetes
Loki
Elastic Stack
Datadog
Cloud logging

Quando usar texto legível


Use quando:
CLI
ferramenta local

[Link] 15/37
11/03/2026, 12:49 Logging Profissional Python Rust

desenvolvimento
debugging manual

16. Spans: o diferencial do tracing


Esse é um dos conceitos mais importantes do Rust moderno.

Um span representa um contexto de execução.

Exemplo: “processando pedido”, “requisição HTTP”, “transação de banco”.

Exemplo

Rust

use tracing::{info, info_span};


use tracing_subscriber::fmt;

fn main() {
fmt().init();

let span = info_span!("processar_pedido", pedido_id = 123, cliente_id = 77);


let _guard = [Link]();

info!("Validando pedido");
info!("Calculando frete");
info!("Pedido concluído");
}

 

Todos esses logs acontecem dentro do contexto do pedido.

Python paralelo conceitual


Em Python puro, isso não é tão natural no logging básico.
Você acaba precisando de:
LoggerAdapter

contextvars

structlog

middleware

Em Rust, tracing já foi desenhado para isso.

[Link] 16/37
11/03/2026, 12:49 Logging Profissional Python Rust

17. Instrumentando funções com #[instrument]


Muito elegante.

Exemplo

Rust

use tracing::{info, instrument};


use tracing_subscriber::fmt;

#[instrument]
fn somar(a: i32, b: i32) -> i32 {
info!("Executando soma");
a + b
}

fn main() {
fmt().init();

let resultado = somar(10, 20);


info!(resultado = resultado, "Resultado calculado");
}

O que acontece
O #[instrument] cria automaticamente um span com os argumentos da função.

Então você ganha contexto como:

nome da função
parâmetros
tempo de execução potencialmente observável
rastreabilidade

Para isso, no [Link]

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

 

Mas em Rust isso é muito mais integrado.

18. Ignorando parâmetros sensíveis com skip


Muito importante em produção.

Exemplo

Rust

use tracing::instrument;

#[instrument(skip(password))]
fn autenticar(usuario: &str, password: &str) -> bool {
usuario == "admin" && password == "123"
}

Assim o password não vai para o log.

Também dá para customizar

Rust

#[instrument(name = "login_usuario", skip(password))]


fn autenticar(usuario: &str, password: &str) -> bool {
usuario == "admin" && password == "123"
}

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

dados pessoais sensíveis


segredo de sessão

19. Logging de erro em Rust


Rust tem uma cultura muito forte de erros com Result .

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)

20. Logging com contexto de erro


Em Rust, é muito comum enriquecer o erro.

Exemplo com tracing

Rust

use tracing::{error, info};

fn dividir(a: i32, b: i32) -> Result<i32, String> {


if b == 0 {
return Err("divisão por zero".into());
}

[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:

erro = %e → usa Display


erro = ?e → usa Debug

Isso é extremamente útil.

21. % e ? em tracing
Exemplo

Rust

use tracing::info;

#[derive(Debug)]
struct Usuario {
id: u32,
nome: String,
}

fn main() {
tracing_subscriber::fmt::init();

let user = Usuario {


id: 1,
nome: "Ana".to_string(),
};

info!(usuario = ?user, "Estrutura completa via Debug");

[Link] 20/37
11/03/2026, 12:49 Logging Profissional Python Rust

info!(nome = %[Link], "Somente o nome via Display");


}

Resumo
?campo → formato Debug
%campo → formato Display

22. Logging condicional e custo de performance


Em Python, gerar mensagem de log pode custar processamento.

Por isso se usa:

Python Executar

[Link]("valor=%s", valor)

e não:

Python Executar

[Link](f"valor={valor}")

porque no segundo caso a string é montada antes.

Em Rust
As macros de logging também ajudam a evitar custo desnecessário quando o nível está
desabilitado.

Rust

debug!("valor = {}", calculo_caro());

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

use log::{debug, log_enabled, Level};

[Link] 21/37
11/03/2026, 12:49 Logging Profissional Python Rust

fn calculo_caro() -> String {


println!("Executando cálculo caro...");
"resultado complexo".to_string()
}

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())

Essa correlação é excelente para mentalidade de performance.

23. Logging em bibliotecas Rust


Aqui existe uma regra importante.

Se você está criando uma biblioteca:


use log ou tracing
não inicialize o logger dentro da biblioteca

Quem deve configurar o logger é a aplicação final.

Exemplo correto em biblioteca

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();
}

Em Python, a mesma boa prática existe


Bibliotecas não devem chamar basicConfig() de forma invasiva.

24. Logging em aplicações assíncronas com Tokio


Se você entrar em Rust web/backend, isso importa muito.

Exemplo com tracing

Rust

use tracing::{info, instrument};


use tracing_subscriber::EnvFilter;

#[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"] }

Por que tracing é melhor em async?


Porque ele lida melhor com:

[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

No ecossistema async Rust, tracing virou praticamente padrão.

25. Logging em frameworks web Rust


Em frameworks como:
axum

actix-web
warp

o mais comum é tracing .

Exemplo mental em uma API


Você quer logar:
método HTTP
rota
status code
latency
request id
user id
erro de handler

Com tracing , isso encaixa muito bem.

Em Python, isso seria algo semelhante a combinar:

logging

middleware do FastAPI/Flask/Django
structlog

observabilidade APM

26. Logging estruturado de requisições


Exemplo conceitual

[Link] 24/37
11/03/2026, 12:49 Logging Profissional Python Rust

Rust

use tracing::{info, instrument};

#[instrument(fields(request_id = %request_id, user_id = %user_id))]


fn processar_requisicao(request_id: &str, user_id: u64) {
info!("Validando entrada");
info!("Buscando dados");
info!("Resposta enviada");
}

fn main() {
tracing_subscriber::fmt().init();
processar_requisicao("req-123", 42);
}

Esse tipo de contexto é exatamente o que produção exige.

27. Formatação de logs: texto humano vs JSON


Texto humano
Bom para:
desenvolvimento
terminal
CLI
debugging local

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

28. Exemplo de configuração dual


Desenvolvimento

Rust

tracing_subscriber::fmt()
.with_env_filter("debug")
.pretty()
.init();

Produção

Rust

tracing_subscriber::fmt()
.json()
.with_env_filter("info")
.init();

29. Logging com target


Você pode usar target customizado.

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

Isso ajuda a separar domínios:

auth

db

http
payment

30. Logging por ambiente


Muito comum em produção.

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

31. Logger global: cuidado importante


Em Rust, o logger global normalmente só pode ser inicializado uma vez.

Exemplo problemático

Rust

env_logger::init();
env_logger::init(); // erro/panic dependendo do caso

Solução para testes ou cenários especiais


[Link] 27/37
11/03/2026, 12:49 Logging Profissional Python Rust

Rust

let _ = env_logger::builder().is_test(true).try_init();

32. Logging em testes


Muito útil.

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);
}
}

Com cargo test

PowerShell

$env:RUST_LOG="info"
cargo test -- --nocapture

Paralelo Python
Seria como habilitar logging dentro de testes pytest ou unittest .

33. println! vs dbg! vs logging


Esse ponto confunde muito quem está começando.

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

println! → CLI simples/saída de usuário


log / tracing → engenharia profissional

34. Quando usar log e quando usar tracing


Use log quando:
projeto simples
CLI pequena
[Link] 29/37
11/03/2026, 12:49 Logging Profissional Python Rust

biblioteca genérica
você quer compatibilidade ampla
logging textual já resolve

Use tracing quando:


API/backend
async com Tokio
precisa de contexto por request
quer campos estruturados
precisa de observabilidade moderna
vai integrar com OpenTelemetry

Regra prática excelente


Para projetos novos de backend em Rust, eu recomendaria:
tracing como padrão

log + env_logger para exemplos simples e CLIs pequenas

35. Integração entre log e tracing


Às vezes você usa crates que emitem log , mas seu app usa tracing .

Isso é comum.

Existem pontes entre esses mundos, como tracing-log .

Assim você consegue centralizar observabilidade.

36. Exemplo profissional completo com tracing


Vamos montar algo mais realista.

[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

use tracing::{error, info, instrument, warn};


use tracing_subscriber::{fmt, EnvFilter};

#[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());
}

if usuario == "admin" && senha == "123" {


info!("Autenticação bem-sucedida");
Ok(42)
} else {
error!("Credenciais inválidas");
Err("falha de autenticação".into())
}
}

fn main() {
fmt()
.with_env_filter(EnvFilter::from_default_env())
.with_target(true)
.init();

match autenticar("admin", "123") {


Ok(user_id) => info!(user_id = user_id, "Login concluído"),
Err(e) => error!(erro = %e, "Falha no login"),
}
}

Executando

PowerShell

$env:RUST_LOG="info"
cargo run

37. O paralelo desse exemplo em Python

[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")

def autenticar(usuario: str, senha: str) -> int:


[Link]("Iniciando autenticação")

if not usuario:
[Link]("Usuário vazio")
raise ValueError("usuário inválido")

if usuario == "admin" and senha == "123":


[Link]("Autenticação bem-sucedida")
return 42
else:
[Link]("Credenciais inválidas")
raise ValueError("falha de autenticação")

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

38. Boas práticas profissionais em Rust


1. Não use log como substituto de tratamento de erro
Errado:

[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

2. Evite log duplicado


Se uma função loga o erro e a camada superior também loga, você polui os logs.

3. Não logue segredo


Nunca.

4. Use níveis corretamente


error não é para qualquer coisa

debug não deve poluir produção


trace é quase “wiretap interno”

5. Logue eventos de negócio importantes


Exemplos:
pedido criado
pagamento aprovado
autenticação falhou
job começou/terminou

6. Prefira campos estruturados


Melhor:

Rust

info!(user_id = 42, action = "login", "Evento de autenticação");

Pior:

Rust

info!("Usuário 42 fez login");

O primeiro é muito melhor para busca e agregação.


[Link] 33/37
11/03/2026, 12:49 Logging Profissional Python Rust

7. Adicione correlação
Use:

request id
user id
job id
trace id

39. Exemplo ruim vs exemplo bom


Ruim

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"
);

Agora seu log tem valor operacional real.

40. Padrão recomendado para você, vindo de Python


Se você está aprendendo Rust e quer evoluir rápido sem se perder, eu te recomendaria
esta trilha:

Etapa 1 — aprender o básico


Use:

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

Etapa 2 — aprender produção moderna


Migre para:

tracing

tracing-subscriber

para entender:

campos estruturados
spans
#[instrument]

async
JSON

Etapa 3 — produção robusta


Depois avance para:
arquivo com rotação
observabilidade
OpenTelemetry
logs centralizados

41. Template mínimo recomendado


Para CLI simples

Rust

use log::{info, warn};

fn main() {
env_logger::init();

info!("Programa iniciado");
warn!("Exemplo de aviso");
}

Para backend moderno


[Link] 35/37
11/03/2026, 12:49 Logging Profissional Python Rust

Rust

use tracing::info;
use tracing_subscriber::{fmt, EnvFilter};

fn main() {
fmt()
.with_env_filter(EnvFilter::from_default_env())
.json()
.init();

info!(service = "api", version = "1.0.0", "Serviço iniciado");


}

42. Resumo decisivo


Python
logging mais centralizado na stdlib
muito bom para uso tradicional
estruturado normalmente exige bibliotecas extras

Rust
abordagem modular por crates
log resolve logging clássico
tracing resolve logging/telemetria modernos muito melhor

para sistemas async e backend, tracing é o caminho mais forte

43. Mapa mental final


Se pensar em Python:
logging → equivalente conceitual de log

Formatter → builder/formatação do logger


Handler → backend/destino

LoggerAdapter / structlog → mundo parecido com tracing

extra/contextvars → parecido com fields/spans

Se pensar em Rust:
println! → saída simples

[Link] 36/37
11/03/2026, 12:49 Logging Profissional Python Rust

dbg! → depuração rápida

log → logging clássico

env_logger → backend simples para terminal

fern / flexi_logger → arquivo e configuração avançada

tracing → logging estruturado e observabilidade profissional

44. Minha recomendação prática para você


Como você já vem de Python, eu seguiria assim:
1. aprenda log + env_logger em 1 dia
2. passe para tracing logo em seguida
3. faça exemplos com CLI, arquivo, JSON e #[instrument]
4. depois aplique em um mini projeto web com Tokio/Axum

Esse caminho te dá base e maturidade rápido.

Posso montar na próxima resposta um projeto completo de exemplo em Rust,


organizado em pastas, mostrando:

[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

Isso seria o melhor próximo passo para consolidar de verdade.

[Link] 37/37

Você também pode gostar