O módulo logging da biblioteca padrão permite construir um sistema de registro que envia mensagens tanto para a saída padrão quanto para arquivos, com níveis de severidade configuráveis e formatação flexível.
Configuração passo a passo
Cada componente do fluxo de registro tem uma responsabilidade bem definida:
- Logger: ponto de entrada da aplicação, responsável por receber os eventos.
- Handler: define onde a mensagem será enviada (arquivo, console, rede, etc.).
- Formatter: especifica como a mensagem será apresentada.
- Level: filtro que decide se uma mensagem deve ou não ser processada.
import logging
# Criar um logger nomeado para evitar conflitos
registrador = logging.getLogger('meu_app')
registrador.setLevel(logging.DEBUG) # Captura tudo a partir de DEBUG
# Handler para arquivo
manipulador_arquivo = logging.FileHandler('app.log', encoding='utf-8')
manipulador_arquivo.setLevel(logging.DEBUG)
# Handler para console
manipulador_console = logging.StreamHandler()
manipulador_console.setLevel(logging.INFO)
# Definir formato desejado
formatador = logging.Formatter(
fmt='%(asctime)s [%(levelname)s] %(name)s: %(message)s',
datefmt='%Y-%m-%d %H:%M:%S'
)
# Associar o formato aos handlers
manipulador_arquivo.setFormatter(formatador)
manipulador_console.setFormatter(formatador)
# Registrar handlers no logger
registrador.addHandler(manipulador_arquivo)
registrador.addHandler(manipulador_console)
# Uso
registrador.debug('Iniciando processamento')
registrador.info('Processo concluído')
Entendendo os níveis
A hierarquia de níveis, do menos ao mais severo, é:
NOTSET < DEBUG < INFO < WARNING < ERROR < CRITICAL
Quando um logger é configurado com INFO, apanas mensagens INFO ou superiores serão processadas; DEBUG será ignorado.
Exemplo prático com rotação
Para evitar arquivos gigantes, use RotatingFileHandler:
from logging.handlers import RotatingFileHandler
rotativo = RotatingFileHandler(
'servidor.log',
maxBytes=5*1024*1024, # 5 MB
backupCount=3,
encoding='utf-8'
)
rotativo.setLevel(logging.WARNING)
rotativo.setFormatter(formatador)
registrador.addHandler(rotativo)
Corrigindo erros comuns
O trecho abaixo contém um erro de digitação no campo do formatador:
import logging
log = logging.getLogger('exemplo')
log.setLevel(logging.DEBUG)
arq = logging.FileHandler('erro.log')
arq.setLevel(logging.DEBUG)
console = logging.StreamHandler()
console.setLevel(logging.DEBUG)
# ERRO: "levlename" → correto é "levelname"
form = logging.Formatter('%(asctime)s - %(name)s - %(levlename)s - %(message)s')
A execução levanta KeyError: 'levlename'. A correção é simples:
form = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
Com essa abordagem, seu aplicativo terá rastreamento detalhado tanto em ambiente de desenvolvimento quanto em produção, facilitando diagnósticos e auditoria.