Skip to content

Esquema de reglas de alerta

Las reglas de alerta se almacenan en la tabla alert_rules y se envían a POST /v1/alert-rules. Esta página es el formato wire. Fuente de verdad: internal/manager/model/alert/model.go.

Forma wire

json
{
  "rule_key": "host_cpu_high",
  "kind": "metric_raw",
  "name": "Host CPU pegged",
  "source_type": "ongrid_builtin",
  "scope_type": "host",
  "join_mode": "all",
  "severity": "warning",
  "enabled": true,
  "conditions": [
    { "expr": "node_cpu_usage_percent > 90" }
  ],
  "labels":      { "team": "sre", "service": "host" },
  "annotations": { "summary": "CPU on {{$labels.device_id}} above 90%" },
  "runbook_url": "https://wiki.example.com/runbooks/host-cpu",
  "notify_channel_ids": [12, 17],
  "notify_window_seconds": 600,
  "notify_min_fires": 3
}

Referencia de campos

Identidad

CampoTipoObligatorioDescripción
rule_keystringIdentificador estable en lower_snake usado en claves de dedupe y en incident.rule. Único.
namestringNombre para mostrar.
enabledboolno (por defecto true)Las reglas deshabilitadas son omitidas por el evaluator y ocultadas de los filtros "active".

Source / scope

CampoTipoObligatorioDescripción
source_typeenumongrid_builtin, prometheus_external. Las reglas integradas llevan valores rule_key canónicos; las reglas externas provienen de un archivo de reglas de alerta de Prometheus importado.
scope_typeenumhost, global, monitoring_pipeline. Determina la dimensión por la que el evaluator agrupa — host produce un incidente por device_id; global produce un único incidente a nivel sistema; monitoring_pipeline es para reglas internas de salud del pipeline.
join_modeenumall (todas las condiciones deben coincidir), any (cualquier condición coincide). Solo relevante cuando conditions tiene más de un elemento.

Kind

kind discrimina cómo interpreta conditions el evaluator. Cada kind dirige a un sub-evaluator distinto.

KindEstadoQué haceForma de conditions
metric_thresholdsolo entrada de UIFormulario amigable. La capa biz lo reescribe a metric_raw al guardar; nunca verás este kind en disco.[{ "metric": "cpu_pct", "operator": ">=", "threshold": 90, "window": "5m", "for": "2m", "aggregator": "avg" }]
metric_rawen vivoPromQL arbitrario. Disparado por ticker.[{ "expr": "rate(http_500[5m]) > 0.1" }]
metric_anomalyen vivoDesviación respecto a una baseline rodante (z-score). Disparado por ticker vía el PromQuerier.[{ "metric": "node_cpu_usage_percent", "window": "1h", "z_threshold": 3.0 }]
metric_forecasten vivoExtrapolación lineal (predict_linear) que cruza un umbral estático dentro de una ventana futura.[{ "metric": "node_filesystem_avail_bytes", "window": "1h", "forecast_for": "24h", "below": 1073741824 }]
metric_burn_rateen vivoMulti-ventana multi-burn-rate de presupuesto de error SLO (Google SRE Workbook).[{ "good": "sum(rate(http_2xx[1h]))", "total": "sum(rate(http_total[1h]))", "slo": 0.999, "long": "1h", "short": "5m" }]
log_matchen vivo (Phase-B)Patrón LogQL que, cuando hace match, dispara.[{ "expr": "{device_id=\"{{.device_id}}\"} |= \"panic\"" }]
log_volumeen vivo (Phase-B)Tasa de stream LogQL por encima de un umbral.[{ "expr": "sum(rate({app=\"foo\"}[5m])) > 100" }]
trace_latencyen vivo (Phase-B)TraceQL p95 / p99 por encima de un umbral para un servicio.[{ "service": "payments", "percentile": 95, "above_ms": 800, "window": "5m" }]
trace_error_rateen vivo (Phase-B)Fracción de spans con error en TraceQL por encima de un umbral.[{ "service": "payments", "above_percent": 1.0, "window": "5m" }]

El enum Go completo vive en model/alert/model.go:

go
const (
    RuleKindMetricThreshold = "metric_threshold" // UI-only input
    RuleKindMetricAnomaly   = "metric_anomaly"
    RuleKindMetricForecast  = "metric_forecast"
    RuleKindMetricBurnRate  = "metric_burn_rate"
    RuleKindMetricRaw       = "metric_raw"
    RuleKindLogMatch        = "log_match"
    RuleKindLogVolume       = "log_volume"
    RuleKindTraceLatency    = "trace_latency"
    RuleKindTraceErrorRate  = "trace_error_rate"
)

Los kinds legacy (edge_offline, prom_query, ingest_health, edge_absence, health_ingest, event_internal) son aliased silenciosamente a metric_raw al guardar.

Conditions

conditions es un array. La forma de cada elemento depende de kind — ver la tabla de arriba. join_mode decide si todos los elementos deben coincidir (all) o cualquiera (any).

Para metric_threshold (el formulario UI), cada condición es un RuleCondition:

go
type RuleCondition struct {
    Metric     string  `json:"metric"`            // e.g. "cpu_pct"
    Operator   string  `json:"operator"`          // ">", ">=", "<", "<=", "=="
    Threshold  float64 `json:"threshold"`         // numeric trigger
    Window     string  `json:"window,omitempty"`  // e.g. "5m"
    For        string  `json:"for,omitempty"`     // sustain duration
    Aggregator string  `json:"aggregator,omitempty"` // avg / max / min
}

La capa biz compila eso en una expr metric_raw al guardar usando las métricas de host canónicas de conjunto cerrado (node_cpu_usage_percent, node_memory_used_percent, node_filesystem_used_percent, node_load1, ...).

Severidad

ValorTratamiento
infose registra; las notificaciones se filtran por el match_severity_min del canal (la mayoría de canales omiten este piso)
warningpor defecto
criticalsiempre se notifica salvo que esté silenciado

El match_severity_min de un canal con valor warning acepta warning + critical; critical acepta solo critical. Vacío acepta cualquiera.

Labels y annotations

Mapas clave/valor de forma libre almacenados como JSON.

  • Las labels se anexan a las labels del incidente en el momento de fire y se usan para agrupamiento / dedupe. Comunes: service, team, env.
  • Las annotations se templatean en el momento de fire usando sintaxis de templates de Go con el snapshot del incidente — por ejemplo summary: "CPU on {{$labels.device_id}} above 90%".

Runbook

runbook_url se muestra textualmente en el detalle del incidente y en la superficie de chat junto al informe de investigación de IA. Úsalo para enlazar a tus runbooks / playbooks internos.

Atenuación de notificaciones

CampoTipoPor defectoDescripción
notify_window_secondsint0Ventana rodante para la atenuación. 0 deshabilita.
notify_min_firesint0Disparos mínimos dentro de la ventana antes de enviar notificación. 0 deshabilita.
notify_channel_idsint[]vacíoFija notificaciones a IDs de canal específicos (sujeto a los filtros propios de cada canal de enabled / severidad / scope). Vacío = router global.

Una regla que dispara menos de notify_min_fires veces dentro de los notify_window_seconds trailing escribe un evento repeat_suppressed en la línea de tiempo (para que veas que la atenuación tuvo efecto) pero no notifica. Ambos en cero = atenuación desactivada, cada disparo notifica sujeto a los gates de cooldown + silence + inhibition.

Mixto (uno cero, otro >0) es rechazado en la capa biz con invalid_argument: notify_window_seconds and notify_min_fires must both be zero or both > 0.

Ciclo de vida del incidente

Los campos de arriba describen una regla (la definición del trigger). Cuando una regla dispara produce un incidente (tabla alert_incidents) con estos estados:

text
open ─┬─> acknowledged ─> resolved
      ├─> silenced ─> resolved
      └─> resolved

Los incidentes se auto-resuelven cuando la condición subyacente se despeja durante un ciclo completo del evaluator. La máquina de estados está documentada en internal/manager/biz/alert/.

Tipos de evento

Cada transición de estado registra una fila de alert_events. Cadenas estables de tipo de evento:

Tipo de eventoCuándo
firingla regla dispara por primera vez (incidente creado o reabierto)
repeat_suppresseddisparo dentro de la ventana de cooldown / atenuación
acknowledgedel usuario hace clic en Ack
silencedel usuario silencia por N horas
resolvedcondición despejada o el usuario hizo clic en Resolve
reopenedun incidente resuelto disparó de nuevo antes de eliminarse
notecomentario añadido por el usuario
notification_sentuna entrega de canal tuvo éxito
notification_faileduna entrega de canal falló
inhibitedsuprimido por un incidente activo de mayor severidad
ai_initial_diagnosisprimera toma proactiva del investigador IA, escrita cuando el incidente dispara por primera vez

Tipos de canal

POST /v1/notification-channels acepta:

TipoValor de channel_typeOrigen
Webhookwebhookenv o UI
Slackslackenv o UI
Larksuite / Feishufeishuenv o UI
DingTalkdingtalkenv o UI
WeCom (企业微信)wecomsolo UI
Telegramtelegramsolo UI

El tipo de canal legacy log se eliminó en 2026-05 — alert_events mismo es la auditoría de entrega.

Véase también