Registro estruturado em Python: console e arquivo simultâneos

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.

Tags: Python Logging RotatingFileHandler StreamHandler debugging

Publicado em 9-6 07:29