spinny:~/writing $ vim opentelemetry-nodejs-observability-guide.md
1~2La primera vez que realmente necesitas observabilidad no es cuando estás mirando tranquilamente un tablero. Es cuando un usuario escribe "el pago es lento", el gráfico de error parece normal y en los registros solo encuentra una fila de mensajes desconectados.3~4OpenTelemetry fue creado para evitar ese momento: no para tener más gráficos, sino para conectar las piezas. Una solicitud ingresa al API, llama a una base de datos, pasa por un proveedor externo, publica un trabajo en cola y tal vez falla tres servicios después. Sin rastreo distribuido, esa historia se reconstruye a mano. Con OpenTelemetry al menos tienes un mapa.5~6## El punto no es el trace, es la historia7~8Un trace es una secuencia de span. Dicho así suena frío. En la práctica, cada span es una parte de la historia: `POST /checkout`, `SELECT inventory`, `call payment provider`, `publish order.created`.9~10El valor surge cuando empiezas a responder preguntas reales:11~12- ¿Qué servicio externo se está desacelerando?13- ¿Los errores provienen de una versión específica?14- ¿El problema afecta a todos o sólo a un inquilino?15- ¿Un reintento oculta un tiempo de espera?16- ¿El trabajo asincrónico comienza pero luego muere en otro lugar?17~18Estas cuestiones no se pueden resolver con un `console.log` lanzado a toda prisa. De hecho, a menudo el registro añadido en caso de emergencia le ayuda hoy y se convierte en ruido mañana.19~20## ¿Cómo pondría esto en una aplicación? Node.js21~22La configuración más saludable es simple: la aplicación produce telemetría, el Collector decide dónde enviarla.23~24```text25Node.js app -> OpenTelemetry Collector -> backend di observability26```27~28¿Por qué no exportar directamente al proveedor? Porque al principio parece más rápido, luego te das cuenta de que cada servicio tiene diferentes configuraciones, diferentes reintentos, diferentes filtros y ningún punto central para eliminar datos sensibles o cambiar de destino.29~30El Collector es aburrido en todos los sentidos. Recibe OTLP, realiza procesamiento por lotes, puede filtrar, realizar muestreos, agregar atributos comunes y exportar a múltiples sistemas.31~32## Autoinstrumentación: buena, pero no suficiente33~34En Node.js comenzaría con la autoinstrumentación. Le brinda visibilidad inmediata de HTTP, marcos compatibles, bases de datos y bibliotecas comunes.35~36```bash37npm install @opentelemetry/sdk-node \38 @opentelemetry/auto-instrumentations-node \39 @opentelemetry/exporter-trace-otlp-http40```41~42Luego inicializas el SDK antes que el resto de la aplicación:43~44```typescript45import { NodeSDK } from '@opentelemetry/sdk-node';46import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';47import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';48~49const sdk = new NodeSDK({50 traceExporter: new OTLPTraceExporter({51 url: process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT,52 }),53 instrumentations: [getNodeAutoInstrumentations()],54});55~56sdk.start();57```58~59Sin embargo, esto ve el marco, no su producto. Sabe que realizó una consulta, pero no sabe que la consulta estaba en "crear pedido" o "renovar suscripción". Para eso necesitas span manuales en los puntos donde el dominio cuenta.60~61```typescript62const span = tracer.startSpan('checkout.create_order');63~64try {65 span.setAttribute('cart.items_count', input.items.length);66 const order = await createOrder(input);67 span.setAttribute('order.id', order.id);68 return order;69} catch (error) {70 span.recordException(error as Error);71 throw error;72} finally {73 span.end();74}75```76~77No pondría span manuales en ningún lado. Los pondría donde, a las tres de la mañana, me gustaría entender qué pasó sin leer la mitad del código base.78~79## Tres reglas que evitan mucho caos80~81Primera regla: cada servicio debe tener `service.name`, entorno y versión. Parece trivial, pero sin estos atributos un trace es mucho menos útil. Cuando una implementación rompe algo, desea filtrar por versión en dos segundos.82~83Segunda regla: no pongas datos sensibles en los atributos. Los correos electrónicos, tokens, cargas útiles de números enteros y direcciones no deberían terminar en un backend de observabilidad por accidente. Si necesita identificar a un usuario, considere las identificaciones internas, el hash o campos menos confidenciales.84~85Tercera regla: presta atención a la cardinalidad. `user.id` como atributo de trace puede tener sentido. Como etiqueta métrica, puede destruir sus costos y rendimiento.86~87## Métricas: pocas, pero buenas88~89Yo empezaría con métricas muy prácticas:90~91- tarifas, errores y duración de las solicitudes;92- latencia de dependencias externas;93- número de tiempos de espera y reintentos;94- profundidad de las colas;95- duración del trabajo;96- porcentaje de errores por versión.97~98El resto se agrega cuando es necesario. Los paneles llenos de gráficos que nadie mira son muebles, no observabilidad.99~100## Registros: sigue siendo útil, pero vinculado101~102Los registros no desaparecen. Simplemente se vuelven mucho más útiles cuando llevan `trace_id` y `span_id`. Por lo tanto, puede comenzar desde un registro de errores y abrir el trace, o comenzar desde un trace lento y leer solo los registros producidos en esa ruta.103~104Sin correlación, buscas agujas. Con correlación, al menos sabes en qué cajón mirar.105~106## La lista de verificación que usaría antes de decir "estamos cubiertos"107~108- El trace en realidad cruza múltiples servicios.109- Los registros incluyen `trace_id` y `span_id`.110- El Collector está configurado con límites de memoria y procesamiento por lotes.111- Los errores se registran en span.112- Existe una política de muestreo.113- Las métricas tienen cardinalidad controlada.114- Se filtran datos sensibles.115- Las alertas comienzan a partir de síntomas del usuario, no de gráficos aleatorios.116~117## Conclusión118~119OpenTelemetry no resuelve los problemas de producción por sí solo. Pero la forma de abordarlos cambia. En lugar de agregar registros a ciegas, comienza a seguir la ruta real de una solicitud.120~121Para mí la señal de que está funcionando es simple: cuando pasa algo, el equipo deja de preguntar "¿hacia dónde miramos?". y empieza a preguntar "¿por qué esa pieza es lenta?". Ahí es donde la observabilidad se convierte en una herramienta, no en una colección de paneles.122~123## Fuentes124~125- [OpenTelemetry: Overview](https://opentelemetry.io/docs/specs/otel/overview/)126- [OpenTelemetry Collector: Configuration](https://opentelemetry.io/docs/collector/configuration/)127- [OpenTelemetry JavaScript: Node.js getting started](https://opentelemetry.io/docs/languages/js/getting-started/nodejs/)128- [OpenTelemetry Semantic Conventions](https://opentelemetry.io/docs/concepts/semantic-conventions/)129~
NORMAL · opentelemetry-nodejs-observability-guide.md [readonly]129 lines · :q to close