"Chromologger" es un módulo avanzado de logging diseñado para facilitar la creación de registros (logs) profesionales en aplicaciones desarrolladas con Python. Proporciona una solución completa y fácil de usar para documentar eventos, excepciones, y actividades del sistema, mejorando significativamente la capacidad de monitoreo, debugging y mantenimiento del código.
Requerimientos: - chromolog==0.2.5 # Para salida colorizada en consola - # pip install chromolog - # pip install chromologger
📋 Formato de registro detallado
[INFO][2025-01-06 19:52:08.636560] - Aplicación iniciada correctamente [ERROR][2025-01-06 19:52:08.636560] - Exception: FileNotFoundError - File: c:\Users\srm\Desktop\app\main.py - ErrorLine: 35 - Message: [Errno 2] No such file or directory: './data/config.json'
# Instalar chromologger
pip install chromologger
# Instalar dependencia (si no se instala automáticamente)
pip install chromolog==0.2.5
from chromologger import Logger
# Crear logger (archivo por defecto: log.log en directorio del script)
logger = Logger()
# Registrar mensaje informativo
logger.log('Aplicación iniciada correctamente')
# Registrar excepción
try:
resultado = 10 / 0
except Exception as e:
logger.log_e(e)
# Cerrar logger (liberar recursos)
logger.close()
from chromologger import Logger
import os
# Crear directorio si no existe
os.makedirs('./logs', exist_ok=True)
# Logger con archivo personalizado
app_logger = Logger('./logs/mi_aplicacion.log')
# Registrar diferentes tipos de eventos
app_logger.log('Sistema iniciado')
app_logger.log(f'Usuario {"admin"} conectado desde IP 192.168.1.100')
# También acepta otros tipos de datos
app_logger.log({'evento': 'login', 'usuario': 'admin', 'timestamp': '2025-01-06'})
app_logger.log(42) # Números también son válidos
# Siempre cerrar el logger
app_logger.close()
📁 Ubicación del archivo: Si usa el nombre por defecto 'log.log'
, el archivo se creará en el mismo directorio del script que llama al Logger. Para rutas personalizadas, asegúrese de que el directorio exista.
💡 Tip: El logger detecta automáticamente la ubicación del script que lo llama y crea el archivo de log en ese directorio. No necesita especificar rutas complejas para uso básico.
La clase principal que gestiona todos los registros con timestamps automáticos y manejo de excepciones.
Logger(log_file_name: str = 'log.log')
log_file_name
(str, opcional): Nombre o ruta del archivo de log.
'log.log'
: Se crea en el directorio del script llamadorRegistra mensajes informativos generales con nivel INFO y timestamp automático.
msg
(any): Mensaje a registrar. Acepta strings, números, diccionarios, listas, etc.# Diferentes tipos de mensajes
logger.log('Operación completada exitosamente')
logger.log(f'Procesados {count} elementos en {time} segundos')
logger.log({'status': 'success', 'items': 150, 'time': 2.5})
logger.log(['evento1', 'evento2', 'evento3'])
📄 Resultado en el archivo de log:
[INFO][2025-01-06 19:52:08.636560] - Operación completada exitosamente [INFO][2025-01-06 19:52:09.125430] - Procesados 150 elementos en 2.5 segundos [INFO][2025-01-06 19:52:09.332100] - {'status': 'success', 'items': 150, 'time': 2.5}
Registra excepciones con información detallada de traceback, incluyendo archivo, línea y mensaje completo.
e
(Exception): Instancia de Exception o sus subclases (ValueError, FileNotFoundError, etc.)# Ejemplo completo de manejo de errores
try:
# Operación que puede fallar
with open('archivo_inexistente.txt', 'r') as f:
contenido = f.read()
except FileNotFoundError as e:
logger.log_e(e) # Registra error detallado
try:
resultado = 10 / 0
except ZeroDivisionError as e:
logger.log_e(e)
try:
lista = [1, 2, 3]
elemento = lista[10] # Índice fuera de rango
except IndexError as e:
logger.log_e(e)
📄 Resultado en el archivo de log:
[ERROR][2025-01-06 20:21:30.744693] - Exception: FileNotFoundError - File: c:\Users\srm\Desktop\app\main.py - ErrorLine: 15 - Message: [Errno 2] No such file or directory: 'archivo_inexistente.txt' [ERROR][2025-01-06 20:21:30.756123] - Exception: ZeroDivisionError - File: c:\Users\srm\Desktop\app\main.py - ErrorLine: 19 - Message: division by zero
Cierra el archivo de log y libera los recursos del sistema.
True
: Archivo cerrado exitosamenteFalse
: No había archivo válido para cerrar# Uso recomendado
logger = Logger('mi_app.log')
logger.log('Iniciando operaciones')
# ... lógica de la aplicación ...
# Cerrar y verificar
if logger.close():
print('Logger cerrado correctamente')
else:
print('Advertencia: No se pudo cerrar el logger')
from chromologger import Logger
import os
from datetime import datetime
# Configurar directorio de logs
log_dir = './logs'
os.makedirs(log_dir, exist_ok=True)
# Logger para eventos de la aplicación
app_logger = Logger(f'{log_dir}/app_{datetime.now().strftime("%Y%m%d")}.log')
class WebApplication:
def __init__(self):
app_logger.log('Inicializando aplicación web')
def handle_request(self, user_id, endpoint):
try:
app_logger.log(f'Usuario {user_id} accediendo a {endpoint}')
# Simular procesamiento
if endpoint == '/api/data':
# Simular error ocasional
import random
if random.random() < 0.1: # 10% de probabilidad de error
raise ConnectionError('Database connection failed')
app_logger.log(f'Datos enviados exitosamente a usuario {user_id}')
except Exception as e:
app_logger.log_e(e)
app_logger.log(f'Error procesando request de usuario {user_id}')
def shutdown(self):
app_logger.log('Cerrando aplicación web')
app_logger.close()
# Uso
app = WebApplication()
app.handle_request('user123', '/api/data')
app.handle_request('user456', '/api/profile')
app.shutdown()
from chromologger import Logger
import time
# Diferentes loggers para diferentes propósitos
access_logger = Logger('./logs/access.log')
error_logger = Logger('./logs/errors.log')
performance_logger = Logger('./logs/performance.log')
def monitor_system():
start_time = time.time()
try:
access_logger.log('Sistema de monitoreo iniciado')
# Simular trabajo
time.sleep(2)
# Registrar rendimiento
elapsed = time.time() - start_time
performance_logger.log(f'Operación completada en {elapsed:.2f} segundos')
access_logger.log('Monitoreo completado exitosamente')
except Exception as e:
error_logger.log_e(e)
finally:
# Cerrar todos los loggers
access_logger.close()
error_logger.close()
performance_logger.close()
monitor_system()
Los timestamps incluyen precisión hasta microsegundos para máxima precisión en el debugging:
YYYY-MM-DD HH:MM:SS.microseconds 2025-01-06 20:21:30.744693
./logs/app.log
# ❌ Error: directorio no existe
logger = Logger('./logs_inexistentes/app.log')
# ✅ Solución: crear directorio primero
import os
os.makedirs('./logs', exist_ok=True)
logger = Logger('./logs/app.log')
# Verificar que el logger se inicializó correctamente
logger = Logger()
if hasattr(logger, 'file') and logger.file != -1:
logger.log('Logger funcionando correctamente')
else:
print('Error: Logger no se inicializó correctamente')
# Siempre usar try/finally o context managers
logger = None
try:
logger = Logger('app.log')
logger.log('Trabajando...')
finally:
if logger:
logger.close()
Chromologger mantiene su propio sistema de logging interno para diagnosticar problemas del módulo. Si encuentra errores, revise:
# Ubicación del log interno
./src/chromologger/log.log
# También se muestran mensajes en consola con colores
# Organizar logs por fecha
from datetime import datetime
date_str = datetime.now().strftime("%Y%m%d")
logger = Logger(f'./logs/app_{date_str}.log')
# O por funcionalidad
auth_logger = Logger('./logs/authentication.log')
db_logger = Logger('./logs/database.log')
api_logger = Logger('./logs/api_requests.log')
# Patrón actual recomendado
def process_data():
logger = Logger('data_processing.log')
try:
logger.log('Iniciando procesamiento de datos')
# ... procesamiento ...
logger.log('Procesamiento completado')
except Exception as e:
logger.log_e(e)
finally:
logger.close()
# ✅ Usar log() para eventos normales
logger.log('Usuario autenticado exitosamente')
logger.log('Base de datos conectada')
logger.log('Archivo procesado: 150 registros')
# ✅ Usar log_e() solo para excepciones
try:
# operación riesgosa
pass
except Exception as e:
logger.log_e(e) # Información completa de traceback
El módulo incluye métodos privados para funcionamiento interno (no accesibles directamente):
# Uso exclusivamente interno - No accesible al usuario
# Estos métodos garantizan la robustez y confiabilidad del módulo