Alert Webhook

Overview

To forward Prometheus alerts to CloudOps, configure your Alertmanager so that fired alerts are delivered to a webhook receiver pointing at the CloudOps webhook endpoint, and define an alert rule in Prometheus that the receiver picks up.

This guide is written for vanilla Prometheus 2.x+ and Alertmanager 0.27+. The CloudOps Prometheus source plugin consumes the standard Alertmanager Webhook v4 payload.

You will need:

  • CloudOps webhook URL — the endpoint that CloudOps issues when you register a Prometheus webhook source. Obtain it first by following Integrate Prometheus to CloudOps. The URL has the form https://<external-host>/integration-hub/webhooks/<webhook-id>/<token>/webhook-ingest.
  • Shell access to the host(s) running Prometheus and Alertmanager, plus permission to edit alertmanager.yml / alert.rules.yml and reload the configs.

The setup follows this order:

  1. Add a webhook receiver in Alertmanager
  2. Define an alert rule in Prometheus
  3. Test the integration
ℹ️
A receiver alone is not enough — Alertmanager only delivers to a receiver that a top-level route (or a child routes: entry) directs to. The example in step 1 pairs the new receiver with a default route.

1. Add a Webhook Receiver in Alertmanager

A receiver defines where Alertmanager sends fired alerts. For CloudOps, use the built-in webhook_configs block.

Edit alertmanager.yml

Open your Alertmanager configuration file (default path: /etc/alertmanager/alertmanager.yml) and add a new entry under receivers: plus a matching route: block.

global:
  resolve_timeout: 1m

route:
  receiver: cloudops-webhook
  group_by: [alertname]
  group_wait: 0s
  group_interval: 30s
  repeat_interval: 5m

receivers:
  - name: cloudops-webhook
    webhook_configs:
      - url: '<CLOUDOPS_WEBHOOK_URL>'
        send_resolved: true

Replace <CLOUDOPS_WEBHOOK_URL> with the Webhook URL you copied from the CloudOps console.

ℹ️
send_resolved: true forwards resolved alerts so CloudOps closes the corresponding event (event_type=RECOVERY). Set it to false only if you want to track firings only.
ℹ️

If you already have an existing default receiver, do not overwrite it. Add cloudops-webhook as an additional receivers: entry, and route to it via a child routes: block under route:, for example:

route:
  receiver: existing-default
  routes:
    - receiver: cloudops-webhook
      matchers:
        - severity =~ "critical|warning"
      continue: false

Reload Alertmanager

Apply the new config without restarting:

# Default signal handler
kill -HUP $(pidof alertmanager)

# Or, if --web.enable-lifecycle was set at start
curl -X POST http://localhost:9093/-/reload

Open Alertmanager UI (http://localhost:9093) and confirm the new receiver appears under [Status > Config].

2. Define an Alert Rule in Prometheus

Alerts originate from rule groups evaluated by Prometheus. CloudOps will only see alerts that Prometheus actually fires.

Edit alert.rules.yml

Add or extend a rule group file (example path: /etc/prometheus/alert.rules.yml):

groups:
  - name: cloudops-integration
    interval: 1m
    rules:
      - alert: CloudOpsHighErrorRate
        expr: rate(http_requests_total{status=~"5.."}[5m]) > 0.05
        for: 2m
        labels:
          severity: critical
          team: platform
        annotations:
          summary: "High 5xx error rate on {{ $labels.service }}"
          description: "5xx error rate exceeded 5% for 2 minutes"

labels become the alert’s labels in Alertmanager (used by route / routes: matching). annotations become the human-readable summary CloudOps displays.

Register the rule file in prometheus.yml

Open prometheus.yml (default: /etc/prometheus/prometheus.yml) and add the rule file path under rule_files, plus an alerting.alertmanagers block if not already present:

alerting:
  alertmanagers:
    - static_configs:
        - targets:
            - alertmanager:9093   # adjust to your Alertmanager host:port

rule_files:
  - /etc/prometheus/alert.rules.yml

Reload Prometheus

# Default signal handler
kill -HUP $(pidof prometheus)

# Or, if --web.enable-lifecycle was set at start
curl -X POST http://localhost:9090/-/reload

Open Prometheus UI (http://localhost:9090) and go to [Status > Rules] — the new rule group should be listed with state: ok.

3. Test the integration

Verify that Prometheus → Alertmanager → CloudOps wiring works before depending on production alerts.

Force a permanent firing for a quick check

Temporarily replace the expr in your rule with vector(1) — this constant always evaluates true, forcing the rule to fire on the next evaluation:

- alert: CloudOpsE2ETrigger
  expr: vector(1)
  for: 0s
  labels:
    severity: critical
  annotations:
    summary: "CloudOps webhook integration test"

Reload Prometheus and wait one evaluation cycle (default: 1 minute).

Verify on CloudOps

Open the CloudOps console and check that the test event arrived under the webhook source you registered. The Requests (24h) counter on the webhook row should increment within ~1 minute.

If it does not arrive:

  • Confirm the URL in webhook_configs.url matches the value issued by CloudOps exactly.
  • Confirm the route (or a child routes: entry) directs to the new receiver — check Alertmanager UI [Status > Config].
  • Check Alertmanager UI [Status > Alerts] for the firing alert; if absent, the rule did not fire — see Prometheus UI [Alerts].
  • Check Alertmanager logs for notify delivery errors.

Verify the RECOVERY flow (optional)

To exercise the resolved path, flip the test rule’s expr from vector(1) to vector(0) and reload Prometheus. Alertmanager will dispatch a resolved status webhook within repeat_interval, and CloudOps will record it as event_type=RECOVERY.

Restore the original expression

After verification, restore your real expr and reload Prometheus.

(Optional) Local sandbox via Docker Compose

For an isolated sandbox to try the integration end-to-end without touching your production Prometheus, the following minimal Docker Compose stack starts a fresh Prometheus + Alertmanager pair:

# docker-compose.yml
services:
  prometheus:
    image: prom/prometheus:v3.0.1
    ports: ["9090:9090"]
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
      - ./alert.rules.yml:/etc/prometheus/alert.rules.yml:ro
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
      - '--web.enable-lifecycle'
    restart: unless-stopped

  alertmanager:
    image: prom/alertmanager:v0.28.0
    ports: ["9093:9093"]
    volumes:
      - ./alertmanager.yml:/etc/alertmanager/alertmanager.yml:ro
    command:
      - '--config.file=/etc/alertmanager/alertmanager.yml'
    restart: unless-stopped

Combine with the alertmanager.yml, alert.rules.yml, and prometheus.yml snippets from sections 1 and 2 above. docker compose up -d brings the stack up at localhost:9090 (Prometheus) and localhost:9093 (Alertmanager). Tear down with docker compose down.

v1.1.0