Registro en aplicaciones TypeScript: mejores prácticas en la práctica

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Registro en aplicaciones TypeScript: mejores prácticas en la práctica



El registro es una parte fundamental de cualquier aplicación en producción. Permite no solo rastrear la ejecución del código y encontrar errores, sino también realizar auditorías de seguridad, analizar el rendimiento y depurar escenarios complejos. En TypeScript, con su potente sistema de tipos, el enfoque de registro se vuelve aún más flexible y confiable. En este artículo, analizaremos las mejores prácticas de registro con ejemplos concretos.



1. Elección de la biblioteca y configuración del logger



Lo primero por empezar es elegir una biblioteca adecuada. Entre las soluciones populares destacan winston y pino. Ambas soportan TypeScript de forma nativa, pero tienen diferentes prioridades: winston — flexibilidad y funcionalidad rica, pino — máximo rendimiento.



Consideremos un ejemplo de configuración de winston con tipado:



import winston from 'winston';

const logger = winston.createLogger({ level: process.env.LOG_LEVEL || 'info', format: winston.format.combine( winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }), winston.format.errors({ stack: true }), winston.format.json() ), defaultMeta: { service: 'user-service' }, transports: [ new winston.transports.Console({ format: winston.format.combine( winston.format.colorize(), winston.format.simple() ), }), new winston.transports.File({ filename: 'logs/error.log', level: 'error' }), new winston.transports.File({ filename: 'logs/combined.log' }), ],});

export default logger;


Para pino, la configuración será más concisa, pero igualmente efectiva:



import pino from 'pino';

const logger = pino({ level: process.env.LOG_LEVEL || 'info', transport: { target: 'pino-pretty', options: { colorize: true, translateTime: 'SYS:standard', }, },});

export default logger;


Consejo: Siempre externalice la configuración del nivel de registro en variables de entorno (LOG_LEVEL). En producción normalmente se usa info o warn, y en desarrollo — debug.



2. Registro estructurado y contexto



Uno de los principales errores es registrar cadenas simples. En su lugar, utilice objetos estructurados. Estos permiten filtrar y agregar fácilmente los registros en sistemas como ELK, Grafana o Datadog.



Ejemplo de mal registro:



logger.info('User logged in successfully');


Ejemplo de buen registro con contexto:



logger.info({  message: 'User logged in',  userId: user.id,  email: user.email,  loginMethod: 'oauth',  ip: request.ip,  duration: Date.now() - startTime,});


Para mayor comodidad, puede crear un envoltorio tipado:



interface LogContext {  requestId?: string;  userId?: string;  action?: string;  [key: string]: unknown;}

function logWithContext(message: string, context: LogContext = {}): void { logger.info({ message, ...context });}

// UsologWithContext('Order processed', { orderId: '12345', userId: 'user_678', total: 99.99 });


Este enfoque garantiza que cada registro contenga información clave para el análisis.



3. Registro de errores y excepciones



El manejo de errores es la parte más importante del registro. Siempre registre la traza completa del error y el contexto en el que ocurrió. No use console.error — no ofrece flexibilidad para rotación y formato.



Patrón correcto con TypeScript:



import logger from './logger';

async function fetchUserData(userId: string): Promise<UserData> { try { const response = await api.get(`/users/${userId}`); ret

Blogs

Book Recommendations