Registro en aplicaciones JavaScript: mejores prácticas en la práctica
El registro no es solo escribir mensajes en la consola. En un entorno de producción, un registro bien configurado se convierte en la principal herramienta de monitoreo, depuración y auditoría. Sin él, trabajas a ciegas. En este artículo, analizaremos las mejores prácticas de registro para aplicaciones JavaScript en Node.js, desde la elección de una biblioteca hasta la configuración de la rotación de archivos. Todos los ejemplos de código están listos para usar.
1. ¿Por qué console.log es malo?
En la etapa de desarrollo, todos usamos console.log. Es rápido y conveniente. Pero en producción, este enfoque es peligroso:
- Sin niveles de registro. No podrás filtrar errores de mensajes informativos.
- Bloqueo síncrono. El
console.logestándar puede ralentizar la aplicación con un gran flujo de solicitudes. - Falta de estructura. Los registros JSON no se pueden analizar sin soluciones adicionales.
- Sin rotación. El archivo de registro crecerá indefinidamente hasta llenar el disco.
En su lugar, use bibliotecas profesionales. Las dos más populares en Node.js son Winston y Pino.
2. Elección de biblioteca: Winston vs Pino
Ambas bibliotecas resuelven la misma tarea, pero tienen diferentes prioridades.
Winston — universal y flexible
Winston es la "navaja suiza" del registro. Soporta múltiples transportes (archivos, consola, HTTP, bases de datos) y es fácil de configurar.
const winston = require('winston');
const logger = winston.createLogger({ level: 'info', format: winston.format.json(), transports: [ new winston.transports.File({ filename: 'error.log', level: 'error' }), new winston.transports.File({ filename: 'combined.log' }), ],});
// En desarrollo, agregamos salida a la consolaif (process.env.NODE_ENV !== 'production') { logger.add(new winston.transports.Console({ format: winston.format.simple(), }));}
logger.info('Servidor iniciado en el puerto 3000');logger.error('Error de conexión a la BD', { db: 'postgres' });Pino — velocidad ante todo
Pino se posiciona como el registrador más rápido para Node.js. Es 5-6x más rápido que Winston gracias al uso de sonic-boom (escritura asíncrona). Ideal para proyectos de alta carga.
const pino = require('pino');
const logger = pino({ level: process.env.LOG_LEVEL || 'info', transport: { target: 'pino/file', options: { destination: './app.log' }, },});
logger.info({ user: 'admin' }, 'Usuario inició sesión');logger.error({ err: new Error('Timeout') }, 'La solicitud excedió el límite');Consejo: Para microservicios y API con alta carga, elija Pino. Para configuraciones complejas con múltiples transportes, elija Winston.
3. Niveles de registro: no escribas todo en info
Use la escala estándar de niveles (en orden ascendente de importancia):
trace/debug— solo para desarrollo. Depuración detallada.info— funcionamiento normal de la aplicación: inicio, solicitudes exitosas, eventos de negocio.warn— problemas potenciales: solicitudes lentas, falta de memoria, métodos obsoletos.error— excepciones, fallos, caídas. Deben estar siempre en un archivo separado o sistema de monitoreo.fatal— errores críticos después de los cuales la aplicación no puede continuar funcionando.
Configure la variable de entorno LOG_LEVEL para cambiar el nivel de filtrado sin reiniciar el código:
// Ejemplo con Winstonconst logger = winston.createLogger({ level: process.env.LOG_LEVEL || 'info', // ...});
// En