For the complete documentation index, see llms.txt. This page is also available as Markdown.

Collector FE — Instrumentação Frontend com Grafana Faro

Guia de instalação e operação do Collector FE, o collector da Elven para Real User Monitoring com Grafana Faro

Ele recebe payloads do Faro Web SDK pelo endpoint POST /collect/:tenant/:token e faz fan-out para os três sinais da stack LGTM:

  • Loki: logs estruturados, eventos, medições e exceções.

  • Mimir: métricas RUM via Prometheus remote_write.

  • Tempo: traces via OTLP/HTTP protobuf a partir de traces.resourceSpans.

O Collector FE é implantado na infraestrutura do cliente ou no cluster Elven dedicado ao cliente. A Elven fornece os endpoints e tokens de escrita. Para Elven Cloud, normalmente o mesmo tenant/token usado em Loki também é reutilizado em Mimir e Tempo.


Índice

  • Visão geral

  • Arquitetura

  • Contrato de payload

  • Compatibilidade com clientes antigos

  • Autenticação e multi-tenancy

  • Variáveis de ambiente

  • Instalação Linux via script

  • Deploy Docker

  • Deploy Kubernetes

  • Configuração do Faro no frontend

  • Métricas geradas

  • Logs estruturados

  • Traces

  • Migração de clientes antigos

  • Health check e validação

  • Troubleshooting

  • FAQ


Visão geral

O Collector FE é um serviço HTTP em Go especializado em payloads do Grafana Faro Web SDK 2.3.1. Ele não substitui o OpenTelemetry Collector de backend; ele existe para receber telemetria de navegador de forma segura, validar o tenant/token e converter os sinais para a stack LGTM.

Fluxo de request:

  1. O browser envia POST /collect/<tenant>/<jwt-token>.

  2. O collector valida o JWT HS256 usando SECRET_KEY.

  3. O body é decodificado como payload Faro 2.3.1.

  4. O payload é normalizado em logs, observações de métricas e traces.

  5. Os sinks habilitados recebem o lote em filas internas.

  6. O request retorna 200 quando todos os sinks habilitados aceitarem o lote na fila.

  7. Se uma fila obrigatória estiver cheia ou indisponível para enqueue, o request retorna 503.

  8. Falhas depois do enqueue viram logs/métricas internas do collector e não mudam a resposta já enviada ao browser.


Arquitetura

Separação de responsabilidades:

Camada
Responsabilidade

Frontend

Inicializar Faro, definir app/environment/release, habilitar tracing quando necessário e enviar payloads.

Collector FE

Validar JWT, preservar contexto rico, controlar cardinalidade, gerar métricas RUM e despachar para sinks.

Loki

Armazenar sinais ricos e investigáveis como logs estruturados.

Mimir

Armazenar séries de métricas agregadas para dashboards e alertas.

Tempo

Armazenar spans enviados pelo Faro tracing.


Contrato de payload

O contrato primário é o TransportBody do Faro 2.3.1.

Campos de topo suportados:

Campo
Uso

meta

Metadados de app, browser, usuário, sessão, página e view.

logs

Logs capturados ou enviados manualmente pelo Faro.

events

Eventos de navegação, recurso, user action, tracing sidecar e eventos customizados.

measurements

Web Vitals e medições customizadas.

exceptions

Exceções JavaScript com stacktrace, contexto e fingerprint.

traces

Objeto OTLP contendo resourceSpans.

Metadados relevantes:

Campo
Exemplos

meta.app

name, namespace, release, version, environment, bundleId

meta.user

id, email, username, fullName, roles, hash, attributes

meta.session

id, attributes, overrides

meta.page

id, url, attributes

meta.browser

name, version, os, mobile, userAgent, language, brands, viewportWidth, viewportHeight

Sinais nativos tratados pelo collector:

Sinal Faro
Uso no collector

measurements.type="web-vitals"

Gera métricas para CLS, FCP, INP, LCP e TTFB.

events.name="faro.performance.navigation"

Gera métricas de navegação e fases de navegação.

events.name="faro.performance.resource"

Gera métricas de recursos, duração e bytes transferidos.

events.name="faro.user.action"

Fonte de verdade para métricas de user action.

events.name="faro.tracing.fetch"

Gera métricas HTTP client para fetch.

events.name="faro.tracing.xml-http-request"

Gera métricas HTTP client para XHR.

events.name="faro.navigation"

Opcional; só gera métricas se o evento existir no payload.

O collector não deriva métricas de traces brutos para evitar dupla contagem. Para HTTP client, use os eventos sidecar faro.tracing.*.


Compatibilidade com clientes antigos

O collector mantém compatibilidade com o payload JSON legado já aceito pela versão anterior quando ele representa logs, eventos, medições ou exceções do Faro. Esse payload é normalizado internamente para o modelo atual.

Limites importantes:

  • Payload Faro antigo em JSON continua aceito quando contém os campos estruturados que o collector já suportava.

  • Clientes que enviavam raw logfmt puro não devem ser migrados trocando apenas a URL. Eles precisam passar a enviar payload Faro JSON via SDK.

  • FID não é premissa da instrumentação atual. A métrica moderna de interação é INP.

  • traces só chegam quando o frontend instala @grafana/faro-web-tracing e registra TracingInstrumentation.

  • Custom measurements sem regra explícita geram contagem em faro_frontend_custom_measurements_total; séries semânticas detalhadas exigem METRICS_CUSTOM_MEASUREMENT_RULES.


Autenticação e multi-tenancy

Endpoint

Parte
Descrição

tenant

Identifica cliente/produto. Por padrão vira X-Scope-OrgID nos sinks multi-tenant.

token

JWT HS256 assinado com a SECRET_KEY configurada no collector.

JWT

Claims obrigatórias:

Claim
Regra

role

Deve ser admin ou user.

iss

Deve ser igual a JWT_ISSUER.

Claim opcional:

Claim
Regra

exp

Só é validada quando JWT_VALIDATE_EXP=true.

Exemplo:

O JWT fica visível no browser porque faz parte da URL do Faro. Use role: user, limite CORS por domínio e, em produção, prefira JWT_VALIDATE_EXP=true com rotação planejada.


Variáveis de ambiente

Essenciais

Variável
Obrigatória
Default
Descrição

SECRET_KEY

Sim

-

Chave HS256 para validar JWTs. Mínimo de 64 caracteres.

LOKI_URL

Sim

-

URL base do Loki. O collector adiciona /loki/api/v1/push.

LOKI_API_TOKEN

Sim

-

Token enviado como Authorization: Bearer ... para Loki.

ALLOW_ORIGINS

Sim

-

Origens CORS separadas por vírgula. Aceita * e https://*.example.com.

PORT

Não

3000

Porta HTTP do collector.

JWT_ISSUER

Não

trusted-issuer

Valor esperado na claim iss.

JWT_VALIDATE_EXP

Não

false

Rejeita JWT expirado quando true.

LOKI_URL deve ser base, por exemplo:

Não use:

Loki

Variável
Default
Descrição

LOKI_TIMEOUT

15s

Timeout por chamada ao Loki.

LOKI_QUEUE_SIZE

256

Tamanho da fila interna de streams.

LOKI_ENQUEUE_TIMEOUT

2s

Tempo máximo esperando espaço na fila.

LOKI_RETRY_ATTEMPTS

3

Tentativas de exportação por lote.

LOKI_RETRY_BACKOFF

500ms

Intervalo entre tentativas.

LOKI_MAX_EVENT_AGE

55m

Eventos mais antigos têm timestamp ajustado para evitar rejeição.

LOKI_MAX_FUTURE_SKEW

10m

Eventos muito no futuro têm timestamp ajustado.

Mimir remote_write

Métricas são opcionais e ficam desligadas por padrão.

Variável
Default
Descrição

METRICS_ENABLED

false

Habilita exportação Prometheus remote_write.

METRICS_REMOTE_WRITE_URL

-

Endpoint completo do remote_write. Obrigatório quando habilitado.

METRICS_REMOTE_WRITE_TIMEOUT

10s

Timeout do cliente remote_write.

METRICS_REMOTE_WRITE_FLUSH_INTERVAL

10s

Intervalo de flush das séries agregadas.

METRICS_QUEUE_SIZE

256

Tamanho da fila de observações.

METRICS_ENQUEUE_TIMEOUT

2s

Tempo máximo esperando espaço na fila.

METRICS_TENANT_MODE

request

request, fixed ou none.

METRICS_TENANT_ID

-

Tenant usado quando METRICS_TENANT_MODE=fixed.

METRICS_LABEL_ALLOWLIST

allowlist interna

Substitui a allowlist padrão de labels.

METRICS_CUSTOM_MEASUREMENT_RULES

-

JSON no formato {"tipo":["campo"]} para medições customizadas detalhadas.

METRICS_RETRY_ATTEMPTS

3

Tentativas de envio remote_write.

METRICS_RETRY_BACKOFF

500ms

Intervalo entre tentativas.

Auth do remote_write:

Variável
Descrição

METRICS_REMOTE_WRITE_AUTH_BEARER_TOKEN

Envia Authorization: Bearer ....

METRICS_REMOTE_WRITE_AUTH_USERNAME / METRICS_REMOTE_WRITE_AUTH_PASSWORD

Envia Basic Auth.

METRICS_REMOTE_WRITE_AUTH_HEADER_NAME / METRICS_REMOTE_WRITE_AUTH_HEADER_VALUE

Envia header customizado. As duas variáveis precisam estar preenchidas juntas.

Tempo OTLP/HTTP

Traces são opcionais e ficam desligados por padrão.

Variável
Default
Descrição

TRACES_ENABLED

false

Habilita exportação de traces.resourceSpans.

TRACES_OTLP_HTTP_URL

-

Endpoint completo OTLP/HTTP. Obrigatório quando habilitado.

TRACES_OTLP_HTTP_TIMEOUT

10s

Timeout do cliente OTLP/HTTP.

TRACES_OTLP_HTTP_COMPRESSION

none no binário, gzip no script

none ou gzip.

TRACES_FLUSH_INTERVAL

2s

Intervalo de flush dos batches.

TRACES_QUEUE_SIZE

256

Tamanho da fila de traces.

TRACES_ENQUEUE_TIMEOUT

2s

Tempo máximo esperando espaço na fila.

TRACES_BATCH_SIZE

20

Quantidade de resource spans para flush antecipado.

TRACES_TENANT_MODE

request

request, fixed ou none.

TRACES_TENANT_ID

-

Tenant usado quando TRACES_TENANT_MODE=fixed.

TRACES_TENANT_HEADER

X-Scope-OrgID

Header usado para propagar tenant.

TRACES_RETRY_ATTEMPTS

3

Tentativas de envio OTLP/HTTP.

TRACES_RETRY_BACKOFF

500ms

Intervalo entre tentativas.

Auth do OTLP/HTTP:

Variável
Descrição

TRACES_OTLP_AUTH_BEARER_TOKEN

Envia Authorization: Bearer ....

TRACES_OTLP_AUTH_USERNAME / TRACES_OTLP_AUTH_PASSWORD

Envia Basic Auth.

TRACES_OTLP_AUTH_HEADER_NAME / TRACES_OTLP_AUTH_HEADER_VALUE

Envia header customizado. As duas variáveis precisam estar preenchidas juntas.


Instalação Linux via script

O caminho recomendado para VM, EC2, bare metal e servidores Linux com systemd é o script:

O instalador:

  • Detecta a distribuição Linux.

  • Baixa o binário de release.

  • Valida as variáveis obrigatórias.

  • Remove /loki/api/v1/push de LOKI_URL se alguém informar a URL antiga.

  • Permite habilitar Mimir e Tempo no modo interativo.

  • Cria /etc/collector-fe-instrumentation/env com permissão 600.

  • Cria e inicia o serviço collector-fe-instrumentation.

  • Opcionalmente instala Caddy para HTTPS automático.

Script com envs: Loki somente

Para produção, prefira pinagem explícita da release do binário:

Script com envs: Loki + Mimir + Tempo

Por padrão, quando Mimir/Tempo estão habilitados no script, LOKI_API_TOKEN é reaproveitado como bearer token desses sinks. Para desabilitar esse comportamento:

Depois configure uma destas opções:

  • METRICS_REMOTE_WRITE_AUTH_BEARER_TOKEN

  • METRICS_REMOTE_WRITE_AUTH_USERNAME / METRICS_REMOTE_WRITE_AUTH_PASSWORD

  • METRICS_REMOTE_WRITE_AUTH_HEADER_NAME / METRICS_REMOTE_WRITE_AUTH_HEADER_VALUE

  • TRACES_OTLP_AUTH_BEARER_TOKEN

  • TRACES_OTLP_AUTH_USERNAME / TRACES_OTLP_AUTH_PASSWORD

  • TRACES_OTLP_AUTH_HEADER_NAME / TRACES_OTLP_AUTH_HEADER_VALUE

Instalação com Caddy

O DNS de CADDY_DOMAIN precisa apontar para a VM antes da instalação.

Arquivos instalados

Item
Caminho

Binário

/opt/collector-fe-instrumentation/collector-fe-instrumentation

Env

/etc/collector-fe-instrumentation/env

Serviço

/etc/systemd/system/collector-fe-instrumentation.service


Deploy Docker

Loki somente

Em produção, use uma tag explícita no lugar de <release-tag>.

Loki + Mimir + Tempo


Deploy Kubernetes

Exemplo mínimo para clusters Elven ou clusters do cliente.

Secret

Em cluster interno, prefira endpoints internos de Loki/Mimir/Tempo para evitar autenticação de borda entre componentes do mesmo cluster. Em endpoint público, configure auth bearer, basic ou header customizado conforme fornecido pela Elven.

values.yaml

Validação:


Configuração do Faro no frontend

Instale as versões da família Faro 2.3.1:

Inicialização base:

Env de frontend:

Sem @grafana/faro-web-tracing, o collector continua recebendo logs, events, measurements e exceptions, mas não terá traces.resourceSpans para enviar ao Tempo.


Métricas geradas

Quando METRICS_ENABLED=true, o collector exporta histogramas clássicos Prometheus e contadores via remote_write.

Famílias principais:

Métrica
Uso

faro_collector_requests_total

Requests recebidos pelo collector.

faro_collector_request_duration_seconds

Latência do endpoint /collect.

faro_collector_payload_bytes_total

Volume recebido.

faro_collector_sink_queue_length

Tamanho das filas por sink.

faro_collector_sink_enqueue_failures_total

Falhas para aceitar lote em fila.

faro_collector_sink_export_failures_total

Falhas de export pós-enqueue.

faro_collector_sink_export_duration_seconds

Duração dos exports por sink.

faro_frontend_signals_total

Total de sinais normalizados.

faro_frontend_logs_total

Logs por app/level.

faro_frontend_exceptions_total

Exceções por app/browser.

faro_frontend_web_vital_seconds

fcp, inp, lcp, ttfb.

faro_frontend_web_vital_ratio

cls.

faro_frontend_web_vital_phase_seconds

Campos numéricos de attribution.

faro_frontend_navigation_duration_seconds

Duração de navegação.

faro_frontend_navigation_phase_seconds

Fases de navegação.

faro_frontend_resource_duration_seconds

Duração de recursos.

faro_frontend_resource_transfer_bytes

Bytes transferidos por recurso.

faro_frontend_user_actions_total

Ações de usuário.

faro_frontend_user_action_duration_seconds

Duração de ações.

faro_frontend_http_client_requests_total

Requests fetch/XHR derivados de faro.tracing.*.

faro_frontend_http_client_duration_seconds

Latência fetch/XHR.

faro_frontend_custom_measurements_total

Contagem de custom measurements.

faro_frontend_custom_measurement_value

Valores detalhados apenas por regra explícita.

Labels de baixa cardinalidade promovidas por padrão:

Nunca promova como label:


Logs estruturados

Loki mantém os dados ricos para investigação. Os campos úteis incluem:

  • trace_id

  • span_id

  • action_name

  • session_id

  • user_id

  • page_url

  • event_name

  • measurement_type

  • atributos originais relevantes

Exemplo de consulta:

Para investigar erro:


Traces

Para traces funcionarem, duas coisas precisam estar verdadeiras:

  • Collector com TRACES_ENABLED=true e TRACES_OTLP_HTTP_URL configurado.

  • Frontend usando @grafana/faro-web-tracing@2.3.1 com TracingInstrumentation.

O collector exporta o subobjeto traces como ExportTraceServiceRequest OTLP/HTTP protobuf. O endpoint deve ser completo para evitar ambiguidade:

Em alguns ingresses da Elven, o endpoint público HTTP usa prefixo:

Em Kubernetes interno:


Migração de clientes antigos

Use este fluxo para clientes que estavam com versão antiga ou integração "só logfmt".

  1. Subir o collector novo primeiro. Habilite Loki e, se possível, Mimir/Tempo já na primeira janela.

  2. Manter o caminho antigo em paralelo. Não remova o fluxo antigo até validar que o frontend novo está mandando Faro JSON.

  3. Atualizar o frontend. Instale @grafana/faro-web-sdk@2.3.1 e, para traces, @grafana/faro-web-tracing@2.3.1.

  4. Configurar VITE_FARO_URL ou equivalente. A URL deve apontar para /collect/<tenant>/<jwt>.

  5. Canariar por uma aplicação ou ambiente. Comece por staging ou uma porcentagem baixa de tráfego.

  6. Validar os três sinais. Confirme logs no Loki, métricas no Mimir e traces no Tempo.

  7. Comparar com o dashboard antigo por 24h. Verifique se erros, sessões e tráfego batem.

  8. Cortar o caminho antigo. Só depois de confirmar que não há perda de dados relevantes.

Critérios de aceite:

  • POST /collect/:tenant/:token retorna 200.

  • Loki mostra logs/events/exceptions com app e environment corretos.

  • Mimir recebe faro_frontend_signals_total.

  • Web Vitals incluem INP e não dependem de FID.

  • Tempo mostra traces para a app quando tracing está habilitado no frontend.

  • Não há erro de export nos logs do collector.


Health check e validação

Endpoint:

Resposta esperada:

Comandos Linux:

Comandos Kubernetes:

Consultas úteis:


Troubleshooting

Serviço não inicia

Verifique:

Erros comuns:

Erro
Correção

missing required env: SECRET_KEY

Defina SECRET_KEY.

SECRET_KEY must be at least 64 characters

Use uma chave maior.

missing required env: LOKI_URL

Configure a URL base do Loki.

missing required env: LOKI_API_TOKEN

Configure o token.

missing required env: ALLOW_ORIGINS

Configure CORS.

missing required env: METRICS_REMOTE_WRITE_URL

Defina a URL ou desabilite METRICS_ENABLED.

missing required env: TRACES_OTLP_HTTP_URL

Defina a URL ou desabilite TRACES_ENABLED.

Faro retorna 401

Verifique:

  • O JWT foi assinado com a mesma SECRET_KEY.

  • O algoritmo é HS256.

  • role é admin ou user.

  • iss é igual a JWT_ISSUER.

  • Se JWT_VALIDATE_EXP=true, o token não expirou.

Faro retorna 503

503 indica que pelo menos um sink habilitado não conseguiu aceitar o lote na fila dentro de *_ENQUEUE_TIMEOUT.

Correções:

  • Aumente LOKI_QUEUE_SIZE, METRICS_QUEUE_SIZE ou TRACES_QUEUE_SIZE.

  • Verifique se o destino está respondendo.

  • Aumente réplicas do collector.

  • Verifique CPU/memória do pod ou da VM.

Logs chegam, mas métricas não

Verifique:

  • METRICS_ENABLED=true.

  • METRICS_REMOTE_WRITE_URL aponta para endpoint completo /api/v1/push.

  • Auth do Mimir está correta.

  • Não há erro em faro_collector_sink_export_failures_total{sink="metrics"}.

  • O payload contém eventos/measurements que geram métricas.

Logs e métricas chegam, mas traces não

Verifique:

  • TRACES_ENABLED=true.

  • TRACES_OTLP_HTTP_URL aponta para endpoint completo OTLP/HTTP.

  • Frontend instalou @grafana/faro-web-tracing.

  • TracingInstrumentation foi registrado.

  • O payload tem traces.resourceSpans.

  • Não há erro em faro_collector_sink_export_failures_total{sink="traces"}.

URL do Loki com path antigo

Use somente a base:

O collector adiciona /loki/api/v1/push. Informar o path completo pode gerar URL duplicada.


FAQ

O Collector FE envia traces também?

Sim, quando TRACES_ENABLED=true e o payload contém traces.resourceSpans. O frontend precisa usar @grafana/faro-web-tracing e TracingInstrumentation.

Preciso da env do Mimir?

Sim, se quiser métricas: METRICS_ENABLED=true e METRICS_REMOTE_WRITE_URL. Para Elven Cloud, normalmente o token pode ser o mesmo do Loki em METRICS_REMOTE_WRITE_AUTH_BEARER_TOKEN.

Preciso da env do Tempo?

Sim, se quiser traces: TRACES_ENABLED=true e TRACES_OTLP_HTTP_URL. Para Elven Cloud, normalmente o token pode ser o mesmo do Loki em TRACES_OTLP_AUTH_BEARER_TOKEN.

Posso usar o mesmo tenant para Loki, Mimir e Tempo?

Sim. O default é request, ou seja, o tenant da rota /collect/<tenant>/<jwt> é propagado para os sinks multi-tenant.

O collector aceita clientes antigos?

Aceita payload JSON legado já compatível com o collector anterior. Não trate raw logfmt puro como compatível com o endpoint Faro novo.

Qual é o risco de cardinalidade?

O collector promove somente labels de baixa cardinalidade para métricas. Dados ricos como URL completa, user id, session id, trace id e span id ficam em Loki, não em labels de Mimir.

Como rodo uma atualização segura?

Reexecute o script ou faça rollout Kubernetes com a nova imagem. Valide /health, Loki, Mimir e Tempo antes de remover o caminho antigo.

Last updated

Was this helpful?