Skip to content

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 infraestructura

error — 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 default

info — 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 estado

debug — 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 queries

trace — 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/recibido

Monitoreo 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ón
Logger.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.