From 4e78620126ebb58d23ed1961038325d9c0790e40 Mon Sep 17 00:00:00 2001 From: mayankpande88 Date: Wed, 7 Oct 2026 19:25:44 +0530 Subject: [PATCH 1/2] docs(integrations): document the Kibana webhook body and workload matching The Elasticsearch / Kibana webhook page told readers to point a connector at the URL but never gave the JSON body a Kibana webhook action has to send. Kibana has no default body, so every reader had to guess one. The page now gives the body for the firing and the recovered action, a table of what each field does, how the rule's group values are matched to a workload, when a namespace or workload label is needed, and why a link only appears when server.publicBaseUrl is set. Signed-off-by: mayankpande88 --- .../Webhooks/elasticsearch_webhook.md | 89 +++++++++++++++++-- 1 file changed, 82 insertions(+), 7 deletions(-) diff --git a/doc-server/docs/integrations/Webhooks/elasticsearch_webhook.md b/doc-server/docs/integrations/Webhooks/elasticsearch_webhook.md index e5dea666..2618ba57 100644 --- a/doc-server/docs/integrations/Webhooks/elasticsearch_webhook.md +++ b/doc-server/docs/integrations/Webhooks/elasticsearch_webhook.md @@ -36,15 +36,87 @@ 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}}", + "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. | +| `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": "" }`, 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) --- @@ -62,9 +134,11 @@ 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`. | --- @@ -72,4 +146,5 @@ Then attach it to the alert rules whose notifications you want in NudgeBee. Send - [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) From 4e3c8541938cff73185c2483995e68dfc11eae96 Mon Sep 17 00:00:00 2001 From: Raman Kumar Date: Fri, 9 Oct 2026 12:57:12 +0530 Subject: [PATCH 2/2] docs(integrations): add alert.uuid to the Kibana webhook body Kibana's alert.uuid changes each time an alert recovers and fires again, so carrying it in the documented body gives each firing its own id. Optional, and available from Kibana 8.8. Co-Authored-By: Claude Opus 5.5 --- doc-server/docs/integrations/Webhooks/elasticsearch_webhook.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc-server/docs/integrations/Webhooks/elasticsearch_webhook.md b/doc-server/docs/integrations/Webhooks/elasticsearch_webhook.md index 2618ba57..4c5848be 100644 --- a/doc-server/docs/integrations/Webhooks/elasticsearch_webhook.md +++ b/doc-server/docs/integrations/Webhooks/elasticsearch_webhook.md @@ -63,6 +63,7 @@ On every rule whose alerts you want in NudgeBee, add the connector as an action }, "alert": { "id": "{{alert.id}}", + "uuid": "{{alert.uuid}}", "action_group": "{{alert.actionGroup}}" }, "status": "firing", @@ -85,6 +86,7 @@ The same body works for every rule. Only `severity` is yours to choose per rule. |-------|----------|----------------------------| | `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. |