
OpenTelemetry en una app Vue: qué funciona hoy y qué sigue siendo experimental (2026)
- vuetelemetry
- Guías
- 9 min de lectura
OpenTelemetry puede trazar una app Vue desde la carga del documento hasta la llamada fetch, pero la parte del navegador está mucho menos asentada que la del servidor. Qué paquetes son estables, qué captura de verdad la auto-instrumentación, el hueco propio de Vue que nadie cubre y dónde acaban los datos.
Tu app Vue se ejecuta en la máquina de otra persona, en una red que no controlas y en una versión de navegador que no elegiste. Los logs del servidor te dicen que llegó una petición y salió una respuesta; no te dicen nada de los cuatro segundos que el usuario pasó mirando un spinner. OpenTelemetry es el estándar neutral que cierra ese hueco: una única forma de producir trazas, métricas y logs, y cualquier backend que hable el protocolo puede recibirlos.
La recompensa es una sola traza que empieza en el navegador y termina en tu base de datos. Un span de carga del documento, luego el fetch que dispara la página, luego el span de servidor que ese fetch provocó, todo cosido por el contexto de traza propagado en las cabeceras HTTP. Eso es lo que no consigues ni con las devtools de Vue ni con el agente de servidor de tu APM por separado, y es justo la razón por la que se recurre a OpenTelemetry en el front.
SDK estable, terreno movedizo

Vamos con la parte honesta, la que se suele pasar por alto. El SDK de trazado para navegador, `@opentelemetry/sdk-trace-web`, está marcado como estable en el repositorio de OpenTelemetry JS. Pero la documentación oficial es tajante sobre el cuadro general: «Client instrumentation for the browser is experimental and mostly unspecified». Ambas afirmaciones son ciertas a la vez y no se contradicen. La fontanería que crea y exporta spans está asentada; las convenciones sobre qué debería contener un span de navegador, y qué señales debería emitir un front, no lo están.
También hay un esfuerzo más reciente que conviene conocer antes de construir sobre suposiciones. El repositorio `open-telemetry/opentelemetry-browser` publica `@opentelemetry/browser-instrumentation`, y su estado figura como experimental. Su enfoque difiere de los paquetes antiguos: emite registros de log estructurados para el rendimiento del navegador y las interacciones de usuario, como complemento a las instrumentaciones basadas en spans que se mantienen en otro sitio. Si empiezas hoy, construye sobre la vía estable de spans y trata la vía basada en eventos como algo que vigilar, no de lo que depender.
Los paquetes y el montaje
El conjunto de paquetes útil es corto. `@opentelemetry/api` aporta la interfaz de tracer, `@opentelemetry/sdk-trace-web` el provider de navegador, `@opentelemetry/sdk-trace-base` los procesadores de spans y el exportador de consola, `@opentelemetry/context-zone` el gestor de contexto y `@opentelemetry/instrumentation` la utilidad de registro. Las instrumentaciones individuales se distribuyen aparte, igual que los exportadores OTLP. Nada de esto es específico de Vue, lo que ya es una pista de lo que viene.
- `@opentelemetry/sdk-trace-web` es estable, pero la documentación oficial afirma que la instrumentación cliente para el navegador es experimental y en gran parte no especificada
- Tres llamadas para montarlo: crear `WebTracerProvider` con sus procesadores de spans, `provider.register()` con `ZoneContextManager` y luego `registerInstrumentations()`
- La cobertura lista para usar es carga de documento, interacciones de usuario, XHR y fetch, agrupados en `@opentelemetry/auto-instrumentations-web`
- No existe instrumentación oficial de Vue: los spans de componentes y de router son código que escribes y mantienes tú
- `@opentelemetry/browser-instrumentation` (el repositorio más reciente opentelemetry-browser) es experimental y emite registros de log estructurados en lugar de spans
- `SimpleSpanProcessor` con consola para desarrollo, `BatchSpanProcessor` con un exportador OTLP para producción
El montaje son tres llamadas. Creas el provider con sus procesadores de spans, por ejemplo `new WebTracerProvider({ spanProcessors: [new SimpleSpanProcessor(new ConsoleSpanExporter())] })`. Lo registras con un gestor de contexto, `provider.register({ contextManager: new ZoneContextManager() })`. Luego registras tus instrumentaciones con `registerInstrumentations({ instrumentations: [new DocumentLoadInstrumentation()] })`. La consola y `SimpleSpanProcessor` son para desarrollo; en producción quieres `BatchSpanProcessor` y un exportador OTLP, para que los spans salgan por lotes en vez de una petición por span.
Qué captura la auto-instrumentación
Lo que capturan de verdad las instrumentaciones ya hechas es más estrecho de lo que la gente espera. `@opentelemetry/instrumentation-document-load` produce spans para la carga del documento y el navigation timing. `@opentelemetry/instrumentation-user-interaction` traza interacciones de usuario, como los clics. `@opentelemetry/instrumentation-xml-http-request` y su equivalente para fetch cubren las peticiones salientes. `@opentelemetry/auto-instrumentations-web` los agrupa para registrar uno en lugar de cuatro. En conjunto obtienes carga de página, clics y llamadas de red: cobertura real, pero cobertura del navegador, no de tus componentes.
El gestor de contexto merece una parada. `ZoneContextManager` existe porque el contexto asíncrono no se propaga solo en un navegador: sin él, un span abierto antes de un await pierde a menudo a su padre y tu traza se fragmenta en huérfanos. Se apoya en zone.js, lo que implica enviar y ejecutar esa biblioteca en tu bundle. Es un coste real en peso y en globals parcheados, y es justo el tipo de compromiso que conviene medir en vez de suponer, sobre todo en un stack que cuida sus Core Web Vitals.
El hueco con forma de Vue
Ahora el hueco. No existe una instrumentación oficial de Vue. Ni en el repositorio principal ni en los paquetes contrib. Lo que circula como «instrumentación de Vue» en entradas de blog y guías de proveedores es código escrito a mano: spans abiertos en los hooks del ciclo de vida, spans envueltos alrededor de los guards de navegación del router, un plugin que arranca un span por renderizado de componente. Es perfectamente razonable construirlo y puede ser genuinamente útil, pero conviene saber que lo escribes y lo mantienes tú, sin convenciones semánticas a las que ajustarte y sin un upstream del que heredar correcciones.
Dónde van los datos es la última decisión, y la que determina si todo esto sale rentable. El exportador habla OTLP sobre HTTP hacia un colector o directamente hacia un backend; a partir de ahí la elección de herramienta es tuya, precisamente porque el estándar es neutral. Empieza más pequeño de lo que crees: `ConsoleSpanExporter` hasta que los spans se vean bien en las devtools, luego document-load y fetch hacia un backend real, y luego decide si los spans a nivel de componente se ganan su sitio. Instrumentarlo todo el primer día es como los proyectos de observabilidad en el front acaban convertidos en ruido que nadie lee.



El gestor de contexto merece una parada. `ZoneContextManager` existe porque el contexto asíncrono no se propaga solo en un navegador: sin él, un span abierto antes de un await pierde a menudo a su padre y tu traza se fragmenta en huérfanos. Se apoya en zone.js, lo que implica enviar y ejecutar esa biblioteca en tu bundle. Es un coste real en peso y en globals parcheados, y es justo el tipo de compromiso que conviene medir en vez de suponer, sobre todo en un stack que cuida sus Core Web Vitals.