OpenTelemetry numa app Vue: o que funciona hoje e o que ainda é experimental (2026)

  • vuetelemetry
  • Guias
  • 9 min de leitura

O OpenTelemetry consegue traçar uma app Vue desde o carregamento do documento até à chamada fetch, mas a parte do navegador está bem menos assente do que a do servidor. Que pacotes são estáveis, o que a auto-instrumentação capta mesmo, o buraco próprio do Vue que ninguém preenche e onde acabam os dados.

A tua app Vue corre na máquina de outra pessoa, numa rede que não controlas, numa versão de navegador que não escolheste. Os logs do servidor dizem-te que chegou um pedido e saiu uma resposta; não te dizem nada sobre os quatro segundos que o utilizador passou a olhar para um spinner. O OpenTelemetry é o padrão neutro que fecha esse buraco: uma única forma de produzir traços, métricas e logs, e qualquer backend que fale o protocolo pode recebê-los.

O ganho é um único traço que começa no navegador e termina na tua base de dados. Um span de carregamento do documento, depois o fetch que a página dispara, depois o span de servidor que esse fetch provocou, tudo cosido pelo contexto de traço propagado nos cabeçalhos HTTP. É precisamente o que nem as devtools do Vue nem o agente do lado do servidor do teu APM dão sozinhos, e é por isso que se recorre ao OpenTelemetry no front end.

SDK estavel, terreno movedico

Grande plano de código JavaScript que usa jQuery para ler a posição de deslocamento da janela: o tipo de trabalho do lado do navegador que uma instrumentação tem de observar de fora.
Grande plano de código JavaScript que usa jQuery para ler a posição de deslocamento da janela: o tipo de trabalho do lado do navegador que uma instrumentação tem de observar de fora.

Agora a parte honesta, a que se costuma passar ao lado. O SDK de tracing para navegador, `@opentelemetry/sdk-trace-web`, está marcado como estável no repositório do OpenTelemetry JS. Mas a documentação oficial é clara quanto ao quadro geral: «Client instrumentation for the browser is experimental and mostly unspecified». As duas afirmações são verdadeiras ao mesmo tempo e não se contradizem. A canalização que cria e exporta spans está assente; as convenções sobre o que um span de navegador deve conter, e que sinais um front end deve emitir, não estão.

Há também um esforço mais recente que convém conhecer antes de construir sobre suposições. O repositório `open-telemetry/opentelemetry-browser` publica `@opentelemetry/browser-instrumentation`, cujo estado consta como experimental. A sua abordagem difere dos pacotes mais antigos: emite registos de log estruturados para o desempenho do navegador e as interações do utilizador, como complemento às instrumentações baseadas em spans mantidas noutro lado. Quem começa hoje deve construir sobre a via estável dos spans e tratar a via baseada em eventos como algo a vigiar, não de que depender.

Os pacotes e a montagem

O conjunto de pacotes útil é curto. O `@opentelemetry/api` dá a interface de tracer, o `@opentelemetry/sdk-trace-web` o provider de navegador, o `@opentelemetry/sdk-trace-base` os processadores de spans e o exportador de consola, o `@opentelemetry/context-zone` o gestor de contexto e o `@opentelemetry/instrumentation` o utilitário de registo. As instrumentações individuais vêm à parte, tal como os exportadores OTLP. Nada disto é específico do Vue, o que já é uma pista sobre o que se segue.

  • O `@opentelemetry/sdk-trace-web` é estável, mas a documentação oficial afirma que a instrumentação cliente para o navegador é experimental e em grande parte não especificada
  • Três chamadas para o montar: criar `WebTracerProvider` com os processadores de spans, `provider.register()` com `ZoneContextManager`, depois `registerInstrumentations()`
  • A cobertura pronta a usar é carregamento do documento, interações do utilizador, XHR e fetch - agrupados no `@opentelemetry/auto-instrumentations-web`
  • Não existe instrumentação Vue oficial: os spans de componentes e de router são código que escreves e manténs tu
  • O `@opentelemetry/browser-instrumentation` (o mais recente repositório opentelemetry-browser) é experimental e emite registos de log estruturados em vez de spans
  • `SimpleSpanProcessor` com consola para desenvolvimento, `BatchSpanProcessor` com um exportador OTLP para produção

A montagem são três chamadas. Crias o provider com os seus processadores de spans, por exemplo `new WebTracerProvider({ spanProcessors: [new SimpleSpanProcessor(new ConsoleSpanExporter())] })`. Registá-lo com um gestor de contexto, `provider.register({ contextManager: new ZoneContextManager() })`. Depois registas as tuas instrumentações com `registerInstrumentations({ instrumentations: [new DocumentLoadInstrumentation()] })`. A consola e o `SimpleSpanProcessor` servem para desenvolvimento; em produção queres `BatchSpanProcessor` e um exportador OTLP, para que os spans saiam em lotes em vez de um pedido por span.

O que a auto-instrumentacao capta

O que as instrumentações prontas captam de facto é mais estreito do que se espera. O `@opentelemetry/instrumentation-document-load` produz spans para o carregamento do documento e o navigation timing. O `@opentelemetry/instrumentation-user-interaction` traça interações do utilizador, os cliques por exemplo. O `@opentelemetry/instrumentation-xml-http-request` e o equivalente para fetch cobrem os pedidos de saída. O `@opentelemetry/auto-instrumentations-web` agrupa-os, para registares um em vez de quatro. No conjunto obténs carregamento de página, cliques e chamadas de rede: cobertura real, mas cobertura do navegador, não dos teus componentes.

O gestor de contexto merece uma paragem. O `ZoneContextManager` existe porque o contexto assíncrono não se propaga sozinho num navegador: sem ele, um span aberto antes de um await perde muitas vezes o seu pai, e o teu traço fragmenta-se em órfãos. Assenta no zone.js, o que implica enviar e executar essa biblioteca no teu bundle. É um custo real em peso e em globals remendados, e é justamente o tipo de compromisso que convém medir em vez de supor, sobretudo numa stack que trabalha os seus Core Web Vitals.

O gestor de contexto merece uma paragem. O `ZoneContextManager` existe porque o contexto assíncrono não se propaga sozinho num navegador: sem ele, um span aberto antes de um await perde muitas vezes o seu pai, e o teu traço fragmenta-se em órfãos. Assenta no zone.js, o que implica enviar e executar essa biblioteca no teu bundle. É um custo real em peso e em globals remendados, e é justamente o tipo de compromisso que convém medir em vez de supor, sobretudo numa stack que trabalha os seus Core Web Vitals.

- vuetelemetry

O buraco com a forma do Vue

Agora o buraco. Não existe uma instrumentação Vue oficial. Nem no repositório principal nem nos pacotes contrib. O que circula como «instrumentação Vue» em artigos de blogue e guias de fornecedores é código escrito à mão: spans abertos nos hooks do ciclo de vida, spans envolvendo os navigation guards do router, um plugin que arranca um span por renderização de componente. É perfeitamente razoável construí-lo e pode servir mesmo, mas convém saber que és tu que o escreves e manténs, sem convenções semânticas a que te ajustares e sem um upstream de que herdar correções.

Para onde vão os dados é a última decisão, e a que determina se tudo isto compensa. O exportador fala OTLP sobre HTTP para um coletor ou directamente para um backend; a partir daí a escolha da ferramenta é tua, precisamente porque o padrão é neutro. Começa mais pequeno do que pensas: `ConsoleSpanExporter` até os spans parecerem correctos nas devtools, depois document-load e fetch para um backend a sério, e só depois decide se os spans ao nível de componente merecem o lugar. Instrumentar tudo no primeiro dia é como os projectos de observabilidade no front end acabam em ruído que ninguém lê.

Stack relacionado