Logger
Wabot incluye un sistema de logging basado en la librería debug con 6 niveles de severidad y soporte para monitoreo de errores externo.
Conceptos clave
Logger: clase que se instancia con un nombre de módulo.- 6 niveles:
trace,debug,info,warn,error,fatal. Logger.setMonitor(): conecta un monitor externo para capturar errores.IErrorMonitor: interfaz para integración con servicios como Sentry.
Crear un logger
Cada logger se identifica con un nombre de módulo. Por convención, usa el prefijo wabot: seguido del nombre del servicio:
import { Logger } from '@wabot-dev/framework'
const logger = new Logger('wabot:payments')
logger.info('Servicio de pagos iniciado')logger.debug('Procesando pago', { orderId: '123', amount: 5000 })logger.error('Error al procesar pago', new Error('Timeout'))Niveles de logging
Usa el nivel apropiado según la situación:
fatal — El proceso no puede continuar
logger.fatal('No se pudo conectar a la base de datos', error)// Usa para: excepciones no capturadas, errores críticos de infraestructuraerror — Una operación falló inesperadamente
logger.error('Falló el envío de email', error, { to: 'user@example.com' })// Usa para: errores de integración, fallos en operaciones de negocio// Incluye siempre: qué falló, por qué (Error), y contexto (IDs)warn — Algo inusual pero el sistema se recuperó
logger.warn('Reintentando conexión', { attempt: 3, maxAttempts: 5 })// Usa para: reintentos, límites alcanzados, configuraciones faltantes con defaultinfo — Eventos clave del ciclo de vida
logger.info('Servidor iniciado en puerto 3000')logger.info('Configuración JWT aplicada', { algorithm: 'HS256' })// Usa para: inicio/parada de servicios, configuración aplicada, cambios de estadodebug — Detalles operativos internos
logger.debug('Lock adquirido', { key: 'order-123' })logger.debug('Query ejecutado', { table: 'prospects', rows: 15 })// Usa para: flujo paso a paso, adquisición de locks, ejecución de queriestrace — Granularidad muy fina
logger.trace('Request HTTP recibido', { method: 'POST', path: '/api/orders' })logger.trace('Mensaje socket recibido', { event: 'join-room', socketId: 'abc' })// Usa para: cada request, cada evento, cada mensaje enviado/recibidoMonitoreo de errores
Conecta un servicio externo para capturar automáticamente errores de nivel warn, error y fatal:
import { Logger, IErrorMonitor, IErrorMonitorContext } from '@wabot-dev/framework'
class SentryMonitor implements IErrorMonitor { captureError(error: Error, context: IErrorMonitorContext) { Sentry.captureException(error, { tags: { logger: context.logger, level: context.level }, extra: context.extra, }) }
captureMessage(message: string, context: IErrorMonitorContext) { Sentry.captureMessage(message, { level: context.level, tags: { logger: context.logger }, extra: context.extra, }) }}
// Configurar al inicio de la aplicaciónLogger.setMonitor(new SentryMonitor())La interfaz IErrorMonitorContext incluye:
interface IErrorMonitorContext { logger: string // Nombre del logger (ej: 'wabot:payments') level: ErrorSeverity // 'warning' | 'error' | 'fatal' timestamp: Date extra?: Record<string, unknown>}Ejemplo completo
Logger integrado en un servicio de procesamiento de pedidos:
import { Logger, singleton } from '@wabot-dev/framework'
@singleton()export class OrderProcessor { private logger = new Logger('wabot:orders')
async processOrder(orderId: string) { this.logger.info('Procesando pedido', { orderId })
try { // Validar stock this.logger.debug('Verificando stock', { orderId }) const stock = await this.checkStock(orderId)
if (stock.available < stock.requested) { this.logger.warn('Stock insuficiente', { orderId, available: stock.available, requested: stock.requested, }) return { success: false, reason: 'stock_insuficiente' } }
// Procesar pago this.logger.debug('Procesando pago', { orderId }) const payment = await this.processPayment(orderId)
if (!payment.success) { this.logger.error('Pago rechazado', new Error(payment.reason), { orderId }) return { success: false, reason: 'pago_rechazado' } }
// Confirmar pedido this.logger.debug('Confirmando pedido', { orderId }) await this.confirmOrder(orderId)
this.logger.info('Pedido procesado exitosamente', { orderId, total: payment.amount, })
return { success: true, orderId } } catch (error) { this.logger.fatal('Error crítico procesando pedido', error, { orderId }) throw error } }}Siguiente paso
Previene procesamiento duplicado con bloqueo distribuido: Bloqueo Distribuido.