Tracing distribuído — Tempo + OpenTelemetry¶
Read in your language: English · Português · Español
Status do escopo (pós-congelamento de escopo 2026-05-10) — Ver ARCHITECTURE.md para os 37 MÓDULOs canônicos + 7 Test Kinds + arquitetura de safety DOM/CPOS/PIE-PA. ADRs 0014, 0019-0025 cobrem adições pós-Freeze.
Status: receiver OTLP do Tempo habilitado (gRPC
:4317+ HTTP:4318). Os agentes browser-engine + synthetic-load têm o código do OpenTelemetry SDK embarcado (agent/src/telemetry.ts), opt-in viascripts/tracing-toggle.sh. Instrumentação das personas Caddy é follow-up pendente (requer rebuild via xcaddy com o módulocaddy-otel).
Por que tracing distribuído aqui¶
A medição central deste test bed é a latência por requisição experimentada quando um agente (browser engine ou synthetic-load engine) fala com um webserver de persona através do NGFW sob teste. Uma única requisição cruza quatro hops:
browser-engine/synthetic-load agent → NGFW (DUT, TLS leg 1) → NGFW (TLS leg 2) → Caddy persona
hop 1 hop 2 hop 3 hop 4
Sem tracing distribuído, o operador só enxerga a latência black-box end-to-end da perspectiva do agente. Uma regressão de 50 ms pode estar no NGFW, na persona Caddy ou no kernel Linux entre eles — métricas do Prometheus sozinhas não dizem qual.
Tracing distribuído expõe o breakdown por hop, que é exatamente o que appliances comerciais (Spirent CyberFlood, Ixia BreakingPoint) não expõem. Esse é um diferenciador estratégico deste projeto — e o motivo pelo qual embarcamos o código do SDK no nível do agente mesmo mantendo-o OPT-IN por padrão.
Opt-in por padrão — considerações de footprint de performance¶
Tracing distribuído está desabilitado por padrão. Os agentes rodam com seu footprint normal de memória + CPU até que o operador o habilite explicitamente.
Por que opt-in: a frota de agentes é projetada para altas contagens de agentes (browser engine 1–300, synthetic-load engine 1–1000) em hardware de laboratório que pode ter restrições de memória/CPU. Não queremos que todo operador pague o custo do SDK em toda execução de teste; queremos que ele escolha pagá-lo durante medições de baseline e execuções de deep-dive.
Footprint quando HABILITADO (medido em Ubuntu 22.04 + Node 20):
| Recurso | Por agente browser engine | Por agente synthetic-load engine |
|---|---|---|
| Memória RSS | +10–15 MB | +5–10 MB |
| CPU em estado estável | <1% | <1% |
| Latência por requisição adicionada | ~50–100 µs | ~50–100 µs |
| Overhead de latência por requisição vs baseline de 200 ms | ~0,05% | ~0,05% |
Mitigações já embutidas no overlay:
- Sampling probabilístico em 10% (OTEL_TRACES_SAMPLER_ARG=0.1). No pico da frota (300 browser engine × 1 ciclo/5 s) isso resulta em ~6 traces/s chegando ao Tempo
- @opentelemetry/instrumentation-fs desabilitado — fs é ruidoso e irrelevante
- Exporter HTTP (não gRPC) — keep-alive, sem dependências binárias extras
- Fila do BatchSpanProcessor limitada (OTEL_BSP_MAX_QUEUE_SIZE=2048) para que a memória seja previsível
- Kill-switch OTEL_SDK_DISABLED=true sempre respeitado
Como habilitar¶
Após subir o cluster em qualquer modo de deployment:
sudo ./scripts/k8s-install.sh --mode=<single|dual|tri|multi> ...
# Apply the tracing overlay on top of the running deployment.
./scripts/tracing-toggle.sh on
Os agentes pegam as novas env vars na próxima rotação de pod:
kubectl rollout restart deployment/web-agent deployment/k6-agent -n web-agents
Verifique se o SDK iniciou (procure pela linha [telemetry] OpenTelemetry SDK started):
kubectl logs -n web-agents deploy/web-agent | grep telemetry
kubectl logs -n web-agents deploy/k6-agent | grep telemetry
Abra a UI do Tempo para ver os traces:
kubectl port-forward -n web-agents svc/tempo 3200:3200
# then visit http://localhost:3200
Como desabilitar¶
Duas opções:
# (a) Kill switch via env var — survives until next overlay re-apply
kubectl set env deployment/web-agent -n web-agents OTEL_SDK_DISABLED=true
kubectl set env deployment/k6-agent -n web-agents OTEL_SDK_DISABLED=true
kubectl rollout restart deployment/web-agent deployment/k6-agent -n web-agents
# (b) Permanent — re-apply the base manifests (overlay stripped)
kubectl apply -k overlays/<your-mode>/
kubectl rollout restart deployment/web-agent deployment/k6-agent -n web-agents
Como o trace se parece¶
Quando habilitado, cada ciclo do browser engine se torna um span pai:
[span] web-agent: cycle (1.2s)
├─ [span] http: GET https://shop.persona.internal/ (340 ms)
│ ├─ [span] dns: lookup shop.persona.internal (2 ms)
│ ├─ [span] tcp: connect 10.1.1.2:443 (8 ms)
│ ├─ [span] tls: handshake (45 ms) ← agent → NGFW (TLS leg 1)
│ └─ [span] http: response (285 ms) ← NGFW → persona (TLS leg 2 + content)
├─ [span] http: GET .../static/main.css (120 ms)
└─ ... per-resource child spans
Trace IDs propagam via headers W3C padrão traceparent / tracestate. O NGFW deve preservar esses headers — a maioria dos firewalls modernos preserva; alguns paths de inspeção QUIC resetam headers, então para traces HTTP/3 use fallback para HTTP/1.1 ou rode com TLS decrypt ON para que o NGFW reconstrua a requisição.
O que NÃO está sendo traçado (ainda)¶
- Personas Caddy: o Caddy 2.7+ tem uma diretiva de tracing built-in mas o módulo
caddy-otelprecisa ser compilado na imagem via xcaddy. Agendado para um PR de follow-up. Até isso ser entregue, o trace termina na resposta HTTP do agente — você verá a requisição sair do agente e completar, mas não o breakdown do que a persona fez internamente - Spans do NGFW: vendors de NGFW tipicamente não emitem OTLP. O NGFW aparece implicitamente como tempo gasto entre o envio HTTP do agente e a resposta HTTP da persona. Para atribuir esse tempo com precisão, ou configure o mirror port do NGFW para um collector ciente de spans OU use as métricas de CPU + queue depth do SNMP exporter como proxy aproximado
Planejamento de armazenamento do Tempo¶
Com sampling de 10% e uma frota synthetic-load engine de 1000 agentes rodando 100 RPS cada: - Spans/s ingeridos: 100.000 × 0,1 ≈ 10.000 spans/s - Tamanho médio do span: ~500 B - Bytes/s: ~5 MB/s - Armazenamento para 24 h: ~430 GB
Defaults em observability/tempo/tempo.yml:
- block_retention: 24h
- max_block_bytes: 100 MiB
- Backend de armazenamento: local (PVC)
Aumente block_retention para 7d para retenção mais longa; provisione o PVC adequadamente.
Roadmap¶
| Fase | Status | O que cobre |
|---|---|---|
| Receiver OTLP do Tempo habilitado | ✅ entregue (PR-4 #179) | gRPC :4317 + HTTP :4318 |
| Código do OpenTelemetry SDK no agente | ✅ entregue (este PR) | Wrappers para browser-engine + synthetic-load |
| Helper de toggle opt-in | ✅ entregue (este PR) | scripts/tracing-toggle.sh |
| Módulo OTel da persona Caddy | ⏳ follow-up | Rebuild da imagem via xcaddy + diretiva de tracing no Caddyfile |
| Correlação de spans do NGFW | ⏳ pesquisa | Específico de vendor; potencialmente via queue-depth do SNMP como proxy |
| Dashboards orientados por trace | ⏳ follow-up | Service map auto-construído a partir de spans, metrics_generator do Tempo já cabeado |
Veja também¶
MONITORING_TEST_VALIDITY.md— contexto mais amplo de observabilidadeSYSTEM_OVERVIEW.md— referência de arquitetura- Documentação do Grafana Tempo
- Referência do OpenTelemetry SDK
agent/src/telemetry.ts— código real de inicialização do SDKscripts/tracing-toggle.sh— helper opt-in (on/off/status)