Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 84 additions & 7 deletions doc-server/docs/integrations/Webhooks/elasticsearch_webhook.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,89 @@ The `token` query parameter authenticates the sender. Treat the full URL as a se

## Step 2: Point Elasticsearch / Kibana at the URL

Create a Kibana webhook connector in Elasticsearch / Kibana and set its destination to the URL from Step 1:
Kibana has no fixed alert format: a webhook action sends exactly the body you give it. Setting this up is two parts — a connector, and an action with a JSON body on each rule.

### Create the connector

In Kibana, open **Stack Management** > **Connectors** and create a **Webhook** connector:

- **Method**: `POST`
- **Content-Type**: `application/json`
- **URL**: the NudgeBee webhook URL, token included
- **URL**: the NudgeBee webhook URL from Step 1, token included
- **Authentication**: none — the token in the URL authenticates the request
- **Header**: `Content-Type: application/json`

### Add the actions to each rule

On every rule whose alerts you want in NudgeBee, add the connector as an action twice.

**1. When the rule fires.** Set the action frequency to **For each alert**, run it on **Query matched** (or the rule type's own active action group), and paste this body:

```json
{
"rule": {
"id": "{{rule.id}}",
"name": "{{rule.name}}",
"type": ".es-query",
"url": "{{rule.url}}"
},
"alert": {
"id": "{{alert.id}}",
"uuid": "{{alert.uuid}}",
"action_group": "{{alert.actionGroup}}"
},
"status": "firing",
"severity": "high",
"title": "{{rule.name}}",
"message": "{{context.message}}",
"value": "{{context.value}}",
"conditions": "{{context.conditions}}",
"link": "{{context.link}}",
"timestamp": "{{date}}",
"tags": "{{rule.tags}}"
}
```

**2. When the rule recovers.** Add a second action on **Recovered** with the same body and `"status": "resolved"`. Without it, alerts stay open in NudgeBee.

The same body works for every rule. Only `severity` is yours to choose per rule.

| Field | Required | What NudgeBee does with it |
|-------|----------|----------------------------|
| `rule.name` | Yes | Shown as the alert's rule, and used to find the rule in NudgeBee. |
| `rule.id`, `alert.id` | Yes | Together they identify one alert. They must be identical in the firing and the recovered body, or the recovery closes nothing. |
| `alert.uuid` | No | Kibana's id for one firing of the alert: it changes each time the alert recovers and fires again. Include it so NudgeBee can tell a new firing from a repeat of the same one. Available from Kibana 8.8. |
| `status` | Yes | `firing` or `resolved`. If left out, a `recovered` action group counts as resolved. |
| `severity` | No | `critical` or `high`, `warning` or `medium`, `low`, `info`. Defaults to `low`. |
| `title`, `message`, `value`, `conditions` | No | Shown on the event. `conditions` becomes the rule's expression. |
| `link` | No | Link back to Kibana. Kept only when it is a full URL — see the note below. |
| `timestamp` | No | When the alert fired. Defaults to the time of arrival. |
| `tags` | No | The rule's tags. |
| `rule.type` | No | `.es-query` lists the rule as a log rule. Leave it out for other rule types. |
| `labels` | No | An object of extra labels, for example `{ "namespace": "prod" }`. |

:::note
Kibana only produces full URLs when `server.publicBaseUrl` is set in `kibana.yml`. Without it `{{rule.url}}` is empty and `{{context.link}}` is a path, so the event carries no link.
:::

### How the workload is found

Then attach it to the alert rules whose notifications you want in NudgeBee. Send a test notification if Elasticsearch / Kibana offers one.
`{{alert.id}}` holds the values the rule is grouped by, and NudgeBee looks each one up in the cluster inventory:

- **Grouped by pod name** — the alert is linked to the pod's workload and namespace.
- **Grouped by container or service name** — the alert is linked to the workload with that name.
- **Grouped by several fields** — every value is tried, so a rule grouped by container and pod is linked through the pod.
- **Not grouped** — there is nothing to look up. Name the workload with a label instead.

Two cases need a label:

- **The same name exists in more than one namespace.** Add `"labels": { "namespace": "<namespace>" }`, otherwise the alert is not tied to a namespace.
- **You want to name the workload yourself.** Add one of `pod`, `deployment`, `statefulset` or `daemonset` to `labels`. A label naming a workload wins over the group values.

:::note
On older server releases the rule is shown by its Kibana rule ID, and a rule grouped by several fields is not linked to a workload. Upgrade to get the behavior described here.
:::

> **Reference:** [Kibana webhook connector documentation](https://www.elastic.co/guide/en/kibana/current/webhook-action-type.html)
> **Reference:** [Kibana webhook connector](https://www.elastic.co/guide/en/kibana/current/webhook-action-type.html) · [Kibana rule action variables](https://www.elastic.co/guide/en/kibana/current/rule-action-variables.html)

---

Expand All @@ -62,14 +136,17 @@ Then attach it to the alert rules whose notifications you want in NudgeBee. Send
|---------|-------------|-----|
| No event appears | Elasticsearch / Kibana cannot reach the NudgeBee URL | Confirm the NudgeBee endpoint is reachable from Elasticsearch / Kibana's notification sender. Check egress rules on both sides. |
| `401` or `403` from the endpoint | The `token` parameter is missing or wrong | Re-copy the full URL from the integration — the token is part of the query string, and is easy to drop when pasting. |
| Event appears with no workload linked | The payload carries no identifier NudgeBee can match | Include the resource, host or service name in the alert payload so it can be matched to a workload. |
| The rule shows as an ID instead of its name | The body carries no `rule.name` | Use the body from Step 2. |
| Event appears with no workload linked | The rule is not grouped by a pod, container or service name, or the name exists in more than one namespace | Group the rule by one of those fields, or add a `namespace` or workload label as described in Step 2. |
| Duplicate events for one alert | Two notification rules point at the same URL | Consolidate them in Elasticsearch / Kibana, or use separate integrations per environment. |
| Alerts never resolve in NudgeBee | Only firing notifications are being sent | Configure Elasticsearch / Kibana to send resolution notifications to the same destination. |
| Alerts never resolve in NudgeBee | The rule has no **Recovered** action, or its body uses a different `rule.id` or `alert.id` | Add the recovered action with the same body and `"status": "resolved"`. |
| The event has no link back to Kibana | Kibana sent a path instead of a full URL | Set `server.publicBaseUrl` in `kibana.yml`. |

---

## Helpful Links

- [Webhooks overview](./index.md)
- [Kibana webhook connector documentation](https://www.elastic.co/guide/en/kibana/current/webhook-action-type.html)
- [Kibana rule action variables](https://www.elastic.co/guide/en/kibana/current/rule-action-variables.html)
- [Workflow triggers](../../features/workflow-builder/triggers.md)
Loading