Pular para o conteúdo principal

Tutorial de registro em log Python: Configuração sem precisar mexer em nada

Aprenda Loguru, a estrutura de registro mais fácil do Python. Controle a rotação de arquivos mestre, o registro estruturado, o tratamento de exceções e os coletores personalizados sem precisar configurar nada.
Atualizado 14 de ago. de 2025  · 10 min lido

Você passou toda a sua vida de programador depurando com instruções “ print() ”. Talvez você já tenha experimentado o módulo de registro do Python uma ou duas vezes, mas voltou para os prints porque eles são mais simples.

Na verdade, tem algo melhor que é tão fácil de usar quanto.

As declarações de impressão não podem ser salvas em arquivos nem ativadas ou desativadas facilmente. O registro integrado do Python pode fazer isso, mas precisa escrever um código de configuração que é mais longo que o seu programa.

O Loguru tem uma abordagem diferente: registrar deve ser tão fácil quanto imprimir, mas muito mais útil. Você tem cores no seu terminal, carimbos de data e hora automáticos e a possibilidade de salvar tudo em arquivos sem precisar escrever uma única linha de configuração.

Neste tutorial, vou mostrar exemplos práticos que fazem com que o registro em log pareça natural, em vez de algo chato. Você vai ver recursos que provavelmente não sabia que existiam, usando padrões de código que realmente facilitam a depuração.

Se você é novo na depuração do Python ou quer reforçar suas habilidades básicas, construir fundamentos sólidos em Python vai te ajudar a entender quando e por que o registro em log é necessário.

Começando com o Loguru: Magia sem configuração

Pra instalar o Loguru, é só usar um comando:

pip install loguru

Com o módulo logging normal, você precisa configurar manipuladores, formatadores e tudo mais antes de ver uma única mensagem de log.

Para uma comparação mais detalhada das abordagens de registro integradas ao Python, confira este tutorial completo sobre registro que fala sobre os métodos tradicionais.

Com o Loguru, basta importar e começar a registrar:

from loguru import logger

# Instead of print("Processing user data...")
logger.info("Processing user data...")

# Instead of print(f"Found {count} records")
logger.info("Found {} records", count)

A saída aparece no seu terminal com cores, carimbos de data/hora e níveis de log automaticamente. Não precisa de configuração.

Saída do console Loguru mostrando mensagens de log coloridas com carimbos de data/hora e diferentes níveis de log no terminal Python

Digamos que você está criando um scraper de web simples. Veja como a depuração muda:

import requests
from loguru import logger

def scrape_website(url):
   logger.info("Starting scrape for {}", url)
  
   response = requests.get(url)
   logger.debug("Response status: {}", response.status_code)
  
   if response.status_code == 200:
       logger.success("Successfully scraped {} characters", len(response.text))
       return response.text
   else:
       logger.error("Failed to scrape {}: status {}", url, response.status_code)
       return None

Repara nos diferentes níveis de log (info, debug, success, error) e na formatação com chaves. Tudo funciona na hora, sem precisar de arquivos de configuração ou código de instalação.

Registro e rotação de arquivos simplificados

Quando você tá depurando com a saída do console, você perde tudo assim que fecha o terminal. Você não pode procurar o que rolou há uma hora atrás e, se o seu script travar durante a noite, não vai ter como saber o que deu errado. Também não dá pra compartilhar facilmente a saída da depuração com seus colegas de equipe quando precisar de ajuda.

O registro em arquivo resolve isso salvando tudo de forma permanente.

O registro tradicional faz você escrever código de configuração para definir manipuladores de arquivos. Você precisa especificar os caminhos dos arquivos, criar diretórios e lidar com permissões. Com o Loguru, adicionar o registro de arquivos é literalmente uma linha:

from loguru import logger

# Add file logging alongside console output
logger.add("app.log")

logger.info("This appears in both console and file")
logger.error("So does this error message")

Agora tudo é salvo em app.log, mas continua aparecendo no seu terminal.

Mas os arquivos de log ficam enormes com o tempo. Um aplicativo web que fica ligado por dias pode gerar gigabytes de logs que acabam enchendo o disco. A rotação de arquivos resolve isso criando automaticamente novos arquivos de log quando certas condições são atendidas. O arquivo antigo é renomeado com uma data e hora, e um novo arquivo é criado:

# When app.log reaches 10 MB, it becomes app_2024-07-15_14-30-25.log
# and a new empty app.log starts
logger.add("app.log", rotation="10 MB")

# Or start a new file every day at midnight
logger.add("app.log", rotation="00:00")

Os carimbos de data e hora padrão funcionam, mas geralmente estão em UTC ou são difíceis de ler. O Loguru te deixa personalizar os formatos de data e hora do jeito que você quiser:

# Custom timestamp format that's easier to read
logger.add("app.log",
         format="{time:YYYY-MM-DD HH:mm:ss} | {level} | {message}",
         rotation="1 day")

Para sistemas de produção, você precisa de mais controle sobre arquivos antigos. O registro de produção precisa seguir as melhores práticas do Python pra garantir que seus registros sejam fáceis de manter e seguros. Sem gerenciamento, os arquivos de log ficam se acumulando e ocupando espaço de armazenamento:

# Keep only the last 10 rotated files, compress the rest
logger.add("production.log",
         rotation="50 MB",     # New file every 50MB
         retention=10,         # Keep only 10 old files
         compression="zip")    # Compress rotated files

Vamos ver isso num cenário realista. Você está criando um pipeline de dados que processa vários arquivos CSV todas as noites, limpando e validando os dados dos clientes antes de carregá-los no seu banco de dados. Você precisa acompanhar quais arquivos foram processados com sucesso e detectar quaisquer problemas de qualidade dos dados:

import pandas as pd
from loguru import logger

# Production-ready file logging setup
logger.add("data_processing_{time:YYYY-MM-DD}.log",
         rotation="00:00",        # New file daily
         retention="1 week",      # Keep 1 week of logs
         format="{time:YYYY-MM-DD HH:mm:ss} | {level} | {message}")

def process_csv_files(file_list):
   logger.info("Starting batch processing of {} files", len(file_list))
  
   for filename in file_list:
       try:
           df = pd.read_csv(filename)
           logger.info("Loaded {} with {} rows", filename, len(df))
          
           # Your processing logic here
           processed_df = df.dropna()
          
           logger.success("Processed {} - kept {} rows", filename, len(processed_df))
          
       except Exception as e:
           logger.error("Failed to process {}: {}", filename, str(e))
  
   logger.info("Batch processing complete")

Os seus registros são salvos com carimbos de data e hora legíveis, os arquivos são rodados automaticamente e os registros antigos são limpos automaticamente. Você pode ver o que rolou dias depois ou mandar arquivos de log para os colegas quando estiver resolvendo problemas.

Registro estruturado para aplicativos modernos

Quando você tá rodando um aplicativo web, seus logs ficam rapidinho uma bagunça de informações misturadas. As ações do usuário, consultas ao banco de dados, chamadas de API e erros se misturam em uma parede de texto. Não é fácil filtrar usuários específicos, rastrear solicitações individuais ou analisar automaticamente registros para sistemas de monitoramento.

Os aplicativos baseados em dados se beneficiam especialmente do registro estruturado. Se você trabalha com pipelines de dados ou análises, desenvolver habilidades de analista de dados ajuda a entender quais informações devem ser capturadas nos seus registros.

O registro tradicional baseado em strings piora ainda mais a situação. Todas as mensagens de log são só texto, então extrair dados que fazem sentido precisa de padrões complexos de expressões regulares ou uma busca manual.

O registro estruturado muda isso, tratando as entradas do registro como objetos de dados em vez de só texto. Cada entrada do log vira um registro estruturado com campos pesquisáveis, facilitando a consulta e a análise programática.

Registro estruturado em JSON com serialize=True

O Loguru facilita o registro estruturado com a opção “ serialize=True ” (Log de eventos):

from loguru import logger

# Enable JSON structured logging
logger.add("api.log", serialize=True)

logger.info("User login", user_id=123, ip_address="192.168.1.1")
logger.error("Payment failed", user_id=123, amount=99.99, error_code="INSUFFICIENT_FUNDS")

O parâmetro " serialize=True " diz ao Loguru para mostrar JSON em vez de texto simples. Em vez de frases legíveis, seu arquivo de log agora tem dados estruturados:

{"text": "User login", "record": {"time": "2024-07-15T14:30:25", "level": {"name": "INFO"}, "extra": {"user_id": 123, "ip_address": "192.168.1.1"}}}

Esse formato funciona super bem com ferramentas de análise de log que podem procurar e filtrar dados JSON automaticamente.

Ligação de contexto

Mas os aplicativos web precisam de mais do que só dados estruturados. Você precisa de contexto que conecte entradas de log relacionadas. Quando você tá processando uma solicitação de usuário, é legal que todos os registros relacionados tenham informações em comum, tipo o ID do usuário ou o ID da sessão.

A ligação de contexto resolve isso juntando informações persistentes ao seu registrador usando logger.bind():

from loguru import logger

def process_user_order(user_id, order_data):
   # Create a logger with attached context
   order_logger = logger.bind(user_id=user_id, order_id=order_data['id'])
  
   order_logger.info("Starting order processing")
   order_logger.debug("Validating payment method", method=order_data['payment'])
   order_logger.info("Order processing complete", total=order_data['total'])

Agora, todos os registros de order_logger incluem automaticamente user_id e order_id, facilitando o rastreamento de todos os registros relacionados a um pedido específico.

Várias pias para diferentes saídas

Os aplicativos modernos também precisam de diferentes saídas de log para diferentes finalidades. Você pode querer logs de console legíveis durante o desenvolvimento, mas logs JSON para monitoramento de produção. No Loguru, cada destino de saída é chamado de “sink” — pense nisso como um lugar para onde as mensagens de log vão.

O Loguru permite adicionar vários sinks com formatos e regras diferentes:

from loguru import logger
import sys

# Remove the default console output
logger.remove()

# Sink 1: Human-readable console for development
logger.add(sys.stdout,
         level="DEBUG",
         format="<green>{time:HH:mm:ss}</green> | {level} | {message}")

# Sink 2: JSON file for production monitoring
logger.add("app.log",
         serialize=True,
         level="INFO")

# Sink 3: Error-only file for alerts
logger.add("errors.log",
         level="ERROR")

A chamada logger.remove() tira a saída padrão do console do Loguru, pra você poder configurar a sua própria. Cada logger.add() cria um novo coletor com suas próprias regras sobre o que é registrado e como é formatado.

Agora, as mesmas instruções de log geram resultados diferentes:

logger.debug("Processing started")      # Only appears in console
logger.info("User data loaded")         # Appears in console and app.log
logger.error("Database connection failed")  # Appears in all three places

Exemplo completo do Loguru: Sistema de registro de usuários

Vamos ver isso com um exemplo mais simples e realista do uso do Loguru — um sistema básico de registro de usuários:

from loguru import logger
import sys

# Set up multiple outputs
logger.remove()
logger.add(sys.stdout, level="INFO", format="{time:HH:mm:ss} | {message}")
logger.add("user_registration.log", serialize=True, level="INFO")
logger.add("errors.log", level="ERROR")

def register_user(email, password):
   # Create logger with user context
   user_logger = logger.bind(email=email)
  
   user_logger.info("Starting user registration")
  
   # Validate email
   if "@" not in email:
       user_logger.error("Invalid email format")
       return False
  
   # Check if user exists
   user_logger.debug("Checking if user already exists")
  
   # Simulate password hashing
   user_logger.debug("Hashing password")
  
   # Save to database
   user_logger.info("Saving user to database")
   user_logger.success("User registration completed")
  
   return True

# Usage
register_user("john@example.com", "secure123")

Essa configuração te dá uma saída legível no console durante o desenvolvimento, logs JSON estruturados para monitoramento automático e logs de erros separados para alertas. O método ` bind() ` garante que todos os registros para cada registro de usuário incluam o endereço de e-mail, facilitando muito a depuração.

Tratamento de exceções Loguru

Quando seu código trava, você geralmente recebe um rastreamento básico da pilha que informa onde ocorreu o erro, mas não explica muito sobre o motivo. Você perde os valores das variáveis no momento da falha, o que dificulta entender o que deu errado. O tratamento tradicional de exceções também exige que você coloque tudo em blocos try-catch e registre manualmente cada exceção.

Isso fica bem chato quando a gente tá tentando resolver problemas na produção. Os usuários relatam erros, mas você não consegue reproduzi-los porque não tem o contexto que existia quando o erro ocorreu.

O Loguru resolve isso com captura automática de exceções e rastreamentos aprimorados que mostram exatamente o que estava acontecendo no seu código quando algo deu errado.

Captura automática de exceções com @logger.catch

O decorador ` @logger.catch ` pega automaticamente qualquer exceção que rolar numa função e registra com todo o contexto. Decoradores como @logger.catch são um conceito intermediário do Python que podem mudar a forma como você lida com erros em todo o seu código:

from loguru import logger

@logger.catch
def divide_numbers(a, b):
   result = a / b
   return result

# This automatically logs the exception with full traceback
result = divide_numbers(10, 0)

Em vez de o seu programa travar com uma mensagem de erro básica, o Loguru captura a exceção e registra-a com informações detalhadas, enquanto o seu programa continua a funcionar. O decorador funciona em qualquer função — métodos de classe, funções assíncronas ou funções normais.

Rastreamentos aprimorados com inspeção de variáveis

Mas o Loguru vai além com rastreamentos aprimorados que mostram os valores das variáveis em cada nível da pilha de chamadas. Esse recurso é chamado de “diagnóstico” e é como ter um depurador embutido nos seus registros:

from loguru import logger

# Enable enhanced tracebacks
logger.add("debug.log", diagnose=True)

@logger.catch
def process_user_data(users):
   for user in users:
       age = user['age']
       if age > 0:
           years_to_retirement = 65 - age
           print(f"User {user['name']} has {years_to_retirement} years to retirement")

# When this crashes, you'll see the exact values of 'users', 'user', and 'age'
users_data = [
   {"name": "Alice", "age": 30},
   {"name": "Bob", "age": "invalid"},  # This will cause an error
]

process_user_data(users_data)

Com o diagnose=True, quando a função trava ao tentar subtrair uma string de um número, o Loguru mostra exatamente o que estava em cada variável:

TypeError: unsupported operand type(s) for -: 'int' and 'str'

Variables values:
   users = [{"name": "Alice", "age": 30}, {"name": "Bob", "age": "invalid"}]
   user = {"name": "Bob", "age": "invalid"}
   age = "invalid"

Esse nível de detalhe torna a depuração muito mais rápida, porque você consegue ver exatamente quais dados causaram o problema.

Tratamento de exceções com consciência ambiental

Mas, os rastreamentos melhorados podem mostrar informações importantes, tipo senhas ou chaves API nos registros de produção. O Loguru te deixa controlar isso em diferentes ambientes:

from loguru import logger
import os

# Development: Full diagnostic information
if os.getenv("ENVIRONMENT") == "development":
   logger.add("app.log", diagnose=True, level="DEBUG")
else:
   # Production: Basic logging without variable inspection
   logger.add("app.log", diagnose=False, level="INFO")

@logger.catch
def authenticate_user(username, password, api_key):
   # In development, you'll see all variable values if this crashes
   # In production, sensitive data stays hidden
   if not username or not password:
       raise ValueError("Missing credentials")

Avaliação preguiçosa para desempenho

Outra coisa legal é a avaliação preguiçosa, que melhora o desempenho quando você está registrando operações que demoram muito. Às vezes, você quer registrar informações complexas, mas só se realmente ocorrer um erro:

from loguru import logger

@logger.catch
def process_large_dataset(data):
   try:
       # Some complex processing that might fail
       result = complex_calculation(data)
       return result
   except Exception as e:
       # This expensive operation only runs if there's an error
       logger.error("Processing failed with data: {data}",
                   data=lambda: expensive_data_summary(data))
       raise

def expensive_data_summary(data):
   # This function takes time to run, summarizing huge datasets
   return {"row_count": len(data), "columns": list(data.keys()), "memory_usage": data.memory_usage()}

A sintaxe ` lambda: ` cria uma função que só é chamada quando o Loguru realmente grava a mensagem de log. Se não rolar nenhum erro, o expensive_data_summary() nunca vai ser executado, economizando tempo de processamento.

Diferentes estratégias para diferentes tipos de erros

Você também pode usar diferentes estratégias de tratamento de exceções para diferentes tipos de erros:

from loguru import logger

# Configure multiple outputs for different error severities
logger.add("warnings.log", level="WARNING", filter=lambda record: record["level"].name == "WARNING")
logger.add("critical_errors.log", level="ERROR")

@logger.catch(level="ERROR")
def critical_database_operation(query):
   # Database errors get logged as ERROR level
   execute_database_query(query)

@logger.catch(level="WARNING", reraise=False)
def optional_feature(user_id):
   # Non-critical features log as WARNING and continue execution
   send_optional_notification(user_id)

def process_user_request(user_id, query):
   # Critical operation - if this fails, the whole request fails
   critical_database_operation(query)
  
   # Optional operation - if this fails, request continues
   optional_feature(user_id)

O parâmetro “ reraise=False ” diz ao Loguru para registrar a exceção, mas não a reativar, permitindo que seu programa continue. Isso é útil pra recursos opcionais que não devem atrapalhar seu fluxo de trabalho principal.

Exemplo completo: processamento de arquivos com tratamento de erros

Vamos ver um exemplo completo com um sistema de processamento de arquivos que lida com diferentes tipos de erros de maneira elegante:

from loguru import logger
import os

# Set up environment-aware logging
if os.getenv("DEBUG"):
   logger.add("file_processor.log", diagnose=True, level="DEBUG")
else:
   logger.add("file_processor.log", diagnose=False, level="INFO")

@logger.catch(reraise=False)
def validate_file_format(filename):
   if not filename.endswith(('.csv', '.json', '.xml')):
       raise ValueError(f"Unsupported file format: {filename}")

@logger.catch
def load_file_data(filename):
   logger.info("Loading file: {}", filename)
  
   # Expensive operation only logged on errors
   logger.debug("File stats: {stats}",
               stats=lambda: {"size": os.path.getsize(filename),
                             "modified": os.path.getmtime(filename)})
  
   with open(filename, 'r') as f:
       return f.read()

def process_files(file_list):
   results = []
  
   for filename in file_list:
       # Validation errors are logged but don't stop processing
       validate_file_format(filename)
      
       try:
           # Loading errors are logged and do stop processing this file
           data = load_file_data(filename)
           results.append(data)
           logger.success("Successfully processed {}", filename)
       except Exception:
           logger.error("Skipping file {} due to loading error", filename)
           continue
  
   return results

Essa configuração te dá captura automática de exceções, contexto detalhado do erro quando necessário e diferentes estratégias de tratamento para diferentes tipos de erros. Seus registros ficam bem mais úteis pra depuração, enquanto seu código continua limpo e fácil de ler.

Configuração e personalização avançadas do Loguru

À medida que suas aplicações crescem, você vai encontrar situações em que as configurações padrão do Loguru não são as mais adequadas. Talvez você precise de um nível de registro especial para métricas de negócios, queira filtrar dados confidenciais dos registros ou precise enviar alertas para o Slack quando ocorrerem erros.

A boa notícia é que o Loguru foi feito pra ser personalizado sem perder a simplicidade. Você pode estendê-lo de maneiras que exigiriam uma configuração complexa em sistemas de registro tradicionais, mantendo seu código limpo e legível.

Vamos ver as personalizações mais úteis que resolvem problemas reais que você vai encontrar em aplicativos de produção.

Níveis e cores personalizados de registro

O Loguru vem com níveis padrão como INFO, DEBUG e ERROR. Mas às vezes você precisa de algo específico para sua aplicação. Talvez você queira um nível especial para métricas de desempenho ou eventos de negócios.

É bem fácil criar níveis de log personalizados:

from loguru import logger

# Add a custom level for business metrics
logger.level("METRIC", no=38, color="<yellow>", icon="📊")

# Add a custom level for security events
logger.level("SECURITY", no=45, color="<red><bold>", icon="🔒")

# Now you can use these levels
logger.log("METRIC", "Order completed in {} seconds", 2.5)
logger.log("SECURITY", "Failed login attempt from IP: {}", "192.168.1.100")

O parâmetro no define a prioridade do nível (números mais altos = prioridade mais alta). Níveis padrão de uso: DEBUG=10, INFO=20, WARNING=30, ERROR=40, CRITICAL=50.

Vamos ver isso num cenário de treinamento de machine learning:

from loguru import logger

# Set up custom levels for ML tracking
logger.level("EPOCH", no=35, color="<cyan><bold>")
logger.level("CHECKPOINT", no=38, color="<green><bold>")

# Configure output
logger.remove()
logger.add("training_{time:YYYY-MM-DD}.log", level="INFO")

def train_model(model, data_loader, epochs=10):
   logger.info("Starting training with {} epochs", epochs)
  
   for epoch in range(epochs):
       # Log epoch progress with custom level
       logger.log("EPOCH", "Epoch {}/{} started", epoch + 1, epochs)
      
       # Training logic here
       loss = 0.523 - (epoch * 0.05)  # Simulated improving loss
       accuracy = 0.72 + (epoch * 0.03)  # Simulated improving accuracy
      
       logger.info("Loss: {:.4f}, Accuracy: {:.2%}", loss, accuracy)
      
       # Save checkpoint every 5 epochs
       if (epoch + 1) % 5 == 0:
           logger.log("CHECKPOINT", "Model saved at epoch {}", epoch + 1)
  
   logger.success("Training completed!")

Interceptando e modificando mensagens de log

Às vezes, você precisa modificar as mensagens de log antes que elas sejam gravadas. Os casos de uso mais comuns incluem remover dados confidenciais, adicionar IDs de solicitação ou reformatar mensagens para ferramentas específicas.

O Loguru te deixa interceptar mensagens usando o parâmetro filter:

from loguru import logger
import re

def hide_sensitive_data(record):
   # Hide credit card numbers
   record["message"] = re.sub(r'\b\d{4}[\s-]?\d{4}[\s-]?\d{4}[\s-]?\d{4}\b',
                             'XXXX-XXXX-XXXX-XXXX',
                             record["message"])
  
   # Hide email addresses
   record["message"] = re.sub(r'\b[\w.-]+@[\w.-]+\.\w+\b',
                             '***@***.***',
                             record["message"])
  
   # Continue processing the log
   return True

# Add the filter to your logger
logger.add("secure.log", filter=hide_sensitive_data)

# Test it
logger.info("User paid with card 4532-1234-5678-9012")
logger.info("Contact email: john.doe@example.com")

Você também pode usar filtros para adicionar informações contextuais:

from loguru import logger
import threading

def add_thread_info(record):
   # Add thread name to every log message
   record["extra"]["thread_name"] = threading.current_thread().name
   return True

def add_environment_info(record):
   # Add environment to production logs
   record["extra"]["env"] = "production"
   record["extra"]["region"] = "us-west-2"
   return True

# Apply multiple filters
logger.add(
   "app.log",
   filter=lambda record: add_thread_info(record) and add_environment_info(record),
   format="{time} | {extra[env]} | {extra[thread_name]} | {message}"
)

Pias personalizadas para serviços externos

Um sink é onde seus logs vão parar. Embora arquivos e consoles sejam comuns, muitas vezes você precisa enviar logs para serviços externos, como Slack, e-mail ou sistemas de monitoramento.

Veja como criar um sink personalizado que manda erros pro Slack:

from loguru import logger
import requests

def send_to_slack(message):
   """Custom sink that sends messages to Slack"""
   # Parse the log record
   record = message.record
  
   # Only send errors and above
   if record["level"].no < 40:  # ERROR level is 40
       return
  
   # Format message for Slack
   slack_message = {
       "text": f"🚨 {record['level'].name}: {record['message']}",
       "attachments": [{
           "color": "danger",
           "fields": [
               {"title": "Time", "value": str(record["time"]), "short": True},
               {"title": "Function", "value": record["function"], "short": True},
               {"title": "File", "value": f"{record['file'].name}:{record['line']}", "short": False}
           ]
       }]
   }
  
   # Send to Slack webhook
   webhook_url = "https://hooks.slack.com/services/YOUR/WEBHOOK/URL"
   requests.post(webhook_url, json=slack_message)

# Add the custom sink
logger.add(send_to_slack, level="ERROR")

# Test it
logger.error("Database connection lost!")

Aqui vai outro exemplo prático: um sink personalizado que coleta métricas de desempenho durante a execução do aplicativo e as salva para análise:

from loguru import logger
from collections import defaultdict
import json

class MetricsCollector:
   def __init__(self):
       self.metrics = defaultdict(list)
  
   def __call__(self, message):
       """This method is called for every log message"""
       record = message.record
      
       # Only process METRIC level logs
       if record["level"].name != "METRIC":
           return
      
       # Extract metric data from the 'extra' fields
       extra = record["extra"]
       if "metric_name" in extra and "value" in extra:
           self.metrics[extra["metric_name"]].append({
               "value": extra["value"],
               "timestamp": record["time"].timestamp()
           })
  
   def save_metrics(self):
       """Save all collected metrics to a JSON file"""
       with open("metrics.json", "w") as f:
           json.dump(dict(self.metrics), f, indent=2)

# Create the collector and add it as a sink
collector = MetricsCollector()
logger.add(collector)

# Create the METRIC level
logger.level("METRIC", no=38)

# Now when you log metrics, they're automatically collected
# The bind() method attaches extra data to the log entry
logger.bind(metric_name="response_time", value=0.234).log("METRIC", "API response")
logger.bind(metric_name="response_time", value=0.189).log("METRIC", "API response")
logger.bind(metric_name="active_users", value=1523).log("METRIC", "User count")

# Later, save all metrics to file
collector.save_metrics()

# The metrics.json file will contain:
# {
#   "response_time": [
#     {"value": 0.234, "timestamp": 1627...},
#     {"value": 0.189, "timestamp": 1627...}
#   ],
#   "active_users": [
#     {"value": 1523, "timestamp": 1627...}
#   ]
# }

O legal dessa abordagem é que o código do seu aplicativo fica limpo — você só precisa registrar as métricas normalmente, e o coletor cuida do armazenamento automaticamente. Você pode trocar isso facilmente por um sink que manda métricas pro Prometheus, DataDog ou qualquer outro serviço de monitoramento.

Essas personalizações oferecem flexibilidade para adaptar o Loguru às suas necessidades específicas, mantendo a simplicidade que o torna excelente. Se você tá criando um script pequeno ou um aplicativo grande, dá pra estender o Loguru pra lidar com suas necessidades específicas de registro sem precisar de arquivos de configuração complicados ou código repetitivo.

Conclusão

O Loguru torna o registro em Python tão simples quanto deveria ser. Chega de arquivos de configuração, chega de configurar manipuladores, chega de código repetitivo. É só importar e começar a registrar com cores, carimbos de data/hora e rotação automática de arquivos.

Você já viu como ele lida com os pontos mais complicados: salvar logs em arquivos, rodá-los automaticamente, capturar exceções com todo o contexto e mandar logs para serviços externos. Os recursos de registro estruturado deixam ele pronto pra produção, enquanto os níveis e coletores personalizados permitem adaptá-lo a qualquer caso de uso.

Use o Loguru quando:

  • Você está cansado de depurar impressões
  • Você precisa de scripts ou cadernos de registro rápido
  • Você tá criando aplicativos web que precisam de registros estruturados
  • Você quer um acompanhamento melhor das exceções sem uma configuração complicada

Para saber mais, dá uma olhada na documentação oficial junto com este tutorial de registro para ver tudo sobre as estratégias de registro do Python.

Comece aos poucos. Troca uma instrução print por um logger.info(). Você nunca mais vai querer voltar.

Perguntas frequentes sobre o Loguru

Como o Loguru se compara a outras bibliotecas de registro em Python?

O Loguru é super legal porque não precisa de nenhuma configuração - dá pra começar a registrar logo com o comando loguru import logger. Diferente do módulo de registro integrado do Python, que precisa de manipuladores, formatadores e uma configuração complexa, o Loguru já vem com cores, carimbos de data/hora e rotação de arquivos. Ele também oferece rastreamentos aprimorados com inspeção variável que outras bibliotecas não oferecem.

Quais são as principais vantagens de usar o Loguru em vez do módulo de registro integrado do Python?

O Loguru elimina a complexidade da configuração, faz a rotação e retenção automática de arquivos, oferece registro JSON estruturado com serialize=True, inclui rastreamento de exceções aprimorado com valores variáveis e suporta destinos personalizados para serviços externos. Você tem recursos de registro prontos para produção sem precisar escrever código de configuração.

O Loguru consegue lidar com aplicativos multithread de forma eficiente?

Sim, o Loguru é seguro para threads por padrão e lida bem com aplicativos multithread. Você pode adicionar informações de thread aos logs usando filtros, e o método logger.bind() funciona em todas as threads para manter o contexto. O desempenho do Loguru é otimizado para registro simultâneo sem bloquear threads.

Como funciona a rotação e retenção automática de logs do Loguru?

O Loguru oferece rotação flexível com base no tamanho do arquivo (rotação = “10 MB”), intervalos de tempo (rotação = “00:00” para diariamente) ou condições personalizadas. A retenção apaga automaticamente os arquivos antigos (retenção=10 mantém 10 arquivos) e a compactação economiza espaço (compactação=&quot;zip&quot;). Tudo rola automaticamente, sem precisar mexer nos arquivos.

Quais são alguns exemplos práticos do uso dos recursos personalizados do Loguru?

Os sinks personalizados permitem enviar logs para serviços externos, como o Slack, para alertas de erros, coletar métricas para monitorar sistemas ou formatar logs para ferramentas específicas. Você pode criar sinks que filtram por nível de log, adicionam informações contextuais ou se integram a serviços como DataDog, Prometheus ou notificações por e-mail para erros críticos.


Bex Tuychiev's photo
Author
Bex Tuychiev
LinkedIn

Sou um criador de conteúdo de ciência de dados com mais de 2 anos de experiência e um dos maiores seguidores no Medium. Gosto de escrever artigos detalhados sobre IA e ML com um estilo um pouco sarcástico, porque você precisa fazer algo para torná-los um pouco menos monótonos. Produzi mais de 130 artigos e um curso DataCamp, e estou preparando outro. Meu conteúdo foi visto por mais de 5 milhões de pessoas, das quais 20 mil se tornaram seguidores no Medium e no LinkedIn. 

Tópicos

Principais cursos da DataCamp

Programa

Fundamentos de dados Python

0 min
Aumente suas habilidades com dados, descubra como manipular e visualizar dados e aplique análises avançadas para tomar decisões orientadas por dados.
Ver detalhesRight Arrow
Iniciar curso
Ver maisRight Arrow
Relacionado
Python

Tutorial

Tutorial para entender a regressão logística em Python

Aprenda sobre a regressão logística, suas propriedades básicas e crie um modelo de aprendizado de máquina em um aplicativo do mundo real em Python.
Avinash Navlani's photo

Avinash Navlani

Tutorial

Desenvolvimento de back-end em Python: Um guia completo para iniciantes

Este guia completo ensina a você os fundamentos do desenvolvimento de back-end em Python. Aprenda conceitos básicos, estruturas e práticas recomendadas para você começar a criar aplicativos da Web.
Oluseye Jeremiah's photo

Oluseye Jeremiah

Tutorial

Configuração do VSCode para Python: Um guia completo

Experimente uma forma simples, divertida e produtiva de desenvolvimento em Python, aprendendo sobre o VSCode e suas extensões e recursos.
Abid Ali Awan's photo

Abid Ali Awan

Tutorial

Tutorial de lambda em Python

Aprenda uma maneira mais rápida de escrever funções em tempo real com as funções lambda.
DataCamp Team's photo

DataCamp Team

Tutorial

Tutorial do Python Excel: O guia definitivo

Saiba como ler e importar arquivos do Excel em Python, gravar dados nessas planilhas e encontrar os melhores pacotes para fazer isso.
Natassha Selvaraj's photo

Natassha Selvaraj

Tutorial

Tutorial de manipulação de dados categóricos de aprendizado de máquina com Python

Aprenda os truques comuns para lidar com dados categóricos e pré-processá-los para criar modelos de aprendizado de máquina!
Moez Ali's photo

Moez Ali

Ver maisVer mais