Monitoreo en TypeScript: trazabilidad, métricas y registros para Node.js

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

Observabilidad en TypeScript: de la caja negra al sistema transparente

\n\n

Imagina que tu aplicación TypeScript es un mecanismo complejo de miles de engranajes. Todo funciona perfectamente hasta que se rompe. Y entonces recibes un mensaje: «El sitio va lento». ¿Dónde buscar el problema? ¿Base de datos? ¿API? ¿O simplemente cayó uno de los microservicios?

\n\n

Sin observabilidad, estarás adivinando como un chamán con su tambor. Con observabilidad, ves el panorama completo: dónde cayó el rendimiento, qué solicitud causó el error y por qué hubo una fuga de memoria.

\n\n

En este artículo, analizaremos los tres pilares de la observabilidad — trazabilidad, métricas y registros — y aprenderemos a implementarlos en aplicaciones TypeScript con ejemplos reales. Descubrirás cómo transformar tu aplicación de una caja negra a un sistema transparente que se puede diagnosticar en minutos.

\n\n

¿Por qué la observabilidad es crítica para las aplicaciones TypeScript?

\n\n

TypeScript no es solo una extensión de JavaScript. Es un lenguaje con el que se escribe backend para sistemas de alta carga, microservicios e incluso herramientas CLI. Y cuanto más complejo es el sistema, más importante es entender lo que sucede en él.

\n\n

El registro tradicional está bien, pero no es suficiente. Cuando tienes 50 microservicios, los registros se convierten en ruido blanco. Necesitas:

\n\n
    \n
  • Trazabilidad — para rastrear la ruta de una sola solicitud a través de todos los servicios.
  • \n
  • Métricas — para ver que la RAM crece como la espuma.
  • \n
  • Registros estructurados — para no buscar una aguja en un pajar.
  • \n
\n\n

Implementemos esto en una aplicación real.

\n\n

Trazabilidad en TypeScript: OpenTelemetry en la práctica

\n\n

La trazabilidad es la historia de vida de una sola solicitud. Ves cuánto tiempo tomó cada paso: desde la solicitud HTTP hasta la consulta a la base de datos. En TypeScript, el estándar de facto es OpenTelemetry.

\n\n

Instalación y configuración de OpenTelemetry

\n\n
npm install @opentelemetry/api @opentelemetry/sdk-node @opentelemetry/auto-instrumentations-node @opentelemetry/exporter-jaeger
\n\n

Creemos un archivo tracing.ts para inicializar la trazabilidad:

\n\n
import { NodeSDK } from '@opentelemetry/sdk-node';\nimport { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';\nimport { JaegerExporter } from '@opentelemetry/exporter-jaeger';\nimport { Resource } from '@opentelemetry/resources';\nimport { SemanticResourceAttributes } from '@opentelemetry/semantic-conventions';\n\nconst jaegerExporter = new JaegerExporter({\n    endpoint: 'http://localhost:14268/api/traces',\n    serviceName: 'my-typescript-app',\n});\n\nconst sdk = new NodeSDK({\n    resource: new Resource({\n        [SemanticResourceAttributes.SERVICE_NAME]: 'my-typescript-app',\n        [SemanticResourceAttributes.SERVICE_VERSION]: '1.0.0',\n    }),\n    traceExporter: jaegerExporter,\n    instrumentations: [getNodeAutoInstrumentations()],\n});\n\nsdk.start();\n
\n\n

Ahora, cada solicitud HTTP, cada llamada a la base de datos se rastreará automáticamente. Verás en Jaeger UI (o Grafana Tempo) el mapa completo de llamadas.

\n\n

Creación manual de spans

\n\n

La autoinstrumentación es genial, pero a veces necesitas agregar tus propias etiquetas. Por ejemplo, medir el tiempo de ejecución de una lógica de negocio compleja:

\n\n
import { trace } from '@opentelemetry/api';\n\nconst tracer = trace.getTracer('business-logic');\n\nasync function processOrder(orderId: string): Promise<void> {\n    const span = tracer.startSpan('process-order', {\n        attributes: { 'order.id': orderId },\n    });\n\n    try {\n        // Tu lógica de procesamiento de pedidos\n        await validateOrder(orderId);\n        await chargePayment(orderId);\n        await sendConfirmation(orderId);\n\n        span.setStatus({ code: 1 }); // OK\n    } catch (error) {\n        span.recordException(error as Error);\n        span.setStatus                

Blogs

Book Recommendations