Trazado distribuido — Tempo + OpenTelemetry¶
Read in your language: English · Português · Español
Estado del alcance (post-congelación de alcance 2026-05-10) — Ver ARCHITECTURE.md para los 37 MÓDULOs canónicos + 7 Test Kinds + arquitectura de safety DOM/CPOS/PIE-PA. ADRs 0014, 0019-0025 cubren adiciones post-Freeze.
Status: receiver OTLP de Tempo habilitado (gRPC
:4317+ HTTP:4318). Los agentes browser-engine + synthetic-load tienen el código del OpenTelemetry SDK embarcado (agent/src/telemetry.ts), opt-in mediantescripts/tracing-toggle.sh. La instrumentación de las personas Caddy queda como follow-up pendiente (requiere rebuild vía xcaddy con el módulocaddy-otel).
Por qué trazado distribuido aquí¶
La medición central de este test bed es la latencia por solicitud que experimenta un agente (browser engine o synthetic-load engine) al hablar con un webserver de persona a través del NGFW bajo prueba. Una sola solicitud cruza cuatro 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
Sin trazado distribuido, el operador solo ve la latencia black-box end-to-end desde la perspectiva del agente. Una regresión de 50 ms podría estar en el NGFW, en la persona Caddy o en el kernel Linux entre ellos — las métricas de Prometheus por sí solas no pueden decirle cuál.
El trazado distribuido expone el desglose por hop, que es exactamente lo que los appliances comerciales (Spirent CyberFlood, Ixia BreakingPoint) no exponen. Este es un diferenciador estratégico para este proyecto — y la razón por la que embarcamos el código del SDK a nivel de agente aunque lo mantenemos OPT-IN por defecto.
Opt-in por defecto — consideraciones de footprint de performance¶
El trazado distribuido está deshabilitado por defecto. Los agentes corren con su footprint normal de memoria + CPU hasta que el operador lo habilite explícitamente.
Por qué opt-in: la flota de agentes está diseñada para conteos altos de agentes (browser engine 1–300, synthetic-load engine 1–1000) en hardware de laboratorio que puede tener restricciones de memoria/CPU. No queremos que cada operador pague el costo del SDK en cada ejecución de prueba; queremos que elija pagarlo durante mediciones de baseline y ejecuciones de deep-dive.
Footprint cuando está HABILITADO (medido en Ubuntu 22.04 + Node 20):
| Recurso | Por agente browser engine | Por agente synthetic-load engine |
|---|---|---|
| Memoria RSS | +10–15 MB | +5–10 MB |
| CPU en estado estable | <1% | <1% |
| Latencia por solicitud agregada | ~50–100 µs | ~50–100 µs |
| Overhead de latencia por solicitud vs baseline de 200 ms | ~0,05% | ~0,05% |
Mitigaciones ya integradas en el overlay:
- Sampling probabilístico al 10% (OTEL_TRACES_SAMPLER_ARG=0.1). En el pico de la flota (300 browser engine × 1 ciclo/5 s) eso resulta en ~6 traces/s llegando a Tempo
- @opentelemetry/instrumentation-fs deshabilitado — fs es ruidoso e irrelevante
- Exporter HTTP (no gRPC) — keep-alive, sin dependencias binarias extra
- Cola del BatchSpanProcessor acotada (OTEL_BSP_MAX_QUEUE_SIZE=2048) para que la memoria sea predecible
- Kill-switch OTEL_SDK_DISABLED=true siempre respetado
Cómo habilitar¶
Después de levantar el cluster en cualquier 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
Los agentes toman las nuevas env vars en la próxima rotación de pod:
kubectl rollout restart deployment/web-agent deployment/k6-agent -n web-agents
Verifique que el SDK arrancó (busque la línea [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 la UI de Tempo para ver los traces:
kubectl port-forward -n web-agents svc/tempo 3200:3200
# then visit http://localhost:3200
Cómo deshabilitar¶
Dos opciones:
# (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
Cómo se ve el trace¶
Cuando está habilitado, cada ciclo de browser engine se convierte en un span padre:
[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
Los trace IDs se propagan vía headers estándar W3C traceparent / tracestate. El NGFW debe preservar estos headers — la mayoría de los firewalls modernos lo hacen; algunos paths de inspección QUIC resetean los headers, así que para traces HTTP/3 use fallback a HTTP/1.1 o ejecute con TLS decrypt ON para que el NGFW reconstruya la solicitud.
Qué NO se está trazando (todavía)¶
- Personas Caddy: Caddy 2.7+ tiene una directiva de tracing built-in pero el módulo
caddy-oteldebe ser compilado dentro de la imagen vía xcaddy. Programado para un PR de follow-up. Hasta que eso se entregue, el trace termina en la respuesta HTTP del agente — verá la solicitud salir del agente y completarse, pero no el desglose de lo que la persona hizo internamente - Spans del NGFW: los vendors de NGFW típicamente no emiten OTLP. El NGFW aparece implícitamente como tiempo transcurrido entre el envío HTTP del agente y la respuesta HTTP de la persona. Para atribuir ese tiempo con precisión, o configure el mirror port del NGFW hacia un collector consciente de spans O use las métricas de CPU + queue depth del SNMP exporter como proxy aproximado
Planificación de almacenamiento de Tempo¶
Con sampling al 10% y una flota synthetic-load engine de 1000 agentes corriendo 100 RPS cada uno: - Spans/s ingeridos: 100.000 × 0,1 ≈ 10.000 spans/s - Tamaño promedio del span: ~500 B - Bytes/s: ~5 MB/s - Almacenamiento para 24 h: ~430 GB
Valores por defecto en observability/tempo/tempo.yml:
- block_retention: 24h
- max_block_bytes: 100 MiB
- Backend de almacenamiento: local (PVC)
Incremente block_retention a 7d para retención más larga; provisione el PVC en consecuencia.
Roadmap¶
| Fase | Status | Qué cubre |
|---|---|---|
| Receiver OTLP de Tempo habilitado | ✅ entregado (PR-4 #179) | gRPC :4317 + HTTP :4318 |
| Código del OpenTelemetry SDK en el agente | ✅ entregado (este PR) | Wrappers para browser-engine + synthetic-load |
| Helper de toggle opt-in | ✅ entregado (este PR) | scripts/tracing-toggle.sh |
| Módulo OTel de la persona Caddy | ⏳ follow-up | Rebuild de la imagen vía xcaddy + directiva de tracing en el Caddyfile |
| Correlación de spans del NGFW | ⏳ investigación | Específico del vendor; potencialmente vía queue-depth de SNMP como proxy |
| Dashboards orientados por trace | ⏳ follow-up | Service map auto-construido a partir de spans, metrics_generator de Tempo ya cableado |
Ver también¶
MONITORING_TEST_VALIDITY.md— contexto más amplio de observabilidadSYSTEM_OVERVIEW.md— referencia de arquitectura- Documentación de Grafana Tempo
- Referencia del OpenTelemetry SDK
agent/src/telemetry.ts— código real de inicialización del SDKscripts/tracing-toggle.sh— helper opt-in (on/off/status)