Skip to main content
La página de estado es tan buena como la señal que hay detrás. B Brands no depende de un ping sintético que dice “el servidor está arriba”; deriva la salud de cada componente del tráfico real de producción y publica tres estados distintos.

El veredicto de tres estados

Cada componente (una categoría de API o una integración) se clasifica continuamente en uno de tres estados.

operational

Todo está dentro de la banda saludable.

degraded

Un cron obsoleto, una única ruta que falla, o una tasa de error de bajo nivel sostenida.

down

Un pico de errores de ventana corta que significa una caída real.

Cómo se computa el veredicto

Funcionalmente: la API cuenta constantemente las solicitudes exitosas y fallidas por componente, observa dos ventanas de tiempo, y elige el peor estado que aplique. Técnicamente, la precedencia se evalúa de arriba hacia abajo:
  1. down — tasa de error de ventana corta >= 50% sobre >= 5 solicitudes, o (para integraciones) una probe activa fallida.
  2. degraded — un cron folded obsoleto, una ruta individual que falla, o una tasa de error de ventana larga sostenida >= 1% sobre >= 5 solicitudes.
  3. operational — todo lo demás.
La histéresis previene el flapping. Una vez que un componente entra en degraded, solo regresa a operational cuando la tasa de error de ventana larga cae por debajo del umbral de recuperación (0.5%). El último veredicto se cachea en Redis (health:verdict:{component}).

Ventanas de tráfico

Los contadores viven en buckets de Redis de 5 minutos (traffic:{scope}:{ok|err}:{windowStart}, TTL ~70 min). Se leen dos rangos:

Umbrales

Todos los umbrales se exportan desde lib/endpoint/health/integration-traffic.ts, así que ajustarlos es un cambio de código de una línea revisado en un PR.

Seguimiento por ruta

recordApiTraffic registra tanto un contador de categoría como un contador por ruta. La ruta se normaliza (normalizeRoutePath) para que los segmentos dinámicos — UUIDs, ids numéricos, tokens opacos largos — colapsen a [id], lo que acota la cardinalidad. Cada clave de ruta es {METHOD}:{normalized-path}. Esto captura una única ruta que falla con fuerza (por ejemplo, una ruta rota de MaihueGO) dentro de una categoría por lo demás sana: la señal de la ruta degrada toda la categoría incluso cuando la tasa de error agregada se mantiene baja y de otro modo ocultaría el problema.

Endpoints de pull por componente

Better Stack no lee Redis ni el estado interno. Consulta un endpoint HTTP por componente:
Ambos requieren el header x-health-token, cotejado contra HEALTH_MONITOR_TOKEN:
  • 401 cuando el header no coincide.
  • 503 cuando el token no está configurado (fail closed — nunca expongas la salud sin auth).
  • 503 solo cuando el veredicto es down. Tanto operational como degraded devuelven 200; la capa amarilla se publica a través de Status Reports, nunca como downtime. El veredicto completo está siempre en el cuerpo de la respuesta.

Sincronización de degradado (Status Reports)

lib/endpoint/health/degraded-sync.ts reconcilia cada veredicto con los Status Reports publicados en Better Stack:
  • Entrar en degradedcreateDegradedReport, almacenando el id del report en health:degraded-report:{component}.
  • Salir de degradedresolveDegradedReport publica un status update resolved en el report (nunca lo elimina, de modo que la entrada de la página de estado y su espejo en Slack muestran la recuperación) y limpia el marcador.
Lee el mapa componente → id de recurso de la página de estado desde la variable de entorno JSON BETTERSTACK_STATUS_PAGE_RESOURCES. Se ejecuta desde ambos crons de salud después de computar los veredictos y es totalmente best-effort (nunca lanza). Cualquier componente que no esté presente en el mapa simplemente se omite.

Heartbeats de cron

Los heartbeats confirman que el scheduler en sí está vivo — una preocupación separada de la salud de los componentes. pingHeartbeat reintenta una vez con un breve backoff dentro de su timeout, absorbiendo los baches de red transitorios.

Métricas de infraestructura

El cron de metrics-push (/api/v3/cron/metrics/push) mide la latencia de la base de datos y de Redis para los gráficos de Infraestructura. Como una única muestra de arranque en frío producía picos falsos, el colector calienta la conexión con una probe sin cronometrar, toma tres muestras cronometradas, y reporta la mediana — manteniendo la cadencia de 5 minutos mientras suaviza los outliers puntuales.

Ruta de la señal de extremo a extremo

Código relacionado

  • Motor de veredicto y umbrales: backend/horizon-api/lib/endpoint/health/
  • Cliente de Status Report: backend/horizon-api/lib/integration/betterstack/status-report.client.ts
  • Análisis profundo: docs/initiatives/betterstack/01-architecture.md