CreaRack-SL

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 UTCEvento
~16:00WS comienza a flapear. Agente inicia reconexiones.
~16:10Primeros replays de métricas viejas llegan. Targets en dashboard comienzan a cambiar a “down”.
~17:00130 targets clavados en “down”. Usuarios reportan anomalía.
~17:20Identificado: el ingest acepta timestamps de >1h atrás sin validar.
~18:04Fix mergeado (a1a2dcf). Deploy automático a prod.
~18:15Estado 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_status y last_packet_loss se 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

  1. Sempre validar timestamps en APIs que aceptan datos históricos.
  2. Separar flujos: gráficas (acepta histórico) vs estado vivo (rechaza antiguo).
  3. 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]]