Prometheus · Arazzo Workflow

Prometheus Test an Alertmanager Routing Path

Version 1.0.0

Send a synthetic alert and follow it through to the receiver that will be paged.

1 workflow 1 source API 1 provider
View Spec View on GitHub AlertingMetricsMonitoringObservabilityTime SeriesArazzoWorkflows

Provider

prometheus

Workflows

test-alert-routing
Post a synthetic alert and confirm which receiver it routes to.
Give the synthetic alert a short endsAt so it self-resolves rather than lingering as a permanent fake incident, and label it clearly so nobody mistakes the resulting page for a real one.
5 steps inputs: alertName, alertNameMatcher, endsAt, expectedReceiver, generatorURL, severity, startsAt outputs: configuredReceivers, fingerprint, groupLabels, routedReceiver, version
1
checkAlertmanagerStatus
getStatus
Confirm the Alertmanager is up and its cluster has settled. Posting alerts at a cluster still in the settling state can produce duplicate or missing notifications that have nothing to do with the routing tree.
2
confirmReceiverExists
listReceivers
List the receivers defined in the loaded configuration. If the expected receiver is not in this list the routing tree cannot possibly select it, and the test would fail for a reason the alert itself never reveals.
3
postSyntheticAlert
postAlerts
Post the synthetic alert exactly as Prometheus would. The labels decide routing; the annotations are carried through to the notification template so the recipient can see this is a test.
4
confirmAlertAccepted
getAlerts
Read the alert back to confirm Alertmanager accepted and is now tracking it. The receivers field names every receiver it will notify.
5
confirmRouting
getAlertGroups
Read the alert groups to see the receiver the routing tree actually chose and the group labels it was grouped under. This is the answer the test exists to produce.

Source API Descriptions

Arazzo Workflow Specification

Raw ↑
arazzo: 1.0.1
info:
  title: Prometheus Test an Alertmanager Routing Path
  summary: Send a synthetic alert and follow it through to the receiver that will be paged.
  description: >-
    Routing trees are configuration, and configuration is only correct once it
    has been exercised. Rather than waiting for a real incident to discover a
    typo in a match block, this workflow checks the Alertmanager is healthy,
    confirms the intended receiver actually exists in the loaded configuration,
    posts a synthetic alert directly to the API the way Prometheus would,
    confirms it was accepted, and reads the alert groups to see which receiver
    the routing tree actually chose. Every step spells out its request inline so
    the flow can be read and executed without opening the underlying OpenAPI
    description.
  version: 1.0.0
sourceDescriptions:
- name: alertmanagerApi
  url: ../openapi/prometheus-alertmanager-api-openapi.yml
  type: openapi
workflows:
- workflowId: test-alert-routing
  summary: Post a synthetic alert and confirm which receiver it routes to.
  description: >-
    Give the synthetic alert a short endsAt so it self-resolves rather than
    lingering as a permanent fake incident, and label it clearly so nobody
    mistakes the resulting page for a real one.
  inputs:
    type: object
    required:
    - alertName
    - alertNameMatcher
    - severity
    - expectedReceiver
    - startsAt
    - endsAt
    properties:
      alertName:
        type: string
        description: >-
          The alertname for the synthetic alert (e.g. RoutingSmokeTest).
      alertNameMatcher:
        type: string
        description: >-
          The same alert as a label matcher (e.g. alertname="RoutingSmokeTest").
      severity:
        type: string
        description: >-
          The severity label to exercise a specific branch of the routing tree
          (e.g. critical).
      expectedReceiver:
        type: string
        description: >-
          The receiver name this alert is expected to route to, used to check
          the routing tree did what was intended.
      startsAt:
        type: string
        description: Alert start time as an RFC3339 timestamp.
      endsAt:
        type: string
        description: >-
          Alert end time as an RFC3339 timestamp. Keep this close so the
          synthetic alert resolves itself shortly after the test.
      generatorURL:
        type: string
        description: >-
          Optional URL linking back to whatever generated this alert, for the
          benefit of whoever receives the test page.
  steps:
  - stepId: checkAlertmanagerStatus
    description: >-
      Confirm the Alertmanager is up and its cluster has settled. Posting alerts
      at a cluster still in the settling state can produce duplicate or missing
      notifications that have nothing to do with the routing tree.
    operationId: getStatus
    successCriteria:
    - condition: $statusCode == 200
    - condition: $response.body#/cluster/status == "ready"
    outputs:
      clusterStatus: $response.body#/cluster/status
      clusterPeers: $response.body#/cluster/peers
      version: $response.body#/versionInfo/version
      uptime: $response.body#/uptime
  - stepId: confirmReceiverExists
    description: >-
      List the receivers defined in the loaded configuration. If the expected
      receiver is not in this list the routing tree cannot possibly select it,
      and the test would fail for a reason the alert itself never reveals.
    operationId: listReceivers
    successCriteria:
    - condition: $statusCode == 200
    outputs:
      receivers: $response.body
      firstReceiverName: $response.body#/0/name
  - stepId: postSyntheticAlert
    description: >-
      Post the synthetic alert exactly as Prometheus would. The labels decide
      routing; the annotations are carried through to the notification template
      so the recipient can see this is a test.
    operationId: postAlerts
    requestBody:
      contentType: application/json
      payload:
      - labels:
          alertname: $inputs.alertName
          severity: $inputs.severity
        annotations:
          summary: Synthetic alert posted to verify the Alertmanager routing tree.
          description: >-
            This alert was generated by an automated routing test and does not
            indicate a real problem. It resolves automatically.
        startsAt: $inputs.startsAt
        endsAt: $inputs.endsAt
        generatorURL: $inputs.generatorURL
    successCriteria:
    - condition: $statusCode == 200
  - stepId: confirmAlertAccepted
    description: >-
      Read the alert back to confirm Alertmanager accepted and is now tracking
      it. The receivers field names every receiver it will notify.
    operationId: getAlerts
    parameters:
    - name: filter
      in: query
      value:
      - $inputs.alertNameMatcher
    - name: active
      in: query
      value: true
    - name: silenced
      in: query
      value: true
    - name: inhibited
      in: query
      value: true
    successCriteria:
    - condition: $statusCode == 200
    outputs:
      alerts: $response.body
      fingerprint: $response.body#/0/fingerprint
      statusState: $response.body#/0/status/state
      receivers: $response.body#/0/receivers
  - stepId: confirmRouting
    description: >-
      Read the alert groups to see the receiver the routing tree actually chose
      and the group labels it was grouped under. This is the answer the test
      exists to produce.
    operationId: getAlertGroups
    parameters:
    - name: filter
      in: query
      value:
      - $inputs.alertNameMatcher
    - name: active
      in: query
      value: true
    - name: silenced
      in: query
      value: true
    - name: inhibited
      in: query
      value: true
    successCriteria:
    - condition: $statusCode == 200
    outputs:
      groups: $response.body
      routedReceiver: $response.body#/0/receiver/name
      groupLabels: $response.body#/0/groupLabels
      groupedAlerts: $response.body#/0/alerts
  outputs:
    version: $steps.checkAlertmanagerStatus.outputs.version
    configuredReceivers: $steps.confirmReceiverExists.outputs.receivers
    fingerprint: $steps.confirmAlertAccepted.outputs.fingerprint
    routedReceiver: $steps.confirmRouting.outputs.routedReceiver
    groupLabels: $steps.confirmRouting.outputs.groupLabels