¿Tu aplicación es una caja negra? Es hora de solucionarlo
\n\n¿Alguna vez te has sorprendido pensando: «¿Por qué mi servicio en Node.js va lento, aunque el código es perfecto?» ¿O recibiste una queja de un usuario, pero no pudiste entender qué salió mal? ¿Te suena familiar? Bienvenido al mundo donde sin observabilidad en JavaScript trabajas a ciegas.
\n\nLa observabilidad no es solo una palabra de moda. Es un enfoque que transforma tu código de una caja negra a un sistema transparente. Aprenderemos a hacerle preguntas: «¿Quién tiene la culpa?» (trazabilidad), «¿Qué está pasando ahora mismo?» (métricas) y «¿Qué pasó ayer a las 3:15?» (registros).
\n\nEn este artículo analizaremos los tres pilares de la observabilidad en Node.js: trazabilidad, métricas y registros. Obtendrás ejemplos de código listos para usar y entenderás cómo implementar estas prácticas hoy mismo. ¡Vamos allá!
\n\nTrazabilidad en JavaScript: el viaje de la solicitud
\n\nImagina que un usuario hace clic en el botón «Realizar pedido». Esta solicitud pasa por API Gateway, el servicio de autenticación, el carrito, la pasarela de pago y la base de datos. Si algo se rompe, ¿dónde buscar? La trazabilidad (o distributed tracing) te da un mapa de este viaje.
\n\n¿Qué es la trazabilidad en palabras sencillas?
\n\nLa trazabilidad es una forma de rastrear el camino de una solicitud específica a través de todos los microservicios y funciones. Cada paso es un span, y toda la cadena es un trace. Ves cuánto tiempo tomó cada etapa y dónde ocurrió el error.
\n\nOpenTelemetry: estándar para observabilidad en JavaScript
\n\nOpenTelemetry (OTel) es el estándar de la industria para recopilar traces, métricas y registros. Es compatible con todas las principales nubes y herramientas (Jaeger, Zipkin, Grafana).
\n\nInstalación:
\nnpm install @opentelemetry/api @opentelemetry/sdk-node @opentelemetry/auto-instrumentations-node\n\nEjemplo básico de trazabilidad para una aplicación Express:
\nconst { NodeTracerProvider } = require('@opentelemetry/sdk-trace-node');\nconst { SimpleSpanProcessor } = require('@opentelemetry/sdk-trace-base');\nconst { ConsoleSpanExporter } = require('@opentelemetry/exporter-console');\nconst { ExpressInstrumentation } = require('@opentelemetry/instrumentation-express');\nconst { HttpInstrumentation } = require('@opentelemetry/instrumentation-http');\n\nconst provider = new NodeTracerProvider();\nprovider.addSpanProcessor(new SimpleSpanProcessor(new ConsoleSpanExporter()));\nprovider.register();\n\nconst { getTracer } = require('@opentelemetry/api');\nconst tracer = getTracer('my-app');\n\n// Trazabilidad automática de HTTP y Express\nconst { registerInstrumentations } = require('@opentelemetry/instrumentation');\nregisterInstrumentations({\n tracerProvider: provider,\n instrumentations: [\n new ExpressInstrumentation(),\n new HttpInstrumentation()\n ]\n});\n\n// Ahora cada solicitud creará un trace con spans\nconst express = require('express');\nconst app = express();\n\napp.get('/api/order', async (req, res) => {\n // Span manual para la lógica de negocio\n const span = tracer.startSpan('processPayment');\n try {\n // ... tu lógica\n await new Promise(r => setTimeout(r, 100)); // simulación\n span.setStatus({ code: 1 }); // OK\n } catch (err) {\n span.setStatus({ code: 2, message: err.message }); // ERROR\n throw err;\n } finally {\n span.end();\n }\n res.send('Order created');\n});\n\napp.listen(3000);\n\nAhora en la consola verás datos estructurados: qué solicitud, cuánto tiempo tomó cada middleware, dónde hubo un error. Esto es observabilidad javascript en acción.
\n\nMétricas: el pulso de tu aplicación
\n\nLa trazabilidad es buena para solicitudes individuales, pero ¿qué hay del panorama general? ¿Cuántas solicitudes por segundo? ¿Cuál es la latencia? ¿Cuánta memoria consume tu Node.js? De esto se encargan las métricas.
\n\nPrometheus y cliente para Node.js
\n\nPrometheus es el estándar de facto para la recolección de métricas. «Extrae» datos de tu aplicación a través de HTTP.