Programa
Has estado depurando con instrucciones « print() » durante toda tu vida como programador. Quizás hayas probado el módulo de registro de Python una o dos veces, pero hayas vuelto a los prints porque son más sencillos.
En realidad, hay algo mejor que es igual de fácil de usar.
Las declaraciones de impresión no se pueden guardar en archivos ni activar y desactivar fácilmente. El registro integrado de Python puede hacer estas cosas, pero requiere escribir código de configuración más largo que tu programa real.
Loguru adopta un enfoque diferente: el registro debe ser tan fácil como imprimir, pero mucho más útil. Obtienes colores en tu terminal, marcas de tiempo automáticas y la posibilidad de guardar todo en archivos sin escribir una sola línea de configuración.
En este tutorial, te mostraré ejemplos prácticos que hacen que el registro sea algo natural en lugar de una tarea pesada. Descubrirás funciones que probablemente no conocías, utilizando patrones de código que facilitan la depuración.
Si eres nuevo en la depuración de Python o deseas reforzar tus habilidades básicas, adquirir unos fundamentos sólidos de Python te ayudará a comprender cuándo y por qué es necesario el registro.
Primeros pasos con Loguru: Magia sin configuración
Para instalar Loguru solo hay que ejecutar un comando:
pip install loguru
Con el módulo logging normal, tendrías que configurar controladores, formateadores y todo lo demás antes de ver un solo mensaje de registro.
Para una comparación más detallada de los métodos de registro integrados en Python, consulta este tutorial completo sobre registro que cubre los métodos tradicionales.
Con Loguru, solo tienes que importar y empezar 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)
La salida aparece en tu terminal con colores, marcas de tiempo y niveles de registro automáticamente. No requiere configuración.

Supongamos que estás creando un sencillo rastreador web. Así es como cambia la depuración:
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
Observa los diferentes niveles de registro (info, debug, success, error) y el formato con llaves. Todo funciona inmediatamente sin archivos de configuración ni código de instalación.
Registro y rotación de archivos simplificados
Cuando depuras con la salida de la consola, pierdes todo en el momento en que cierras el terminal. No puedes buscar lo que ocurrió hace una hora y, si tu script se bloquea durante la noche, no hay rastro de lo que ha fallado. Tampoco puedes compartir fácilmente los resultados de la depuración con tus compañeros de equipo cuando solicitas ayuda.
El registro de archivos resuelve este problema guardando todo de forma permanente.
El registro tradicional te obliga a escribir código de configuración para configurar los controladores de archivos. Debes especificar las rutas de los archivos, crear directorios y gestionar los permisos. Con Loguru, añadir el registro de archivos es, literalmente, una línea:
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")
Ahora todo se guarda en app.log y sigue apareciendo en tu terminal.
Pero los archivos de registro se vuelven enormes con el tiempo. Una aplicación web que se ejecuta durante días puede generar gigabytes de registros que, con el tiempo, llenarán tu disco. La rotación de archivos resuelve este problema creando automáticamente nuevos archivos de registro cuando se cumplen determinadas condiciones. El archivo antiguo se renombra con una marca de tiempo y se crea un archivo nuevo:
# 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")
Las marcas de tiempo predeterminadas funcionan, pero a menudo están en UTC o son difíciles de leer. Loguru te permite personalizar los formatos de fecha y hora según tus necesidades:
# 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 los sistemas de producción, necesitas un mayor control sobre los archivos antiguos. El registro de producción requiere seguir las prácticas recomendadas de Python para garantizar que tus registros sean mantenibles y seguros. Sin gestión, los archivos de registro se acumulan y consumen almacenamiento:
# 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
Veamos esto en un escenario realista. Estás creando un canal de datos que procesa varios archivos CSV cada noche, limpiando y validando los datos de los clientes antes de cargarlos en tu base de datos. Debes realizar un seguimiento de los archivos que se han procesado correctamente y detectar cualquier problema de calidad de los datos:
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")
Tus registros se guardan con marcas de tiempo legibles, los archivos se rotan automáticamente y los registros antiguos se limpian solos. Puedes revisar lo que sucedió días después o enviar archivos de registro a tus compañeros de trabajo cuando solucionen problemas.
Registro estructurado para aplicaciones modernas
Cuando ejecutas una aplicación web, tus registros se convierten rápidamente en un caos de información mezclada. Las acciones de los usuarios, las consultas a la base de datos, las llamadas a la API y los errores se mezclan en un muro de texto. No puedes filtrar fácilmente por usuarios específicos, rastrear solicitudes individuales ni analizar automáticamente registros para sistemas de supervisión.
Las aplicaciones basadas en datos se benefician especialmente del registro estructurado. Si trabajas con canalizaciones de datos o análisis, desarrollar habilidades de analista de datos te ayudará a comprender qué información debes capturar en tus registros.
El registro tradicional basado en cadenas empeora aún más la situación. Todos los mensajes de registro son solo texto, por lo que extraer datos significativos requiere patrones de expresiones regulares complejos o búsquedas manuales.
El registro estructurado cambia esto al tratar las entradas de registro como objetos de datos en lugar de solo texto. Cada entrada del registro se convierte en un registro estructurado con campos que se pueden buscar, lo que facilita la consulta y el análisis mediante programación.
Registro estructurado JSON con serialize=True
Loguru simplifica el registro estructurado con la opción « serialize=True » (Registro estructurado):
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")
El parámetro « serialize=True » indica a Loguru que genere JSON en lugar de texto sin formato. En lugar de frases legibles, tu archivo de registro ahora contiene datos estructurados:
{"text": "User login", "record": {"time": "2024-07-15T14:30:25", "level": {"name": "INFO"}, "extra": {"user_id": 123, "ip_address": "192.168.1.1"}}}
Este formato funciona perfectamente con herramientas de análisis de registros que pueden buscar y filtrar datos JSON automáticamente.
Enlace de contexto
Pero las aplicaciones web necesitan algo más que datos estructurados. Necesitas contexto que conecte las entradas de registro relacionadas. Al procesar una solicitud de usuario, es conveniente que todos los registros relacionados compartan información común, como el ID de usuario o el ID de sesión.
El enlace de contexto resuelve esto adjuntando información persistente a tu registrador mediante 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'])
Ahora, todos los registros de order_logger incluyen automáticamente user_id y order_id, lo que facilita el seguimiento de todos los registros relacionados con un pedido específico.
Múltiples sumideros para diferentes salidas
Las aplicaciones modernas también necesitan diferentes salidas de registro para diferentes fines. Es posible que desees registros de consola legibles durante el desarrollo, pero registros JSON para la supervisión de la producción. En Loguru, cada destino de salida se denomina «sumidero», es decir, un lugar al que fluyen los mensajes de registro.
Loguru te permite añadir múltiples sumideros con diferentes formatos y reglas:
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")
La llamada logger.remove() elimina la salida predeterminada de la consola de Loguru para que puedas configurar la tuya propia. Cada logger.add() crea un nuevo sumidero con sus propias reglas sobre lo que se registra y cómo se formatea.
Ahora las mismas sentencias de registro producen 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
Ejemplo completo de Loguru: Sistema de registro de usuarios
Veamos esto con un ejemplo más sencillo y realista del uso de Loguru: un sistema básico de registro de usuarios.
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")
Esta configuración te proporciona una salida de consola legible durante el desarrollo, registros JSON estructurados para la supervisión automatizada y registros de errores independientes para las alertas. El método ` bind() ` garantiza que todos los registros de cada registro de usuario incluyan la dirección de correo electrónico, lo que facilita enormemente la depuración.
Gestión de excepciones Loguru
Cuando tu código falla, normalmente obtienes un seguimiento básico de la pila que te indica dónde se ha producido el error, pero no te da mucha información sobre el motivo. Pierdes los valores de las variables en el momento del bloqueo, lo que dificulta comprender qué ha fallado. El manejo tradicional de excepciones también requiere que envuelvas todo en bloques try-catch y registres manualmente cada excepción.
Esto resulta especialmente doloroso cuando se depuran problemas de producción. Los usuarios informan de errores, pero tú no puedes reproducirlos porque no conoces el contexto en el que se produjeron.
Loguru resuelve esto con la captura automática de excepciones y trazas mejoradas que te muestran exactamente qué estaba sucediendo en tu código cuando surgieron los problemas.
Captura automática de excepciones con @logger.catch
El decorador ` @logger.catch ` captura automáticamente cualquier excepción que se produzca en una función y la registra con todo el contexto. Los decoradores como @logger.catch son un concepto intermedio de Python que puede transformar la forma en que gestionas los errores en tu código base:
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)
En lugar de que tu programa se bloquee con un mensaje de error básico, Loguru captura la excepción y la registra con información detallada, mientras tu programa sigue ejecutándose. El decorador funciona en cualquier función: métodos de clase, funciones asíncronas o funciones normales.
Rastreos mejorados con inspección de variables
Pero Loguru va más allá con trazas mejoradas que muestran los valores de las variables en cada nivel de la pila de llamadas. Esta función se llama «diagnóstico» y es como tener un depurador integrado en tus 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)
Con « diagnose=True », cuando la función se bloquea al intentar restar una cadena de un número, Loguru te muestra exactamente qué había en cada variable:
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"
Este nivel de detalle agiliza considerablemente la depuración, ya que permite ver exactamente qué datos han causado el problema.
Gestión de excepciones respetuosa con el medio ambiente
Sin embargo, los rastreos mejorados pueden exponer información confidencial, como contraseñas o claves API, en los registros de producción. Loguru te permite controlar este comportamiento para diferentes entornos:
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")
Evaluación perezosa para mejorar el rendimiento
Otra potente característica es la evaluación diferida, que mejora el rendimiento al registrar operaciones costosas. A veces quieres registrar información compleja, pero solo si realmente se produce un error:
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()}
La sintaxis « lambda: » crea una función que solo se invoca cuando Loguru escribe realmente el mensaje de registro. Si no se produce ningún error, expensive_data_summary() nunca se ejecuta, lo que ahorra tiempo de procesamiento.
Diferentes estrategias para diferentes tipos de errores
También puedes utilizar diferentes estrategias de gestión de excepciones para diferentes tipos de errores:
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)
El parámetro « reraise=False » indica a Loguru que registre la excepción, pero que no la vuelva a generar, lo que permite que el programa continúe. Esto resulta útil para funciones opcionales que no deben interrumpir el flujo de trabajo principal.
Ejemplo completo: procesamiento de archivos con gestión de errores
Veamos un ejemplo completo con un sistema de procesamiento de archivos que gestiona diferentes tipos de errores con elegancia:
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
Esta configuración te ofrece captura automática de excepciones, contexto detallado de los errores cuando es necesario y diferentes estrategias de gestión para distintos tipos de errores. Tus registros se vuelven mucho más útiles para la depuración, mientras que tu código permanece limpio y legible.
Configuración y personalización avanzadas de Loguru
A medida que tus aplicaciones crezcan, te encontrarás con situaciones en las que los valores predeterminados de Loguru no se ajustan del todo a tus necesidades. Quizás necesites un nivel de registro especial para métricas empresariales, quieras filtrar datos confidenciales de los registros o necesites enviar alertas a Slack cuando se produzcan errores.
La buena noticia es que Loguru está diseñado para personalizarse sin perder su simplicidad. Puedes ampliarlo de formas que requerirían una configuración compleja en los sistemas de registro tradicionales, todo ello manteniendo tu código limpio y legible.
Veamos las personalizaciones más útiles que resuelven problemas reales a los que te enfrentarás en aplicaciones de producción.
Niveles y colores de registro personalizados
Loguru viene con niveles estándar como INFO, DEBUG y ERROR. Pero a veces necesitas algo específico para tu aplicación. Quizás quieras un nivel especial para métricas de rendimiento o eventos empresariales.
Crear niveles de registro personalizados es muy sencillo:
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")
El parámetro no establece la prioridad del nivel (cuanto mayor sea el número, mayor será la prioridad). Uso de los niveles estándar: DEBUG=10, INFO=20, WARNING=30, ERROR=40, CRITICAL=50.
Veamos esto en un escenario de formación en 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!")
Interceptar y modificar mensajes de registro
A veces es necesario modificar los mensajes de registro antes de que se escriban. Algunos casos de uso habituales son eliminar datos confidenciales, añadir ID de solicitud o reformatear mensajes para herramientas específicas.
Loguru te permite interceptar mensajes utilizando el 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")
También puedes utilizar filtros para añadir información contextual:
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}"
)
Lavabos a medida para servicios externos
Un sumidero es el lugar al que fluyen tus registros. Aunque los archivos y la consola son comunes, a menudo es necesario enviar registros a servicios externos como Slack, correo electrónico o sistemas de supervisión.
A continuación se explica cómo crear un sumidero personalizado que envía los errores a 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!")
Aquí tienes otro ejemplo práctico: un sumidero personalizado que recopila métricas de rendimiento durante la ejecución de la aplicación y las guarda para su análisis:
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...}
# ]
# }
La ventaja de este enfoque es que el código de la aplicación permanece limpio: solo tienes que registrar las métricas como de costumbre y el colector se encarga automáticamente del almacenamiento. Puedes sustituirlo fácilmente por un sumidero que envíe métricas a Prometheus, DataDog o cualquier otro servicio de monitorización.
Estas personalizaciones te ofrecen la flexibilidad necesaria para adaptar Loguru a tus necesidades específicas sin perder la simplicidad que lo hace tan especial. Tanto si estás creando un pequeño script como una gran aplicación, puedes ampliar Loguru para que se adapte a tus necesidades específicas de registro sin necesidad de archivos de configuración complejos ni código repetitivo.
Conclusión
Loguru hace que el registro en Python sea tan sencillo como debería ser. Se acabaron los archivos de configuración, la configuración de controladores y el código repetitivo. Solo tienes que importar y empezar a registrar con colores, marcas de tiempo y rotación automática de archivos.
Ya has visto cómo gestiona los puntos débiles más comunes: guardar registros en archivos, rotarlos automáticamente, capturar excepciones con todo el contexto y enviar registros a servicios externos. Las funciones de registro estructurado lo hacen apto para la producción, mientras que los niveles y sumideros personalizados te permiten adaptarlo a cualquier caso de uso.
Utiliza Loguru cuando:
- Estás cansado de depurar impresiones
- Necesitas scripts o cuadernos de registro rápido.
- Estás creando aplicaciones web que necesitan registros estructurados.
- Deseas un mejor seguimiento de las excepciones sin una configuración compleja.
Para obtener más información, consulta la documentación oficial junto con este tutorial sobre registro para obtener una descripción completa de las estrategias de registro de Python.
Empieza poco a poco. Reemplaza una instrucción de impresión por logger.info(). Nunca volverás atrás.
Preguntas frecuentes sobre Loguru
¿En qué se diferencia Loguru de otras bibliotecas de registro de Python?
Loguru destaca por no requerir ninguna configuración: puedes empezar a registrar inmediatamente con from loguru import logger. A diferencia del módulo de registro integrado de Python, que necesita controladores, formateadores y una configuración compleja, Loguru proporciona colores, marcas de tiempo y rotación de archivos desde el primer momento. También ofrece un seguimiento mejorado con inspección variable que otras bibliotecas no proporcionan.
¿Cuáles son las principales ventajas de utilizar Loguru en lugar del módulo de registro integrado en Python?
Loguru elimina la complejidad de la configuración, proporciona rotación y retención automática de archivos, ofrece registros JSON estructurados con serialize=True, incluye seguimiento de excepciones mejorado con valores variables y admite sumideros personalizados para servicios externos. Obtienes funciones de registro listas para la producción sin necesidad de escribir código de configuración.
¿Loguru puede gestionar aplicaciones multihilo de manera eficiente?
Sí, Loguru es seguro para subprocesos de forma predeterminada y gestiona bien las aplicaciones multihilo. Puedes añadir información sobre subprocesos a los registros utilizando filtros, y el método logger.bind() funciona en todos los subprocesos para mantener el contexto. El rendimiento de Loguru está optimizado para el registro simultáneo sin bloquear subprocesos.
¿Cómo funciona la rotación y retención automática de registros de Loguru?
Loguru ofrece una rotación flexible basada en el tamaño del archivo (rotación = «10 MB»), intervalos de tiempo (rotación = «00:00» para diaria) o condiciones personalizadas. La retención elimina automáticamente los archivos antiguos (retención=10 conserva 10 archivos) y la compresión ahorra espacio (compresión="zip"). Todo se realiza automáticamente sin necesidad de gestionar archivos manualmente.
¿Cuáles son algunos ejemplos prácticos del uso de las funciones personalizadas de Loguru?
Los sumideros personalizados te permiten enviar registros a servicios externos como Slack para alertas de errores, recopilar métricas para sistemas de supervisión o dar formato a los registros para herramientas específicas. Puedes crear sumideros que filtren por nivel de registro, añadir información contextual o integrarlos con servicios como DataDog, Prometheus o notificaciones por correo electrónico para errores críticos.

Soy un creador de contenidos de ciencia de datos con más de 2 años de experiencia y uno de los mayores seguidores en Medium. Me gusta escribir artículos detallados sobre IA y ML con un estilo un poco sarcastıc, porque hay que hacer algo para que sean un poco menos aburridos. He publicado más de 130 artículos y un curso DataCamp, y estoy preparando otro. Mi contenido ha sido visto por más de 5 millones de ojos, 20.000 de los cuales se convirtieron en seguidores tanto en Medium como en LinkedIn.
