Incidente: 130 targets clavados en DOWN con WS flapeando (org 1, 2026-07-17)
Resumen
A las ~16:00 UTC del 2026-07-17, en la organización 1, 130 targets de monitoreo quedaron marcados como “down” mientras la red estaba viva (87 targets realmente arriba). El WebSocket del Agente Local flapeaba (desconexiones/reconexiones frecuentes), causando que replays de métricas viejas (24h atrás, loss=100%) sobrescribieran constantemente el estado actual.
Impacto: Dashboard de monitoreo mostraba estado falso. Alertas se dispararían incorrectamente.
Duración: ~2-4 horas (hasta que WS se estabilizó).
Root cause: Guard de frescura ausente en receive_bulk_metrics().
Fix: v1.61.2 — añadido _TARGET_STATE_FRESHNESS = 120s.
Timeline
| Hora UTC | Evento |
|---|---|
| ~16:00 | WS comienza a flapear. Agente inicia reconexiones. |
| ~16:10 | Primeros replays de métricas viejas llegan. Targets en dashboard comienzan a cambiar a “down”. |
| ~17:00 | 130 targets clavados en “down”. Usuarios reportan anomalía. |
| ~17:20 | Identificado: el ingest acepta timestamps de >1h atrás sin validar. |
| ~18:04 | Fix mergeado (a1a2dcf). Deploy automático a prod. |
| ~18:15 | Estado vuelve a la normalidad. |
Observaciones técnicas
Volumen de datos:
- 12.4M métricas re-empujadas en 10 horas (por reconexiones frecuentes).
- 547k métricas producidas en el mismo período.
- Ratio: 22.7x amplificación por replays.
Comportamiento del Agente (correcto):
push_historical: re-envía 24h de histórico en cada reconexión (para VictoriaMetrics dedup).- El .exe NO tenía lógica de throttle. Cada reconexión = “replay completo”.
Comportamiento del servidor (bug):
receive_bulk_metrics()NO validaba timestamp.last_statusylast_packet_lossse escribían de CUALQUIER métrica.- Con flapping: cada replay viejo machacaba el estado actual.
Ejemplos de métricas que llegaban
timestamp: 2026-07-17 08:30:00 UTC (8h atrás)
metric_type: "ping_loss"
value: 100.0 ← Refleja un corte real de esa mañana
↓
↓ Llega a receive_bulk_metrics() a las 16:30 UTC
↓
last_status = "down" ← ¡FALSO! El equipo está vivo ahora.
last_packet_loss = 100.0 ← ¡FALSO! 0% ahora.
Impacto en VictoriaMetrics
✅ Sin problemas: VM dedup por timestamp, así que los replays se deduplican y las gráficas quedan completas. El problema era SOLO en MonitoringTarget.
Fix en v1.61.2
Guardado de frescura (_TARGET_STATE_FRESHNESS = 120s):
state_freshness_floor = now - 120
for m in payload.metrics:
if m.timestamp < state_freshness_floor:
continue # VictoriaMetrics lo recibe, MonitoringTarget NO
# ... actualizar last_status, last_check, last_packet_loss
Test: test_stale_replay_does_not_touch_live_state — verifica que un replay de 1h atrás entra a VM (accepted=2) pero NO cambia el estado del target (last_status sigue siendo “up”).
Acciones futuras
Server-side (ya cerrado)
- ✅ Guard de frescura en
receive_bulk_metrics()(v1.61.2). - ✅ Test de regresión.
Agente-side (próximo .exe, #196/#197)
- Throttle de
push_historical(no re-enviar todo cada vez). - Diagnóstico de flapping WS (alertar al usuario si la reconexión es muy frecuente).
- Log de reconexiones para auditoría.
Cómo evitar en el futuro
- Sempre validar timestamps en APIs que aceptan datos históricos.
- Separar flujos: gráficas (acepta histórico) vs estado vivo (rechaza antiguo).
- Monitoreo de ratios: si
métricas_replayed / métricas_nuevas > 5x→ alertar sobre WS inestable.
Véase también
- [[decision—20260717—target-state-freshness]]
- [[entity—terminal—endpoint—agent-metrics-bulk]]
- [[entity—monitoring—model—monitoring-target]]
- [[concept—monitoring—agent-architecture]]