Grafana Grafana

Provisiona reglas de alertas, contact points y políticas de notificación

Define todo el pipeline de alertas en YAML para que se revise y versione como código.

15 min Intermedio

El alerting de Grafana tiene cuatro piezas móviles: las reglas de alertas deciden cuándo algo va mal, los contact points dicen adónde enviar una notificación, las políticas de notificación enrutan las alertas a los contact points, y los mute timings y las plantillas dan forma a cuándo y cómo salen los mensajes. Las cuatro pueden provisionarse desde YAML en la carpeta provisioning/alerting, lo que hace que el alerting sea revisable en lugar de un montón de ajustes de interfaz. Esta guía construye un pequeño pipeline funcional.

Los recursos de alertas provisionados no pueden editarse en la interfaz, e importar un recurso que ya existe provoca un conflicto, así que elimina primero los duplicados hechos a mano. Cada archivo empieza con apiVersion: 1.

Contact points

provisioning/alerting/contact-points.yaml:

apiVersion: 1

contactPoints:
  - orgId: 1
    name: team-slack
    receivers:
      - uid: team-slack-1
        type: slack
        disableResolveMessage: false
        settings:
          url: ${SLACK_WEBHOOK_URL}
          recipient: '#alerts'

  - orgId: 1
    name: oncall-email
    receivers:
      - uid: oncall-email-1
        type: email
        settings:
          addresses: oncall@example.com

Notas:

  • uid de cada receiver debe ser único y estable. Grafana lo usa para actualizar el receiver en el mismo lugar.
  • type es la integración, como slack, email, webhook, pagerduty, opsgenie o prometheus-alertmanager. Las claves bajo settings dependen del tipo, así que consulta la documentación del tuyo.
  • Los secretos vienen de variables de entorno con $VAR o ${VAR}, así que la URL del webhook nunca vive en Git. Usa $$ para mantener un signo de dólar literal.
  • Para eliminar uno, añade deleteContactPoints con su orgId y uid.

Políticas de notificación

El árbol de políticas decide qué contact point gestiona qué alerta. Todo el árbol es un solo recurso, y provisionarlo sobrescribe todas las políticas existentes.

provisioning/alerting/policies.yaml:

apiVersion: 1

policies:
  - orgId: 1
    receiver: team-slack            # predeterminado para todo lo que no coincida abajo
    group_by: ['alertname', 'namespace']
    group_wait: 30s
    group_interval: 5m
    repeat_interval: 4h
    routes:
      - receiver: oncall-email
        object_matchers:
          - ['severity', '=', 'critical']
        repeat_interval: 1h
      - receiver: team-slack
        object_matchers:
          - ['team', '=', 'platform']
        mute_time_intervals:
          - weekends
  • receiver en el nivel superior es el contact point de reserva.
  • group_by agrupa alertas relacionadas en una sola notificación.
  • group_wait, group_interval, repeat_interval controlan la rapidez con que sale el primer mensaje, con qué frecuencia se envían actualizaciones de un grupo y con qué frecuencia se repite una alerta sin resolver.
  • routes son políticas hijas que usan los mismos campos. La primera ruta que coincide gana a menos que definas continue: true.
  • object_matchers son tríos [etiqueta, operador, valor]. Los operadores son =, !=, =~ y !~.

Para restablecer el árbol al predeterminado de Grafana, usa resetPolicies: [1] con el ID de la organización.

Mute timings

apiVersion: 1

muteTimes:
  - orgId: 1
    name: weekends
    time_intervals:
      - weekdays: ['saturday', 'sunday']
        location: 'UTC'

times (con start_time y end_time), weekdays, months, years y days_of_month pueden combinarse, y los rangos usan dos puntos, como 'monday:friday'. Elimina con deleteMuteTimes. Los mute timings no pueden usar interpolación de variables en sus nombres ni intervalos.

Plantillas de notificación

apiVersion: 1

templates:
  - orgId: 1
    name: slack_title
    template: |
      {{ define "slack_title" }}
        [{{ .Status | toUpper }}] {{ .CommonLabels.alertname }}
      {{ end }}

Haz referencia a una plantilla desde los ajustes de un contact point (por ejemplo el campo title de Slack) como {{ template "slack_title" . }}. Los nombres y el contenido de las plantillas no admiten interpolación de variables, así que escríbelos literalmente.

Reglas de alertas

Las reglas se organizan en grupos que comparten un intervalo de evaluación y viven en una carpeta. Cada regla tiene una lista de pasos de consulta y expresión, y una condition que nombra el paso que decide si se dispara.

provisioning/alerting/rules.yaml:

apiVersion: 1

groups:
  - orgId: 1
    name: webapp
    folder: Applications
    interval: 1m
    rules:
      - uid: webapp-down
        title: Webapp targets down
        condition: C
        for: 5m
        noDataState: NoData
        execErrState: Error
        labels:
          severity: critical
          team: platform
        annotations:
          summary: 'No healthy webapp targets for 5 minutes'
          runbook_url: https://runbooks.example.com/webapp-down
        data:
          - refId: A
            relativeTimeRange:
              from: 600
              to: 0
            datasourceUid: prometheus
            model:
              refId: A
              expr: sum(up{job="webapp"})
              instant: true
          - refId: B
            datasourceUid: __expr__
            model:
              refId: B
              type: reduce
              expression: A
              reducer: last
              datasource:
                type: __expr__
                uid: __expr__
          - refId: C
            datasourceUid: __expr__
            model:
              refId: C
              type: threshold
              expression: B
              conditions:
                - evaluator:
                    type: lt
                    params: [1]
              datasource:
                type: __expr__
                uid: __expr__

Cómo leerlo:

  • El paso A consulta Prometheus (por el uid del data source que provisionaste) el número de targets sanos durante los últimos diez minutos. relativeTimeRange está en segundos.
  • El paso B reduce el resultado a un único valor. Las expresiones usan el UID especial de data source __expr__.
  • El paso C es un umbral: se dispara cuando el valor es menor que 1. condition: C lo marca como el paso decisivo.
  • for: 5m exige que la condición se mantenga durante cinco minutos antes de que la alerta se dispare, lo que evita el parpadeo.
  • noDataState y execErrState indican qué hacer cuando la consulta no devuelve nada o falla: NoData, Alerting u OK para la primera, y Error, Alerting u OK para la segunda.
  • labels alimentan el árbol de políticas de notificación, así que severity: critical es lo que envió esta alerta por la ruta oncall-email de arriba.
  • uid (hasta 40 caracteres de letras, dígitos, - y _) debe ser único y estable. Opcionalmente añade dashboardUid y panelId para enlazar una regla con un panel.
  • Carpeta: usa una carpeta que exista. La forma más simple es reutilizar el título de una carpeta que crea tu proveedor de dashboards.

La interpolación de variables no funciona en las anotaciones de las reglas, relativeTimeRange, el model de las consultas ni el contenido de las plantillas, así que escribe esos valores literalmente.

Para eliminar una regla, añade deleteRules con su orgId y uid:

apiVersion: 1

deleteRules:
  - orgId: 1
    uid: webapp-down

Aplica y verifica

Los recursos de alertas se leen al arrancar, así que reinicia Grafana tras cambiar los archivos:

docker compose restart grafana

curl -s -u admin:$GRAFANA_ADMIN_PASSWORD \
  http://localhost:3000/api/v1/provisioning/alert-rules | jq '.[] | {uid, title, folderUID}'
curl -s -u admin:$GRAFANA_ADMIN_PASSWORD \
  http://localhost:3000/api/v1/provisioning/contact-points | jq '.[].name'
curl -s -u admin:$GRAFANA_ADMIN_PASSWORD \
  http://localhost:3000/api/v1/provisioning/policies | jq .receiver

Luego prueba la entrega bajando temporalmente un umbral, o enviando una notificación de prueba desde la API del contact point.

Escribe reglas más rápido

El YAML de las reglas es verboso. Construye una regla una vez en una instancia de pruebas, expórtala en formato de provisioning mediante la API de provisioning de alertas (las rutas export bajo /api/v1/provisioning/, con ?format=yaml) y haz commit del resultado con un uid estable. Para muchas reglas similares, genera el YAML a partir de una plantilla en CI, o gestiónalas con Terraform o el Grafana Operator, que ambos tienen recursos de reglas de alertas.

Guías populares