---
title: "Logging: O que É e Como Funciona | Python Brasil"
url: "https://python.dev.br/glossario/logging/"
markdown_url: "https://python.dev.br/glossario/logging.MD"
description: "Domine o modulo logging em Python: niveis, handlers, formatters, configuracao avancada e boas praticas para registrar eventos na sua aplicacao."
date: "2026-01-10"
author: ""
---

# Logging: O que É e Como Funciona | Python Brasil

Domine o modulo logging em Python: niveis, handlers, formatters, configuracao avancada e boas praticas para registrar eventos na sua aplicacao.


## O que e Logging?

**Logging** e o mecanismo de registrar eventos que ocorrem durante a execucao de um programa. O modulo `logging` da biblioteca padrao do Python oferece um sistema flexivel e configuravel para emitir mensagens de log com diferentes niveis de severidade. Diferente de `print()`, o logging permite controlar o que e registrado, para onde vai (arquivo, console, servicos externos) e em que formato, sem modificar o codigo da aplicacao.

Em aplicacoes profissionais, logging e essencial para depuracao, monitoramento, auditoria e diagnostico de problemas em producao.

## Niveis de Log

O Python define cinco niveis padrao de severidade, em ordem crescente:

```python
import logging

# DEBUG — informacoes detalhadas para diagnostico
logging.debug('Variavel x = 42')

# INFO — confirmacao de que as coisas estao funcionando
logging.info('Servidor iniciado na porta 8000')

# WARNING — algo inesperado ou potencial problema
logging.warning('Disco com 90%% de uso')

# ERROR — erro que impede uma funcionalidade
logging.error('Falha ao conectar ao banco de dados')

# CRITICAL — erro grave que pode encerrar o programa
logging.critical('Memoria insuficiente, encerrando')
```

## Configuracao Basica

```python
import logging

# Configuracao rapida
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    datefmt='%Y-%m-%d %H:%M:%S',
)

# Usando
logging.info('Aplicacao iniciada')
logging.warning('Configuracao nao encontrada, usando padrao')
```

## Loggers, Handlers e Formatters

O sistema de logging do Python e composto por tres componentes principais que trabalham juntos.

```python
import logging

# Criar logger com nome (geralmente __name__)
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)

# Formatter — define o formato da mensagem
formatter = logging.Formatter(
    '%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    datefmt='%Y-%m-%d %H:%M:%S',
)

# Handler para console
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.INFO)
console_handler.setFormatter(formatter)

# Handler para arquivo
file_handler = logging.FileHandler('app.log', encoding='utf-8')
file_handler.setLevel(logging.DEBUG)
file_handler.setFormatter(formatter)

# Adicionar handlers ao logger
logger.addHandler(console_handler)
logger.addHandler(file_handler)

# Usar o logger
logger.debug('Informacao detalhada (so vai para o arquivo)')
logger.info('Informacao geral (console e arquivo)')
logger.error('Erro encontrado (console e arquivo)')
```

## Logging com Rotacao de Arquivos

```python
import logging
from logging.handlers import RotatingFileHandler, TimedRotatingFileHandler

logger = logging.getLogger('minha_app')
logger.setLevel(logging.INFO)

# Rotacao por tamanho
handler_tamanho = RotatingFileHandler(
    'app.log',
    maxBytes=5 * 1024 * 1024,  # 5 MB
    backupCount=5,              # manter 5 arquivos antigos
    encoding='utf-8',
)

# Rotacao por tempo
handler_tempo = TimedRotatingFileHandler(
    'app.log',
    when='midnight',     # rotacionar a meia-noite
    interval=1,          # a cada 1 dia
    backupCount=30,      # manter 30 dias
    encoding='utf-8',
)

formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
handler_tamanho.setFormatter(formatter)
logger.addHandler(handler_tamanho)
```

## Configuracao com Dicionario

```python
import logging
import logging.config

config = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'padrao': {
            'format': '%(asctime)s - %(name)s - %(levelname)s - %(message)s',
        },
        'simples': {
            'format': '%(levelname)s - %(message)s',
        },
    },
    'handlers': {
        'console': {
            'class': 'logging.StreamHandler',
            'level': 'INFO',
            'formatter': 'simples',
        },
        'arquivo': {
            'class': 'logging.handlers.RotatingFileHandler',
            'level': 'DEBUG',
            'formatter': 'padrao',
            'filename': 'app.log',
            'maxBytes': 10485760,
            'backupCount': 5,
        },
    },
    'loggers': {
        '': {  # root logger
            'level': 'DEBUG',
            'handlers': ['console', 'arquivo'],
        },
    },
}

logging.config.dictConfig(config)
logger = logging.getLogger(__name__)
```

## Logging Estruturado

```python
import logging
import json

class JsonFormatter(logging.Formatter):
    """Formatter que gera logs em JSON."""

    def format(self, record):
        log_data = {
            'timestamp': self.formatTime(record),
            'level': record.levelname,
            'logger': record.name,
            'message': record.getMessage(),
        }
        if record.exc_info:
            log_data['exception'] = self.formatException(record.exc_info)
        if hasattr(record, 'extra_data'):
            log_data['data'] = record.extra_data
        return json.dumps(log_data, ensure_ascii=False)

# Configurar
logger = logging.getLogger('api')
handler = logging.StreamHandler()
handler.setFormatter(JsonFormatter())
logger.addHandler(handler)
logger.setLevel(logging.INFO)

# Usar
logger.info('Requisicao recebida', extra={'extra_data': {'metodo': 'GET', 'path': '/api/users'}})
```

## Logging em Funcoes e Classes

```python
import logging

logger = logging.getLogger(__name__)

def processar_pedido(pedido_id: int) -> dict:
    """Processa um pedido com logging adequado."""
    logger.info('Iniciando processamento do pedido %d', pedido_id)

    try:
        # logica de processamento
        logger.debug('Validando pedido %d', pedido_id)
        resultado = {'pedido_id': pedido_id, 'status': 'processado'}
        logger.info('Pedido %d processado com sucesso', pedido_id)
        return resultado

    except ValueError as e:
        logger.warning('Dados invalidos no pedido %d: %s', pedido_id, e)
        raise

    except Exception as e:
        logger.exception('Erro inesperado ao processar pedido %d', pedido_id)
        raise

class ServicoEmail:
    def __init__(self):
        self.logger = logging.getLogger(f'{__name__}.{self.__class__.__name__}')

    def enviar(self, destinatario: str, assunto: str):
        self.logger.info('Enviando email para %s: %s', destinatario, assunto)
```

## Erros Comuns

O erro mais frequente e usar `print()` em vez de logging para depuracao, tornando dificil controlar e filtrar as mensagens. Outro erro e chamar `logging.basicConfig()` multiplas vezes esperando que reconfigure — ele so funciona na primeira chamada. Tambem e comum incluir dados sensiveis como senhas e tokens em mensagens de log. Usar `logging.exception()` fora de um bloco `except` e outro erro, pois ele espera informacoes de excecao ativa. Formatar a string antes de passar para o logger com f-strings (`logger.info(f'valor: {x}')`) e menos eficiente que usar formatacao preguicosa (`logger.info('valor: %s', x)`).

## Boas Praticas

Use `logging.getLogger(__name__)` para criar loggers com nomes hierarquicos. Prefira formatacao preguicosa (`%s`) em vez de f-strings em chamadas de log. Use `logger.exception()` dentro de blocos `except` para incluir o traceback. Configure logging no ponto de entrada da aplicacao, nao dentro de bibliotecas. Nunca registre dados sensiveis. Use niveis de log apropriados — DEBUG para desenvolvimento, INFO para operacao normal, WARNING para situacoes inesperadas.

## Quando Usar

Logging deve ser usado em toda aplicacao que va para producao. Substitua `print()` por logging desde o inicio do projeto. Em APIs web, registre cada requisicao com tempo de resposta. Em scripts de processamento, registre progresso e erros. Em bibliotecas, use logging mas deixe a configuracao para a aplicacao consumidora.

> **Veja também**: explore como outras linguagens abordam tópicos similares em <a href="https://golang.com.br/blog/" target="_blank" rel="noopener" onclick="umami.track('portfolio-site-click', {source: 'python.dev.br', target: 'golang.com.br', content: 'glossario-logging'})">golang.com.br</a> e <a href="https://rustlang.com.br/blog/" target="_blank" rel="noopener" onclick="umami.track('portfolio-site-click', {source: 'python.dev.br', target: 'rustlang.com.br', content: 'glossario-logging'})">rustlang.com.br</a>.
