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:
O browser envia
POST /collect/<tenant>/<jwt-token>.O collector valida o JWT HS256 usando
SECRET_KEY.O body é decodificado como payload Faro 2.3.1.
O payload é normalizado em logs, observações de métricas e traces.
Os sinks habilitados recebem o lote em filas internas.
O request retorna
200quando todos os sinks habilitados aceitarem o lote na fila.Se uma fila obrigatória estiver cheia ou indisponível para enqueue, o request retorna
503.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:
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:
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:
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:
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.
FIDnão é premissa da instrumentação atual. A métrica moderna de interação éINP.tracessó chegam quando o frontend instala@grafana/faro-web-tracinge registraTracingInstrumentation.Custom measurements sem regra explícita geram contagem em
faro_frontend_custom_measurements_total; séries semânticas detalhadas exigemMETRICS_CUSTOM_MEASUREMENT_RULES.
Autenticação e multi-tenancy
Endpoint
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:
role
Deve ser admin ou user.
iss
Deve ser igual a JWT_ISSUER.
Claim opcional:
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, prefiraJWT_VALIDATE_EXP=truecom rotação planejada.
Variáveis de ambiente
Essenciais
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
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.
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:
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.
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:
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/pushdeLOKI_URLse alguém informar a URL antiga.Permite habilitar Mimir e Tempo no modo interativo.
Cria
/etc/collector-fe-instrumentation/envcom permissão600.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_TOKENMETRICS_REMOTE_WRITE_AUTH_USERNAME/METRICS_REMOTE_WRITE_AUTH_PASSWORDMETRICS_REMOTE_WRITE_AUTH_HEADER_NAME/METRICS_REMOTE_WRITE_AUTH_HEADER_VALUETRACES_OTLP_AUTH_BEARER_TOKENTRACES_OTLP_AUTH_USERNAME/TRACES_OTLP_AUTH_PASSWORDTRACES_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
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:
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_idspan_idaction_namesession_iduser_idpage_urlevent_namemeasurement_typeatributos originais relevantes
Exemplo de consulta:
Para investigar erro:
Traces
Para traces funcionarem, duas coisas precisam estar verdadeiras:
Collector com
TRACES_ENABLED=trueeTRACES_OTLP_HTTP_URLconfigurado.Frontend usando
@grafana/faro-web-tracing@2.3.1comTracingInstrumentation.
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".
Subir o collector novo primeiro. Habilite Loki e, se possível, Mimir/Tempo já na primeira janela.
Manter o caminho antigo em paralelo. Não remova o fluxo antigo até validar que o frontend novo está mandando Faro JSON.
Atualizar o frontend. Instale
@grafana/faro-web-sdk@2.3.1e, para traces,@grafana/faro-web-tracing@2.3.1.Configurar
VITE_FARO_URLou equivalente. A URL deve apontar para/collect/<tenant>/<jwt>.Canariar por uma aplicação ou ambiente. Comece por staging ou uma porcentagem baixa de tráfego.
Validar os três sinais. Confirme logs no Loki, métricas no Mimir e traces no Tempo.
Comparar com o dashboard antigo por 24h. Verifique se erros, sessões e tráfego batem.
Cortar o caminho antigo. Só depois de confirmar que não há perda de dados relevantes.
Critérios de aceite:
POST /collect/:tenant/:tokenretorna200.Loki mostra logs/events/exceptions com
appeenvironmentcorretos.Mimir recebe
faro_frontend_signals_total.Web Vitals incluem
INPe não dependem deFID.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:
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éadminouuser.issé igual aJWT_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_SIZEouTRACES_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_URLaponta 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_URLaponta para endpoint completo OTLP/HTTP.Frontend instalou
@grafana/faro-web-tracing.TracingInstrumentationfoi 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?

