diff --git a/explore-analyze/alerting/experimental-alerting-system/rules.md b/explore-analyze/alerting/experimental-alerting-system/rules.md new file mode 100644 index 0000000000..589ed957bf --- /dev/null +++ b/explore-analyze/alerting/experimental-alerting-system/rules.md @@ -0,0 +1,35 @@ +--- +navigation_title: Rules +applies_to: + stack: experimental 9.5+ + serverless: experimental +products: + - id: kibana +description: "Rules in Kibana's experimental alerting system define what to detect using ES|QL. Evaluation runs on a schedule and alerts, action policies, and notifications flow from rule detections." +--- + +# Rules in the {{alerting-v2-system}} [rules] + +A rule is where the {{alerting-v2-system}} starts. It points {{kib}} at the data you care about, describes what counts as a problem in {{esql}}, and says how often to check. Alerts, action policies, and notifications all flow from what a rule detects. + +This page explains what rules do, what they don't control, and how to choose a creation path. + +## What rules do [detection-and-notification] + +On each run, a rule executes an {{esql}} query against your data. Matches are recorded as rule events (`rule_event`), and handled according to the rule's mode, which can be Signal mode or Alert mode. + +In Signal mode, each matching row is stored as a signal document with no alert lifecycle or notifications. In Alert mode, the rule creates and tracks an alert episode for each match. Episodes move through lifecycle states, appear on the Alerts UI, and can trigger notifications through action policies. + +## What rules don't do + +Rules only define *what* to detect. They don't control notifications, who gets notified, or when. That's the job of action policies, which are global objects scoped to your space that match alert episodes from any rule. A rule has no say in which action policies pick it up. + +This separation means you can build and test a rule without anyone getting paged, update notification routing without touching the rule, and have multiple action policies respond to the same rule independently. + +## Next steps + +- [Create a rule](rules/create-a-rule.md): Compare creation paths and choose the one that fits your workflow. +- [Configure a rule](rules/configure-a-rule.md): Set the schedule, grouping, activation thresholds, recovery conditions, and no-data behavior. +- [View and manage rules](rules/view-manage-rules.md): Enable, disable, clone, delete, and bulk-manage rules from the rules list. +- [Review execution history](rules/review-rule-execution-history.md): Monitor rule and action policy execution outcomes across all rules in a space. +- [{{esql}} query patterns](rules/esql-query-patterns.md): Browse query patterns ordered by complexity, from a basic event filter to SLO burn rate and persistent breach detection. \ No newline at end of file diff --git a/explore-analyze/alerting/experimental-alerting-system/rules/configure-a-rule.md b/explore-analyze/alerting/experimental-alerting-system/rules/configure-a-rule.md new file mode 100644 index 0000000000..087f7472c2 --- /dev/null +++ b/explore-analyze/alerting/experimental-alerting-system/rules/configure-a-rule.md @@ -0,0 +1,24 @@ +--- +navigation_title: Configure a rule +applies_to: + stack: experimental 9.5+ + serverless: experimental +products: + - id: kibana +description: "Overview of all configurable rule settings in the experimental alerting system. Required settings are mode, ES|QL query, and schedule. Optional settings include severity, grouping, activation and recovery thresholds, no-data handling, and tags." +--- + +# Configure a rule in the {{alerting-v2-system}} [rule-settings] + +Rules in the {{alerting-v2-system}} have three required settings and several optional ones. Start with the required settings in order. Only add optional settings once the detection logic is validated. The following table links to a dedicated page for each setting with field descriptions, accepted values, and guidance on when to configure it. + +| Setting | Description | Required | +| --- | --- | --- | +| [Rule mode](configure-rule-mode.md) | Can be Signal or Alert. Controls whether matching rows generate signal documents or tracked alert episodes. | Required | +| [{{esql}} query](configure-rule-query.md) | The detection logic and the parameters available in query expressions. | Required | +| [Schedule and lookback](configure-rule-schedule.md) | How often the rule evaluates and how far back the query looks. | Required | +| [Severity](configure-rule-severity.md) | Assign severity levels to alert episodes using a `severity` column in query output. | Optional | +| [Grouping](configure-rule-grouping.md) | Track multiple subjects (hosts, services, users) as independent alert series in one rule. | Optional | +| [Activation and recovery thresholds](configure-rule-thresholds.md) | Reduce noise with delay modes for opening and closing alert episodes. Alert mode only. | Optional | +| [No-data handling](configure-no-data-handling.md) | What the rule records when the base query returns no results. | Optional | +| [Tags and runbooks](configure-rule-tags.md) | Free-form labels and investigation guides attached to the rule. Alert mode only. | Optional | diff --git a/explore-analyze/alerting/experimental-alerting-system/rules/configure-no-data-handling.md b/explore-analyze/alerting/experimental-alerting-system/rules/configure-no-data-handling.md new file mode 100644 index 0000000000..e2d3231928 --- /dev/null +++ b/explore-analyze/alerting/experimental-alerting-system/rules/configure-no-data-handling.md @@ -0,0 +1,55 @@ +--- +navigation_title: No-data handling +applies_to: + stack: experimental 9.5+ + serverless: experimental +products: + - id: kibana +description: "How to configure the no-data strategy for rules in the experimental alerting system. Controls whether an empty query result emits a no-data event, holds the last known alert state, triggers recovery, or is ignored." +--- + +# No-data handling in the {{alerting-v2-system}} [no-data-handling] + +No-data handling is an optional setting for rules in the {{alerting-v2-system}}. Use `no_data_strategy` to control what the rule records when the base query returns no results. Setting this correctly prevents false recoveries and misleading `no_data` events when data sources stop reporting. + +## No-data strategy options [no-data-strategy-options] + +The `no_data_strategy` field accepts the following values. + +| Value | Description | +| --- | --- | +| `emit` | Record a no-data event. | +| `last_known_status` | Hold the last known lifecycle state. An active breach stays active and a recovered episode stays recovered. | +| `recover` | Treat absence as recovery. | +| `none` | Turn off no-data detection | + +:::{note} +`no_data_strategy` only applies when the base query returns **no rows at all**. If one host or data source goes silent while others continue reporting, the query still returns results for the active sources and `no_data_strategy` does not trigger. Refer to [No-data detection](esql-no-data-detection.md) for an {{esql}} pattern that surfaces individual silent sources as alert rows. +::: + +## When to configure no-data handling [no-data-when-to-use] + +Configure `no_data_strategy` when: + +* The data source your rule monitors can go silent. Examples include a metrics agent that stops reporting, a pipeline that breaks, or a service that stops generating events. +* A false recovery caused by an empty query result would be more harmful than holding the current alert state. +* Absence of data is itself a signal worth surfacing, such as missing heartbeat events from a critical service. + +Leave `no_data_strategy` unconfigured (or set to `none`) when: + +* Your data source reliably produces output on every evaluation and a gap in data would indicate a genuine recovery. +* You are still tuning the rule and don't yet know how it behaves when data is absent. Set the strategy once the rule's normal behavior is understood. + +## Examples + +### Maintain alert state during a metrics collection outage + +This rule monitors infrastructure CPU. If the metrics collection agent stops sending data, you don't want an active CPU breach to auto-recover because the query returned nothing. Set `no_data_strategy` to `last_known_status`. The rule holds the alert in its current state until data resumes. + +Use this when an empty query result most likely means a pipeline problem rather than a genuine recovery. + +### Surface a broken data pipeline as an alert + +This rule monitors for login events from an identity provider. If no events appear in the lookback window, it's unusual enough to warrant attention. Either the pipeline is broken or something has suppressed activity. Set `no_data_strategy` to `emit`. The absence is recorded as a `no_data` event in `.rule-events`, making it visible alongside other rule activity. + +Use this when receiving no data is itself a signal worth investigating. diff --git a/explore-analyze/alerting/experimental-alerting-system/rules/configure-rule-grouping.md b/explore-analyze/alerting/experimental-alerting-system/rules/configure-rule-grouping.md new file mode 100644 index 0000000000..5132240cd4 --- /dev/null +++ b/explore-analyze/alerting/experimental-alerting-system/rules/configure-rule-grouping.md @@ -0,0 +1,68 @@ +--- +navigation_title: Grouping +applies_to: + stack: experimental 9.5+ + serverless: experimental +products: + - id: kibana +description: "Configure rule grouping in Kibana's experimental alerting system to track multiple subjects as independent alert series." +--- + +# Rule grouping in the {{alerting-v2-system}} [rule-grouping] + +Rule grouping is an optional setting in the {{alerting-v2-system}} that lets a single rule track multiple things independently. For example, a rule monitoring CPU usage across hosts can produce a separate alert series for each host, rather than one alert for everything combined. + +In Alert mode, each group becomes its own alert episode with an independent lifecycle. One group can be active while another has recovered, and notifications apply per episode, not across all groups combined. Snooze state is also per series. Snoozing one group does not affect other groups tracked by the same rule. + +## When to configure grouping [grouping-when-to-use] + +Configure grouping when: + +* Your {{esql}} query uses a `BY` clause to aggregate across multiple subjects such as hosts, services, or users, and you want each subject to have an independent alert lifecycle. +* You need to track that one host has recovered while another is still breaching, rather than treating all subjects as a single combined series. +* You want action policy notifications to apply per subject rather than firing once for the entire rule. + +Skip grouping when: + +* Your query does not use a `BY` clause. Grouping requires `BY` columns in the query output to be meaningful. +* You intentionally want a single alert series for the rule regardless of how many subjects match. An example is a rule that fires when any host in a cluster is down and the individual host identity doesn't matter for the notification. + +Rule grouping controls how alert series are created. Notification grouping, configured on an action policy, controls how those alert episodes are batched into messages. These are separate settings. + +## Configure grouping fields [grouping-fields-config] + +The {{alerting-v2-system}} does not automatically infer grouping from your {{esql}} query. When your query uses `BY` to produce one row per group, the system still treats all rows as a single series unless you explicitly declare which fields define series identity in the grouping configuration. The fields you declare in `grouping.fields` are what the system uses to separate rows into independent alert series and track each one through its own lifecycle. + +The fields you declare in `grouping.fields` must match the column names produced by the `BY` clause in your {{esql}} `STATS` command. If they don't match, the system can't correlate query rows to alert series and the grouping configuration has no effect. + +:::{tip} +Write the query first, then set the group fields. That way the `BY` columns are already defined and you can select them directly. If you later add or remove a `BY` field in the query, update the group fields to match. +::: + +## Examples + +### Track error rates per service + +This rule counts HTTP errors per service and opens a separate alert series for each service that exceeds the threshold. Each service gets its own lifecycle. If the checkout service recovers but the payments service stays critical, those are tracked independently. + +```esql +FROM logs-* +| WHERE @timestamp >= ?_tstart AND @timestamp < ?_tend +| STATS error_count = COUNT_IF(http.response.status_code >= 500) BY service.name // Group field: one series per service +| WHERE error_count > 10 +| KEEP service.name, error_count +``` + +Without a matching `grouping.fields` entry, the rule treats all services as a single combined series. A spike in one service would activate the alert for everything, and recovery requires all services to drop below the threshold at the same time. + +### Track CPU usage per host and region + +When the query groups by multiple fields, include all fields in `grouping.fields` to create one alert series per unique combination. + +```esql +FROM metrics-* +| WHERE @timestamp >= ?_tstart AND @timestamp < ?_tend +| STATS avg_cpu = AVG(system.cpu.total.pct) BY host.name, cloud.region // Group fields: one series per host+region pair +| WHERE avg_cpu > 0.90 +| KEEP host.name, cloud.region, avg_cpu +``` diff --git a/explore-analyze/alerting/experimental-alerting-system/rules/configure-rule-mode.md b/explore-analyze/alerting/experimental-alerting-system/rules/configure-rule-mode.md new file mode 100644 index 0000000000..b90c8e50d8 --- /dev/null +++ b/explore-analyze/alerting/experimental-alerting-system/rules/configure-rule-mode.md @@ -0,0 +1,50 @@ +--- +navigation_title: Rule mode +applies_to: + stack: experimental 9.5+ + serverless: experimental +products: + - id: kibana +description: "How rule mode determines whether detections produce signal documents or tracked alert episodes in the experimental alerting system, and when to use each." +--- + +# Rule mode in the {{alerting-v2-system}} [rule-mode] + +Rule mode is a required setting for rules in the {{alerting-v2-system}}. It determines what the rule produces when the detection query finds a match. Rule mode is set by the rule creation method. Some [creation paths](create-a-rule.md) only support one mode. + +| Mode | Behavior | +| --- | --- | +| Signal | Records each matching row as a signal document. No alert episodes, no notifications. | +| Alert | Creates an alert episode for each matching row. Episodes are tracked through lifecycle states, appear on the Alerts UI, and can be routed to notifications by action policies. | + +## When to use each rule mode [rule-mode-when-to-use] + +Signal mode is the right fit when: + +* You are writing a new detection query and want to verify it produces the expected matches before notifying anyone. +* You need to build detection history in `.rule-events` without generating alert noise or triggering notifications. + +Signal mode is **not** the right fit when: + +* You need to track how long a condition has been active or how it transitions between states. Signal mode does not create episodes or lifecycle state. +* You need notifications when a condition fires. Switch to Alert mode and attach an action policy. + +Alert mode is the right fit when: + +* The rule is production-ready and each breach should be tracked as a distinct alert episode that opens, can escalate, and closes when the condition clears. +* Alert episodes from the rule should be available for be triage, acknowledgment, or escalation. +* You want to attach action policies to route notifications when alert episodes open, escalate, or recover. + +Alert mode is **not** the right fit when: + +* The rule's query is still being tuned and generating alerts would create noise for on-call teams. Use Signal mode to validate first, then switch. + +## Examples + +### Build detection history before enabling alerts + +You're writing a new detection query and want to verify it produces the results you expect before anyone gets paged. Create the rule in Signal mode so matches are recorded in `.rule-events` and you can inspect them in Discover without opening any alert episodes or triggering notifications. Once the matches look correct, edit the rule and switch it to Alert mode. + +### Route critical episodes to an on-call workflow + +You have a checkout service error rate rule and want on-call engineers notified when it fires. Create the rule in Alert mode so each breach opens a tracked episode that action policies can route to a notification channel. The rule's episodes appear on the Alerts UI and are visible to any action policy whose KQL matcher matches the episode fields. diff --git a/explore-analyze/alerting/experimental-alerting-system/rules/configure-rule-query.md b/explore-analyze/alerting/experimental-alerting-system/rules/configure-rule-query.md new file mode 100644 index 0000000000..c466920586 --- /dev/null +++ b/explore-analyze/alerting/experimental-alerting-system/rules/configure-rule-query.md @@ -0,0 +1,108 @@ +--- +navigation_title: ES|QL query +applies_to: + stack: experimental 9.5+ + serverless: experimental +products: + - id: kibana +description: "How to structure the ES|QL detection query for a rule in the experimental alerting system. Covers the base query, the optional alert condition that gates which rows become breaches, and dynamic parameters for time bounds and configurable thresholds." +--- + +# {{esql}} query in the {{alerting-v2-system}} [esql-query-rule] + +Every rule in the {{alerting-v2-system}} uses an {{esql}} query to define what to evaluate. The query consists of a base query that shapes and filters the data and an optional alert condition that determines which rows become alert events. For more advanced use cases, the query also supports [dynamic values](#dynamic-query-values) for filtering by the evaluation window or setting configurable thresholds through the rule form. + +## Base query [query-base] + +The base query is the main {{esql}} expression. Use `FROM` to point the rule at the indices or data streams to read. Shape results with `STATS`, `WHERE`, and `EVAL`, and control which fields are stored with `KEEP`. The base query runs on every evaluation, even when no match occurs, which is what enables no-data detection and recovery. The [{{esql}} reference](elasticsearch://reference/query-languages/esql.md) covers all available commands and processing functions. + +This query counts HTTP 5xx errors per service over the lookback window and stores only the fields needed for triage. + +```esql +FROM logs-* +| WHERE @timestamp >= ?_tstart AND @timestamp < ?_tend +| STATS error_count = COUNT_IF(http.response.status_code >= 500) BY service.name +| KEEP service.name, error_count +``` + +Without an alert condition, every row returned by this query is treated as a breach, so the rule fires for every service that logged at least one 5xx error. + +## Alert condition [query-alert-condition] + +The alert condition is an optional `WHERE` clause appended after the base query. Only rows that pass the condition are treated as breaches. Use an alert condition when the base query returns aggregate results and you only want to alert when a value crosses a threshold. + +This example extends the base query above to only fire when a service exceeds 10 errors. + +```esql +FROM logs-* +| WHERE @timestamp >= ?_tstart AND @timestamp < ?_tend +| STATS error_count = COUNT_IF(http.response.status_code >= 500) BY service.name +| KEEP service.name, error_count +// Alert condition: only services with more than 10 errors become breaches +| WHERE error_count > 10 +``` + +The `KEEP` command controls which fields appear on each stored alert event. Only the fields in `KEEP` are available for action policy matchers, grouping keys, and triage. + +## When to add an alert condition [query-when-to-use] + +Add an alert condition when: + +* Your base query returns aggregate results (for example, counts or averages per group) and you only want to alert when a value crosses a specific threshold. Without an alert condition, every row returned by the base query is treated as a breach. +* You want to keep filtering logic out of the base query and express the threshold separately for clarity. + +Skip the alert condition when: + +* Every row returned by the base query should be treated as a breach. This applies when the query filters directly for specific error events where any match warrants attention. +* All filtering can be expressed cleanly in a single `WHERE` clause without a two-stage query. + +## Use dynamic values in your rule query [dynamic-query-values] + +{{esql}} rule queries support two kinds of parameters that make queries more dynamic. The executor injects time bounds automatically, and you define form variables when creating a rule. You don't need either to write a working rule, but they're useful for scoping queries precisely to the evaluation window or making thresholds configurable without editing the query. + +### Filter your query to the evaluation window (`?_tstart` and `?_tend`) [time-bound-parameters] + +`?_tstart` and `?_tend` are reserved parameter names that the rule executor binds automatically on every evaluation. They hold the start and end timestamps of the lookback window, so you can scope a query to exactly the period the rule is evaluating. + +```esql +FROM logs-* +| WHERE @timestamp >= ?_tstart AND @timestamp < ?_tend +| STATS error_count = COUNT(*) BY service.name +| WHERE error_count > 10 +``` + +These parameters work across all rule creation methods. + +### Set configurable values in the rule form (`?param`) [form-variables] + +When creating a rule through the form, you can use `?param` placeholders, such as `?threshold`, as {{esql}} Control variables. The form resolves these variables and embeds their values into the query before saving. The stored rule and the YAML representation of it contains the resolved values, not the placeholder tokens. + +## Examples + +### Scoping a query to the evaluation window + +This query counts HTTP errors per service over the rule's lookback window. `?_tstart` and `?_tend` are bound automatically at runtime, so the query always covers exactly the configured window regardless of when the rule runs. + +```esql +FROM logs-* +| WHERE @timestamp >= ?_tstart AND @timestamp < ?_tend +| STATS error_count = COUNT_IF(http.response.status_code >= 500) BY service.name +| WHERE error_count > 0 +| KEEP service.name, error_count +``` + +If you omit the time filter, the query scans the full index on every evaluation, which increases query cost and can return stale matches from earlier runs. + +### Using a form variable for a configurable threshold + +This query uses `?threshold` as a form variable so the threshold can be set in the rule form UI without editing the query directly. When the rule is saved, the form resolves `?threshold` to its configured value and embeds it. The stored query contains the literal number, not the placeholder. + +```esql +FROM logs-* +| WHERE @timestamp >= ?_tstart AND @timestamp < ?_tend +| STATS p99_latency = PERCENTILE(http.response_time, 99) BY service.name +| WHERE p99_latency > ?threshold +| KEEP service.name, p99_latency +``` + +Because `?threshold` is resolved before saving, YAML and API representations of this rule always show the resolved value. diff --git a/explore-analyze/alerting/experimental-alerting-system/rules/configure-rule-schedule.md b/explore-analyze/alerting/experimental-alerting-system/rules/configure-rule-schedule.md new file mode 100644 index 0000000000..d45abee80c --- /dev/null +++ b/explore-analyze/alerting/experimental-alerting-system/rules/configure-rule-schedule.md @@ -0,0 +1,78 @@ +--- +navigation_title: Schedule and lookback +applies_to: + stack: experimental 9.5+ + serverless: experimental +products: + - id: kibana +description: "How the execution interval and lookback window control when a rule evaluates and how much data it covers each time in the experimental alerting system." +--- + +# Schedule and lookback in the {{alerting-v2-system}} [schedule-lookback] + +Schedule and lookback are required settings for rules in the {{alerting-v2-system}}. They control how often a rule runs and how far back it looks when evaluating data. This page describes both fields, lists the accepted values and bounds, and includes guidance on choosing appropriate values for different monitoring scenarios. + +Both fields accept duration strings such as `30s`, `5m`, `2h`, or `7d`. Refer to [Duration format](yaml-rule-schema-reference.md#duration-format) for supported units. + +## When to use a short or long interval and lookback [schedule-when-to-use] + +Use a short execution interval (seconds to a few minutes) when: + +* The condition being monitored can develop quickly and fast detection is critical. Examples include a burst of failed authentication attempts or a spike in HTTP error rate. +* Notification latency matters and you need the rule to fire close to when the breach occurs. + +Use a longer execution interval (tens of minutes or more) when: + +* The condition develops slowly and near-real-time detection isn't required. Examples include disk utilization for capacity planning or a weekly job failure check. +* You want to reduce evaluation cost. Longer intervals lower the frequency of query execution against your data. + +Use a short lookback window when: + +* Your data arrives reliably and with low latency, and you want to avoid re-scanning data that older evaluations already covered. +* You are running high-frequency rules where a narrow window keeps each evaluation focused on recent data. + +Use a longer lookback window when: + +* The condition you're detecting can develop across multiple events spread over time, and a narrow window might miss the full picture. +* You are setting up a new rule and want to verify the query covers the expected data before tightening the window. +* Ingestion lag means events arrive later than their timestamps, and a wider window ensures late-arriving data is still evaluated. + +Avoid setting the lookback shorter than the execution interval. If the lookback doesn't cover the full gap between evaluations, events that arrive between runs can be missed. + +## Execution interval [schedule-execution-interval] + +The execution interval (`schedule.every`) determines how frequently the rule evaluates. The minimum is `5s` and the maximum is `365d`. Values outside that range are rejected. + +## Lookback window [schedule-lookback-window] + +The lookback window (`schedule.lookback`) determines the time range that the {{esql}} query covers. The minimum is `5s` and the maximum is `365d`. + +If the lookback is shorter than the execution interval, evaluations can miss data between runs. Use a lookback at least as long as the execution interval unless you have a deliberate reason not to. + +## Examples [schedule-examples] + +### High-frequency security rule + +This rule detects a burst of failed login attempts. Because the threat can develop quickly and needs fast detection, the interval is set to **1 minute** and the lookback to **5 minutes**. The 5-minute lookback is five times the interval, so a burst that straddles two evaluation windows is never missed. + +```esql +FROM logs-* +| WHERE @timestamp >= ?_tstart AND @timestamp < ?_tend // Covers the 5-minute lookback on each evaluation +| STATS failed_logins = COUNT_IF(event.outcome == "failure") BY user.name +| WHERE failed_logins > 10 +| KEEP user.name, failed_logins +``` + +The `?_tstart` and `?_tend` parameters are automatically bound to the lookback window, so the query always covers exactly the configured 5-minute range. + +### Cost-optimized infrastructure rule + +This rule monitors disk utilization for capacity planning. Fast response isn't critical, so the interval is set to **15 minutes** and the lookback to **30 minutes**. The wider window smooths out brief spikes that don't indicate a real capacity problem, reducing evaluation cost without sacrificing coverage. + +```esql +FROM metrics-* +| WHERE @timestamp >= ?_tstart AND @timestamp < ?_tend // Covers the 30-minute lookback on each evaluation +| STATS max_disk_pct = MAX(system.filesystem.used.pct) BY host.name, system.filesystem.mount_point +| WHERE max_disk_pct > 0.90 +| KEEP host.name, system.filesystem.mount_point, max_disk_pct +``` diff --git a/explore-analyze/alerting/experimental-alerting-system/rules/configure-rule-severity.md b/explore-analyze/alerting/experimental-alerting-system/rules/configure-rule-severity.md new file mode 100644 index 0000000000..66de8fe832 --- /dev/null +++ b/explore-analyze/alerting/experimental-alerting-system/rules/configure-rule-severity.md @@ -0,0 +1,93 @@ +--- +navigation_title: Severity +applies_to: + stack: experimental 9.5+ + serverless: experimental +products: + - id: kibana +description: "Assign severity levels to alert episodes in Kibana's experimental alerting system using a severity column in ES|QL query output." +--- + +# Severity in the {{alerting-v2-system}} [rule-severity] + +Severity is an optional setting for rules in the {{alerting-v2-system}}. To set it, include a column named `severity` in your {{esql}} query output and add it to your `KEEP` list. The framework reads that column after each evaluation and maps it to one of five fixed levels. + +| Value | Description | Urgency | +| --- | --- | --- | +| `info` | Informational event worth recording. | No action required. | +| `low` | Minor condition that might need monitoring. | Review when convenient. | +| `medium` | Notable condition that warrants investigation. | Investigate soon. | +| `high` | Serious condition requiring prompt attention. | Address promptly. | +| `critical` | Severe condition requiring immediate action. | Act immediately. | + +## When to configure severity [severity-when-to-use] + +Configure severity when: + +* You want to route different urgency levels to different notification channels, for example, send `critical` episodes to an on-call channel and `low` episodes to a review queue. +* You want to filter the Alerts UI by urgency to help triage during incidents. +* The rule's detection logic can meaningfully distinguish between urgency levels through a computed metric, such as burn rate, error count, or latency percentile. + +Skip severity when: + +* All breaches from the rule are equally urgent. A fixed label in the rule's tags is simpler and doesn't require query changes. +* The underlying data doesn't produce a reliable metric to grade urgency. Severity that's frequently wrong generates more noise than routing by severity resolves. + +## Severity behavior and usage [severity-behavior] + +Keep the following in mind when configuring severity. + +- **Matching is case-insensitive** - `critical`, `Critical`, and `CRITICAL` are all treated the same. You can use any casing in your `EVAL` expression. +- **Unrecognized values are silently ignored** - If the `severity` column contains a value that doesn't match one of the five levels, the alert episode is still created but `severity` is not set. If severity isn't appearing as expected, check the exact string your query is producing. +- **Severity only applies to breached events** - `recovered` and `no_data` events don't carry a severity value. Action policy matchers that filter by severity only match open episodes. + + + +## Examples + +### Static severity for a fixed threshold rule + +If every breach of a rule is equally urgent, assign a fixed severity rather than computing it dynamically. The `EVAL` command adds a constant `severity` column to every row the query returns. + +```esql +FROM logs-* +| WHERE @timestamp >= ?_tstart AND @timestamp < ?_tend +| STATS error_count = COUNT_IF(http.response.status_code >= 500) BY service.name +| WHERE error_count > 100 +| EVAL severity = "critical" +| KEEP service.name, error_count, severity +``` + +Every breach from this rule produces a `critical` episode. Use this when the threshold itself represents a critical condition and intermediate severity levels don't apply. + +### Dynamic severity based on burn rate + +Use `CASE` to map a computed metric to different severity levels. This query grades each service's error rate. Services consuming error budget at 14.4× baseline or above are `critical`, those between 6× and 14.4× are `high`, and so on. Only services above 1× are returned, so below-threshold services don't generate alert rows. + +```esql +FROM metrics-* +| WHERE @timestamp >= ?_tstart AND @timestamp < ?_tend // Bind to the rule's configured lookback window +| STATS + errors = COUNT_IF(outcome == "failure"), + total = COUNT(*) + BY service.name +| EVAL burn_rate = errors / total +| EVAL severity = CASE( + burn_rate > 14.4, "critical", + burn_rate > 6.0, "high", + burn_rate > 1.0, "medium", + "low" + ) +| WHERE burn_rate > 1.0 +| KEEP service.name, burn_rate, severity +``` + +- **`WHERE`** (time filter): Scopes the query to the rule's configured lookback window using the reserved `?_tstart` and `?_tend` parameters. +- **`STATS`**: Counts failures and total requests, grouped by service. +- **`EVAL burn_rate`**: Computes the error rate as a fraction of failures to total requests. +- **`EVAL severity`**: Maps the burn rate to a severity level. +- **`WHERE burn_rate`**: Only services above the minimum threshold count as breaches. +- **`KEEP`**: Includes `severity` in the output so the {{alerting-v2-system}} reads and stores it. diff --git a/explore-analyze/alerting/experimental-alerting-system/rules/configure-rule-tags.md b/explore-analyze/alerting/experimental-alerting-system/rules/configure-rule-tags.md new file mode 100644 index 0000000000..2b1e531666 --- /dev/null +++ b/explore-analyze/alerting/experimental-alerting-system/rules/configure-rule-tags.md @@ -0,0 +1,60 @@ +--- +navigation_title: Tags and runbooks (Alert mode only) +applies_to: + stack: experimental 9.5+ + serverless: experimental +products: + - id: kibana +description: "Add tags and runbooks to Alert-mode rules in Kibana's experimental alerting system for filtering and investigation context." +--- + +# Tags and runbooks in the {{alerting-v2-system}} (Alert mode only) [tags-investigation] + +Tags and runbooks are optional artifacts for Alert-mode rules in the {{alerting-v2-system}}. + +- **Tags**: Free-form labels for filtering and organization. Maximum 20 tags per rule. Each tag can be up to 128 characters. +- **Runbooks**: An investigation guide stored with the rule so responders have context when alerts are generated. + +## When to configure tags and runbooks [tags-when-to-use] + +Configure tags when: + +* You want to filter the Alerts UI by team, environment, or severity tier without writing ad hoc KQL queries each time. +* You are using action policies and want to match episodes by ownership or category rather than by rule name. Tags are inherited by alert episodes, so any tag you add to a rule is available as a KQL matcher in action policies. +* You manage many rules and need a consistent labeling scheme to track which team owns which alerts. + +Configure a runbook when: + +* Responders who aren't familiar with the service might need to triage the alert. A runbook surfaces triage steps directly alongside the alert without requiring a separate search. +* The alert requires a consistent response process that you want encoded and version-controlled alongside the rule. + +Skip tags and runbooks when: + +* The rule is in Signal mode. Tags and runbooks are Alert-mode-only artifacts and have no effect on signal document output. +* The rule is experimental or not yet part of a monitored production system. + +## Examples + +### Tag a rule for team ownership and severity + +Tags let you filter alerts by team, environment, or severity tier. For a checkout service rule, you might add tags like: + +- `team:payments` +- `env:production` +- `sev:p1` + +On-call engineers can then narrow the alerts view to rules their team owns without scanning every active episode. + +### Add a runbook with triage steps + +A runbook gives responders immediate context when an alert fires. Write it as plain text in the rule's description field. Include enough detail that an engineer unfamiliar with the service can triage without asking for help. + +``` +Fires when checkout error rate exceeds 10% for 3 consecutive evaluations. + +Triage steps: +1. Check the checkout service deployment history in the last 30 minutes. +2. Review the error breakdown dashboard: https://kibana.example.com/dashboards/checkout-errors +3. If errors are concentrated in one region, escalate to the infra team. +4. If errors are global, page the payments on-call lead. +``` diff --git a/explore-analyze/alerting/experimental-alerting-system/rules/configure-rule-thresholds.md b/explore-analyze/alerting/experimental-alerting-system/rules/configure-rule-thresholds.md new file mode 100644 index 0000000000..de826d29b1 --- /dev/null +++ b/explore-analyze/alerting/experimental-alerting-system/rules/configure-rule-thresholds.md @@ -0,0 +1,84 @@ +--- +navigation_title: Activation and recovery thresholds (Alert mode only) +applies_to: + stack: experimental 9.5+ + serverless: experimental +products: + - id: kibana +description: "Configure activation and recovery thresholds for Alert-mode rules in Kibana's experimental alerting system to reduce noise from brief spikes and rapid state changes." +--- + +# Activation and recovery thresholds in the {{alerting-v2-system}} (Alert mode only) [activation-recovery-thresholds] + +Activation and recovery thresholds are optional settings for Alert-mode rules in the {{alerting-v2-system}}. They control when alerts transition between lifecycle states, reducing noise from brief spikes and rules that alternate rapidly between breaching and recovering. + +## When to configure thresholds [thresholds-when-to-use] + +Configure activation and recovery thresholds when: + +* The metric being monitored fluctuates and a single breach or recovery doesn't reflect a real state change. Examples include CPU usage that briefly spikes during process startup or a connection pool that crosses the threshold on alternating evaluations. +* You want to reduce notification noise from rules that alternate rapidly between breaching and recovering on consecutive evaluations. +* The cost or urgency of a notification is high enough that you need confidence the condition is sustained before alerting on it. + +Skip activation and recovery thresholds when: + +* Any single breach warrants immediate attention and you cannot tolerate the added latency of waiting for consecutive evaluations. Leave the activation mode set to Immediate. +* The rule is in Signal mode. Thresholds only apply to Alert-mode rules and have no effect on signal document output. + +## Activation thresholds + +Activation thresholds control when a breached rule transitions from pending to active. Three delay modes are available: + +| Mode | Behavior | When to use | +| --- | --- | --- | +| Immediate | Opens an alert episode as soon as the threshold is breached on the first evaluation. | Use when any single breach warrants attention and latency matters. | +| Breaches | Opens an alert episode after the threshold is breached a set number of times in a row. | Use when a single breach isn't enough reason to act, for example when brief spikes are normal and you only care if the condition keeps firing. | +| Duration | Opens an alert episode after the threshold has been continuously breached for a set time. | Use when duration of the problem matters more than how many evaluations caught it, for example sustained high CPU rather than a momentary spike. | + +### Activation fields + +Use the following fields to configure the Breaches and Duration modes. Timeframe fields accept duration strings between `5s` and `365d`. Refer to [Duration format](yaml-rule-schema-reference.md#duration-format) for supported units. + +:::{note} +In the YAML rule schema, these fields are prefixed with `state_transition.` — for example, `pending_count` here is `state_transition.pending_count` in the [YAML rule schema reference](yaml-rule-schema-reference.md#state-transition-fields). They are the same fields. +::: + +| Field | Type | Description | +| --- | --- | --- | +| `pending_count` | Integer, 0–1000 | Number of consecutive breach evaluations required before the alert episode opens. Set to `0` to skip the pending phase and transition directly to active on the first breach. | +| `pending_timeframe` | Duration string | How long the condition must remain breached before the alert episode opens. | +| `pending_operator` | `AND` or `OR` | When both `pending_count` and `pending_timeframe` are set, controls whether both must be satisfied (`AND`) or either one is enough (`OR`). | + +You can combine Breaches and Duration by setting both `pending_count` and `pending_timeframe`. Use `pending_operator: AND` to require both conditions before the episode opens, or `pending_operator: OR` if either condition alone is enough. + +## Recovery thresholds + +Recovery thresholds control when an active alert episode transitions back to inactive. The same delay modes available for activation apply. You can require a set number of consecutive recoveries, a minimum recovery duration, or both. + +### Recovery fields + +| Field | Type | Description | +| --- | --- | --- | +| `recovering_count` | Integer, 0–1000 | Number of consecutive non-breaching evaluations required before the alert episode closes. Set to `0` to skip the recovering phase and transition directly to inactive on recovery. | +| `recovering_timeframe` | Duration string | How long the condition must remain non-breaching before the alert episode closes. | +| `recovering_operator` | `AND` or `OR` | When both `recovering_count` and `recovering_timeframe` are set, controls whether both must be satisfied (`AND`) or either one is enough (`OR`). | + +Time frame fields accept the same `5s` to `365d` bounds as activation time frames. Refer to [Duration format](yaml-rule-schema-reference.md#duration-format) for supported units. + +:::{note} +`recovery_strategy` is a separate field that controls how recovery is detected, independent of how many recoveries these thresholds require. Refer to [YAML rule schema reference](yaml-rule-schema-reference.md#recovery-strategy) for field details and default values. +::: + +## Examples + +### Ignore brief CPU spikes + +This rule monitors CPU usage and runs every minute. A single high reading is often a process starting up. Set `pending_count` to `3` so the rule requires 3 consecutive breaches before opening an episode, meaning the condition has been true for at least 3 minutes. This filters out noise without losing real signals. + +### Require sustained breach before escalating + +This rule monitors a payment error rate. Brief spikes happen during deployments and are expected. Set `pending_count` to `5`, `pending_timeframe` to `2m`, and `pending_operator` to `AND`. The rule only fires when the error rate has breached on 5 consecutive evaluations and has been continuously elevated for at least 2 minutes. Either condition alone isn't enough. + +### Require consecutive recoveries before closing an episode + +This rule monitors database connection pool saturation. After the condition clears, set `recovering_count` to `3` to require 3 consecutive non-breaching evaluations before closing the episode. Without this, a rule that alternates between breaching and recovering on consecutive evaluations generates a constant stream of open and closed notifications. diff --git a/explore-analyze/alerting/experimental-alerting-system/rules/create-a-rule.md b/explore-analyze/alerting/experimental-alerting-system/rules/create-a-rule.md new file mode 100644 index 0000000000..26d0f21c42 --- /dev/null +++ b/explore-analyze/alerting/experimental-alerting-system/rules/create-a-rule.md @@ -0,0 +1,24 @@ +--- +navigation_title: Create a rule +applies_to: + stack: experimental 9.5+ + serverless: experimental +products: + - id: kibana +description: "Create rules in Kibana's experimental alerting system using the ES|QL editor, AI Agent, rule builder, or directly from a Discover session." +--- + +# Create a rule in the {{alerting-v2-system}} [create-a-rule] + +The {{alerting-v2-system}} in {{kib}} provides several ways to create rules. For details on configurable rule settings and guidance on how to configure them, refer to [Configure a rule](configure-a-rule.md). + +| Option | Best for | +| --- | --- | +| [Create an ES\|QL rule](create-esql-rule.md) | Full control over the query. Supports both a step-by-step form and a YAML editor. | +| [Create using {{agent-builder}}](create-rules-action-policies-agent-builder.md) | When you know what you want to detect but aren't sure how to write the ES\|QL. | +| [Use the rule builder](use-rule-builder.md) | Rules that follow a guided, form-based setup. | +| [Create from Discover](create-rule-from-discover.md) | When you already have an ES\|QL query working in Discover and want to convert it into a rule. | + +:::{note} +For query examples ranging from a basic event filter to SLO burn rate and persistent breach detection, refer to [ES|QL query patterns](esql-query-patterns.md). +::: \ No newline at end of file diff --git a/explore-analyze/alerting/experimental-alerting-system/rules/create-esql-rule.md b/explore-analyze/alerting/experimental-alerting-system/rules/create-esql-rule.md new file mode 100644 index 0000000000..1d7a455ea1 --- /dev/null +++ b/explore-analyze/alerting/experimental-alerting-system/rules/create-esql-rule.md @@ -0,0 +1,42 @@ +--- +navigation_title: Create an ES|QL rule +applies_to: + stack: experimental 9.5+ + serverless: experimental +products: + - id: kibana +description: "Write ES|QL detection queries for rules in Kibana's experimental alerting system using the rule form or YAML editor, with a live query sandbox for previewing results." +--- + +# Create an {{esql}} rule in the {{alerting-v2-system}} [create-esql-rule] + +The {{esql}} rule path lets you write the detection query directly. There are two ways to define the rule: + +- **Rule form** - Fill in the step-by-step form with a live preview of results. +- **YAML mode** - Edit the raw rule definition. You can switch between form and YAML at any time, unless the YAML can't be translated to a valid form state, in which case you must stay in YAML. + +For details on configurable rule settings and guidance on how to configure them, refer to [Configure a rule](configure-a-rule.md). For a list of supported YAML fields, refer to [YAML rule schema reference](yaml-rule-schema-reference.md). + +## Preview query results in the sandbox [rule-builder-query-sandbox] + +The query sandbox lets you run your {{esql}} query against current data and preview the results before applying them to the rule form. Use the time field selector and date picker to control the time range, then select **Search** (or press ⌘↵) to execute. When the results look correct, select **Apply changes** to populate the form. + +:::{note} +In the query sandbox, the time field selector and date picker control the query results only. They do not set the rule's schedule or lookback period. +::: + +Use the sandbox to: + +- **Confirm grouping** - Check that your `BY` clause produces the series you intend, for example, one distinct series per host or per service, not a single undifferentiated result. +- **Catch unexpected output** - Verify that the query returns data in the right shape for the alert condition you plan to set. A query that returns zero rows or an unexpected field name won't behave as expected once the rule runs on a schedule. +- **Refine before committing** - Edit the query and re-run it as many times as needed without leaving the rule creation form. + +While the sandbox is open, switching between rule form and YAML or between rule modes (Alert and Signal) is not available. Close the sandbox first if you need to change authoring mode. + +### Control how your query splits [sandbox-split-editor] + +By default, applying changes automatically splits your query into a [base query and alert condition](configure-rule-query.md). If you want full manual control over the split, use the toggle in the sandbox to switch to separate Base and Alert editors. If auto-split fails, a callout on the alert condition step lets you open the sandbox directly in manual split mode. + +## Using the YAML editor [yaml-editor] + +Use the YAML editor when you want to copy or adapt a rule quickly without re-entering settings by hand, or provision many rules at once. The YAML editor isn't available within the Threshold Alert builder. diff --git a/explore-analyze/alerting/experimental-alerting-system/rules/create-rule-from-discover.md b/explore-analyze/alerting/experimental-alerting-system/rules/create-rule-from-discover.md new file mode 100644 index 0000000000..4bdb57a615 --- /dev/null +++ b/explore-analyze/alerting/experimental-alerting-system/rules/create-rule-from-discover.md @@ -0,0 +1,28 @@ +--- +navigation_title: Create from Discover +applies_to: + stack: experimental 9.5+ + serverless: experimental +products: + - id: kibana +description: "Convert an ES|QL query from a Discover session into a rule in Kibana's experimental alerting system, with the query pre-filled and a preview panel for verifying grouping." +--- + +# Create a rule from Discover in the {{alerting-v2-system}} [create-from-discover] + +When you build an {{esql}} query in Discover that surfaces interesting patterns, you can convert it into a rule without rewriting the query. Starting from Discover means your query is already tested and returns the shape you expect before the rule is ever saved. + +## Entry points [discover-rule-entry-points] + +Two paths lead to Discover-based rule creation: + +- **Discover Alerts menu**: When you're in Discover with an active {{esql}} query and the {{alerting-v2-system}} is enabled, the Alerts menu includes a **Create ES|QL rule** option. The rule creation flyout opens pre-populated with the current query. This path is only available in ES|QL mode. +- **Rules list**: Selecting the option to create a rule from Discover opens a flyout that embeds a live Discover session so you can compose and test the query before saving the rule. + +## How it works [discover-rule-flow] + +When you trigger rule creation from Discover, your {{esql}} query pre-fills the **Create ES|QL rule** form. The rule creation form also shows a preview panel that reflects how your query partitions results into alert series. If your query uses a `BY` clause, the preview shows the series that would be evaluated on each run, letting you verify grouping logic against live data before committing to a schedule. + +The rule creation flyout supports both a step-by-step form and a YAML editing mode. You can switch between them at any point. Edits in YAML mode are preserved when you return to the form view. The YAML editor includes {{esql}} autocomplete in the query field. + +For details on configurable rule settings and guidance on how to configure them, refer to [Configure a rule](configure-a-rule.md). diff --git a/explore-analyze/alerting/experimental-alerting-system/rules/create-rules-action-policies-agent-builder.md b/explore-analyze/alerting/experimental-alerting-system/rules/create-rules-action-policies-agent-builder.md new file mode 100644 index 0000000000..68074e8ee5 --- /dev/null +++ b/explore-analyze/alerting/experimental-alerting-system/rules/create-rules-action-policies-agent-builder.md @@ -0,0 +1,85 @@ +--- +navigation_title: Create rules using Agent Builder +applies_to: + stack: experimental 9.5+ + serverless: experimental +products: + - id: kibana +description: "How Agent Builder creates rules and action policies in the experimental alerting system using the rule management skill, what the agent produces, and the save-order dependency." +--- + +# Create rules and action policies with {{agent-builder}} [create-rules-agent-builder] + +Rule and action policy authoring in {{agent-builder}} is part of the {{alerting-v2-system}} in {{kib}}. The {{alerting-v2-system}} registers rules and action policies as attachment types in {{agent-builder}}, so an agent equipped with the rule management skill can propose, create, and configure them through natural language conversation. + +Instead of filling out the rule form manually, you describe what you want to monitor and the agent uses its rule management skill and tools to resolve the data source and build a fully configured rule proposal for you. + +## Requirements [create-ai-agent-requirements] + +Before you start, make sure you have the following: + +- **The required subscription** - {{agent-builder}} requires the appropriate {{stack}} [subscription](https://www.elastic.co/pricing) or {{serverless-short}} [project feature tier](/deploy-manage/deploy/elastic-cloud/project-settings.md#project-features-add-ons). +- **The `agentBuilder:experimentalFeatures` advanced setting turned on** - Go to the **Advanced Settings** menu using the navigation menu or the [global search field](/explore-analyze/find-and-organize/find-apps-and-objects.md), and turn on `agentBuilder:experimentalFeatures`. +- **The required privileges** - Your [role](/deploy-manage/users-roles/cluster-or-deployment-auth/kibana-role-management.md) must include the following: + + | To... | Required privilege | + |---|---| + | Access and use {{agent-builder}} | **{{agent-builder}}: Read** (under **Analytics**) | + | Save the rule | **Rules: All** (under **Alerting**) | + | Save the action policy | **Action Policies: All** (under **Alerting**) | + | Select or create the workflow destination | **Workflows: Read** to select an existing workflow; **Workflows: All** to create one (under **Analytics > Workflows**) | + +## Propose and save a rule [ai-agent-rule-proposal] + +You can start from the rule management page by selecting the option to create a rule with an agent, or open any agent in [{{agent-builder}}](/explore-analyze/ai-features/elastic-agent-builder.md) that has the rule management skill configured. The rule management skill gives the agent domain expertise in {{alerting-v2-system}} rule authoring, including knowledge of {{esql}} query patterns, threshold configuration, grouping, and the alerting v2 data model. When you describe a monitoring requirement, the agent uses its tools to resolve the relevant data source and builds a rule proposal. + +The proposal appears as an inline attachment in the conversation, summarizing the rule name, type, schedule, and tags. Opening the attachment shows the full configuration across three views: + +- **Conditions** - The {{esql}} query, thresholds, grouping criteria, and schedule the agent constructed. +- **Query preview** - The results of running the proposed {{esql}} query against live data, so you can evaluate whether the rule would produce meaningful signal before committing to it. +- **Runbook** - A free-text runbook field associated with the rule, which the agent can populate from context in the conversation. + +The agent can also search for and attach an existing rule to the conversation using the same inline attachment, opening the same view for inspection or revision. + +The agent does not persist the rule automatically. Saving is an explicit action that signals the configuration is ready. Until the rule is saved, the proposal exists only in the conversation and is not evaluated against data. + +When {{agent-builder}} saves or edits a rule, {{kib}} automatically adds an `agent-builder-assisted` tag to it. The tag appears in the rules list and works as a normal filter tag. You can remove it or edit it manually. If the agent edits the same rule later, the tag is re-applied automatically. + +:::{note} +Signal rules do not support notifications. Alert episodes, and therefore action policies, only apply to rules running in Alert mode. If you ask the agent to set up notifications for a signal rule, the rule management skill explains the limitation and offers to either convert the rule to Alert mode or create a separate alert rule. +::: + +## Example prompts [ai-agent-sample-prompts] + +Use these prompts as a starting point, then adjust them to your data and thresholds: + +- Create an error threshold rule on the checkout service data. Alert when there are more than 3 HTTP 5xx errors in the past 5 minutes, grouped by URL path. +- Monitor average CPU usage across all hosts. Alert when any host exceeds 90% for more than 10 minutes. +- Alert when log volume from the payments service drops below 100 events in a 5-minute window. This likely means data has stopped flowing. +- Set up a rule that tracks error rate by service. Alert at medium severity when the rate exceeds 1%, and critical when it exceeds 5%. + +## Set up notifications [ai-agent-notification-setup] + +After a rule is saved, you can ask the agent to configure notifications. The rule management skill handles this by creating workflows and action policies. + +- **Workflows** - Workflows are the delivery mechanism. They define what happens when the {{alerting-v2-system}} determines that a notification should be sent, such as posting to Slack, emailing a team, triggering PagerDuty, and so on. +- **Action policies** - Action policies are the gating mechanism. They evaluates alert episodes from the rule on a continuous schedule and invokes the workflow when the episode clears the action policy's match conditions and frequency settings. When the agent creates an action policy alongside a specific rule, the action policy is automatically scoped to that rule. + +Both objects are proposed as inline attachments and must be explicitly saved before they take effect. + +### Save order [save-order-ai-agent] + +The three objects have a dependency chain that determines the order in which they must be saved: + +1. **Rule** - The action policy references the rule by ID. The ID is not available until the rule is persisted. +2. **Workflow** - The action policy references the workflow as a destination. The reference must resolve to a persisted workflow. +3. **Action policy** - Can only be saved after both its rule and workflow dependencies exist. + +Action policies saved or edited through {{agent-builder}} also receive the `agent-builder-assisted` tag automatically, with the same behavior: user-editable and re-applied on subsequent agent edits. + +## Related pages + +- [{{agent-builder}}](/explore-analyze/ai-features/elastic-agent-builder.md) - How the {{agent-builder}} platform works, including agents, skills, and tools. + + + diff --git a/explore-analyze/alerting/experimental-alerting-system/rules/esql-first-rule-query.md b/explore-analyze/alerting/experimental-alerting-system/rules/esql-first-rule-query.md new file mode 100644 index 0000000000..80e4b17674 --- /dev/null +++ b/explore-analyze/alerting/experimental-alerting-system/rules/esql-first-rule-query.md @@ -0,0 +1,47 @@ +--- +navigation_title: Your first rule query +applies_to: + stack: experimental 9.5+ + serverless: experimental +products: + - id: kibana +description: "Write your first ES|QL rule query in Kibana's experimental alerting system. Covers the minimum query structure and how to adapt it to your data." +--- + +# Your first rule query in the {{alerting-v2-system}} [first-rule-query] + +If you're new to {{esql}} or to writing rules, this page shows the simplest query structure that a rule needs. It requires only a basic familiarity with your data. + +## The simplest rule query + +This query returns one row for every log entry at `ERROR` level in the lookback window. No aggregation happens. Each matching event becomes its own alert event. Use this pattern when any single occurrence of a condition is worth alerting on: any critical error log, any failed authentication attempt, any payment rejection. + +```esql +FROM logs-* +| WHERE @timestamp >= ?_tstart AND @timestamp < ?_tend // Scope to the rule's configured lookback window +| WHERE level == "ERROR" // The alert condition: every match is a breach +| KEEP service.name, message, @timestamp // Fields stored on each alert event +``` + +Every row the query returns is treated as a breach. If the query returns nothing, no alert fires. + +### What each part does + +| Part | Purpose in a rule | +| --- | --- | +| `FROM logs-*` | The index or data stream to query. | +| `WHERE @timestamp >= ?_tstart AND @timestamp < ?_tend` | Scopes the query to the rule's lookback window. `?_tstart` and `?_tend` are bound automatically at runtime. Always include this filter to avoid scanning your entire index on every evaluation. | +| `WHERE level == "ERROR"` | The alert condition. Only rows that pass this filter generate an alert event. | +| `KEEP service.name, message, @timestamp` | The fields stored on each alert event. Only fields in `KEEP` are available for routing, grouping, and triage. | + +### How to adapt this query + +To use this query with your own data, change three things: + +1. **Index**: Replace `logs-*` with the index or data stream that holds your data. +2. **Alert condition**: Replace `level == "ERROR"` with the field name and value that defines a breach in your data. For example: `event.outcome == "failure"`, `http.response.status_code >= 500`, or `process.name == "malware.exe"`. +3. **KEEP fields**: Replace the field list with whatever you need for triage. Include any fields you plan to use for grouping, routing, or displaying in the alert detail view. + +## Next steps + +This pattern alerts on individual events. If you want to alert only when a count or rate crosses a threshold rather than on individual occurrences, the [threshold query pattern](esql-threshold-queries.md) is the next step. diff --git a/explore-analyze/alerting/experimental-alerting-system/rules/esql-no-data-detection.md b/explore-analyze/alerting/experimental-alerting-system/rules/esql-no-data-detection.md new file mode 100644 index 0000000000..e74676cb8f --- /dev/null +++ b/explore-analyze/alerting/experimental-alerting-system/rules/esql-no-data-detection.md @@ -0,0 +1,32 @@ +--- +navigation_title: No-data detection +applies_to: + stack: experimental 9.5+ + serverless: experimental +products: + - id: kibana +description: "Detect silent hosts and stopped data sources in Kibana's experimental alerting system using ES|QL last-seen queries." +--- + +# No-data detection in the {{alerting-v2-system}} [no-data-esql-query] + +No-data detection solves a different problem from threshold alerting. A threshold query evaluates data that's present. No-data detection identifies sources that have gone silent. Threshold queries can't do this. A silent host produces no rows at all, so there's nothing to evaluate a condition against. + +The pattern inverts the normal approach: use a broad lookback to find all known hosts, then surface only those that have not reported recently. + +```esql +FROM metrics-* +| WHERE @timestamp >= NOW() - 12 hours // Cover the longest expected reporting gap for your hosts. + // Too short: silent hosts fall outside the window and are never checked. + // Too long: increases query cost on high-frequency data streams. +| STATS last_seen = MAX(@timestamp) BY host.name // Find the most recent event timestamp per host +| WHERE last_seen < NOW() - 15 minutes // Silence threshold: set slightly above your expected maximum reporting interval + // to avoid false positives from brief gaps +| KEEP host.name, last_seen // Each returned row is a silent host +``` + +Every row returned is a host that has gone silent. The query result itself drives the alert. A separate alert condition isn't needed. + +:::{note} +This pattern detects specific silent sources. For controlling what the rule records when the entire base query returns zero rows, for example when an index is completely empty, refer to [No-data handling](configure-no-data-handling.md). +::: diff --git a/explore-analyze/alerting/experimental-alerting-system/rules/esql-persistent-breach.md b/explore-analyze/alerting/experimental-alerting-system/rules/esql-persistent-breach.md new file mode 100644 index 0000000000..d6471397ed --- /dev/null +++ b/explore-analyze/alerting/experimental-alerting-system/rules/esql-persistent-breach.md @@ -0,0 +1,45 @@ +--- +navigation_title: Persistent breach detection +applies_to: + stack: experimental 9.5+ + serverless: experimental +products: + - id: kibana +description: "Detect conditions that persist across consecutive time buckets in Kibana's experimental alerting system using ES|QL bucket counting." +--- + +# Persistent breach detection in the {{alerting-v2-system}} [persistent-breach] + +A persistent breach condition detects a metric that stays above a threshold across several consecutive time buckets, for example CPU above 90% in all 10 of the last 10 five-minute windows. This filters out transient spikes and fires only when a problem has been sustained. + +{{esql}} can express this with bucket counting: + +```esql +FROM metrics-* +| WHERE @timestamp >= NOW() - 50 minutes // Lookback must cover all 10 buckets (10 × 5 min = 50 min) +| EVAL bucket = BUCKET(@timestamp, 5 minutes) // Assign each event to its 5-minute time bucket +| STATS + total_buckets = COUNT_DISTINCT(bucket), // How many distinct buckets exist in the window + exceeding_buckets = COUNT_DISTINCT( + CASE(system.cpu.total.pct > 0.90, bucket, null) // Count only buckets where CPU exceeded threshold; + ) // null values are excluded by COUNT_DISTINCT + BY host.name +| WHERE total_buckets >= 10 // Require a full window of data before firing; + AND exceeding_buckets == total_buckets // every bucket must have breached +| KEEP host.name, total_buckets, exceeding_buckets +``` + +The rule's lookback window must cover all the buckets you want to check. In this example, 10 five-minute buckets requires at least 50 minutes of lookback. + +## Handling gaps in data + +If any bucket is missing because the host stopped reporting briefly mid-window, `total_buckets` drops below 10 and the condition doesn't fire. This is a deliberate safety check: a host that went silent for one bucket is treated as "we don't have enough data to confirm persistence" rather than "breach." + +If you want to allow some gaps, replace `exceeding_buckets == total_buckets` with a ratio or a minimum count: + +```esql +| WHERE total_buckets >= 8 // Tolerate up to 2 missing buckets + AND exceeding_buckets >= total_buckets * 0.9 // 90% of present buckets must have breached +``` + +Design the query so that gaps in reporting produce the behavior you want before deploying it. diff --git a/explore-analyze/alerting/experimental-alerting-system/rules/esql-query-patterns.md b/explore-analyze/alerting/experimental-alerting-system/rules/esql-query-patterns.md new file mode 100644 index 0000000000..604ff57bd9 --- /dev/null +++ b/explore-analyze/alerting/experimental-alerting-system/rules/esql-query-patterns.md @@ -0,0 +1,21 @@ +--- +navigation_title: ES|QL query patterns +applies_to: + stack: experimental 9.5+ + serverless: experimental +products: + - id: kibana +description: "ES|QL query patterns for rules in Kibana's experimental alerting system, from basic event filters to SLO burn rates, silent source detection, and persistent breach checks." +--- + +# {{esql}} query patterns for rules in the {{alerting-v2-system}} [esql-query-patterns] + +The following pages cover {{esql}} query patterns for rules in the {{alerting-v2-system}}, ordered from the simplest starting point to advanced use cases. Start with [Your first rule query](esql-first-rule-query.md) if you're new, or jump to the pattern you need. + +| Pattern | What it solves | Complexity | +| --- | --- | --- | +| [Your first rule query](esql-first-rule-query.md) | Alert on any individual event that matches a condition. No aggregation needed. | Beginner | +| [Threshold queries](esql-threshold-queries.md) | Alert when a metric crosses a limit. Covers single-series and grouped (per-host, per-service) rules. | Beginner | +| [No-data detection](esql-no-data-detection.md) | Alert when a specific host or data source stops reporting. | Intermediate | +| [SLO burn rate](esql-slo-burn-rate.md) | Alert when error budget consumption exceeds safe rates across multiple time windows. | Advanced | +| [Persistent breach detection](esql-persistent-breach.md) | Alert when a condition has been continuously true across consecutive time buckets. | Advanced | diff --git a/explore-analyze/alerting/experimental-alerting-system/rules/esql-slo-burn-rate.md b/explore-analyze/alerting/experimental-alerting-system/rules/esql-slo-burn-rate.md new file mode 100644 index 0000000000..98a53f0e47 --- /dev/null +++ b/explore-analyze/alerting/experimental-alerting-system/rules/esql-slo-burn-rate.md @@ -0,0 +1,75 @@ +--- +navigation_title: SLO burn rate +applies_to: + stack: experimental 9.5+ + serverless: experimental +products: + - id: kibana +description: "Detect SLO error budget burn across multiple time windows in Kibana's experimental alerting system using ES|QL conditional aggregation." +--- + +# SLO burn rate detection in the {{alerting-v2-system}} [slo-burn-rate-query] + +An SLO burn rate query asks a different question than a basic threshold: are you consuming your error budget faster than you can afford to? Rather than checking a single metric at a fixed limit, it calculates error rates across multiple time windows simultaneously and assigns a severity level based on how fast the budget is being consumed. + +## Single-tier query + +This version checks one window pair and fires only at `critical` severity. It shows the core two-window pattern with the minimum number of moving parts. + +```esql +FROM metrics-* +| WHERE @timestamp >= NOW() - 1 hour // Cover the longest window in the pair +| STATS + errors_5m = COUNT_IF(outcome == "failure" AND @timestamp >= NOW() - 5 minutes), + total_5m = COUNT_IF(@timestamp >= NOW() - 5 minutes), + errors_1h = COUNT_IF(outcome == "failure"), + total_1h = COUNT(*) + BY slo.id // Each SLO is evaluated independently +| EVAL + burn_5m = errors_5m / total_5m, + burn_1h = errors_1h / total_1h +| WHERE burn_5m > 14.4 AND burn_1h > 14.4 // Both windows must exceed the threshold to fire; + // the short window detects the spike, the long window confirms it's sustained +| EVAL severity = "critical" +| KEEP slo.id, severity, burn_5m, burn_1h +``` + +The 14.4× multiplier reflects the rate at which a service would exhaust a 99.9% monthly error budget in one hour. Adjust it to match your SLO target. + +## Multi-tier query + +This version extends the single-tier pattern to detect both `critical` and `high` severity in one pass. Each severity level uses its own window pair with different time scales and thresholds. + +```esql +FROM metrics-* +| WHERE @timestamp >= NOW() - 3 days // Cover the longest window pair used below. + // Keep this in sync with the rule's lookback setting. +| STATS + // CRITICAL window pair: 5 min fast signal, 1 hour sustained confirmation + errors_5m = COUNT_IF(outcome == "failure" AND @timestamp >= NOW() - 5 minutes), + total_5m = COUNT_IF(@timestamp >= NOW() - 5 minutes), + errors_1h = COUNT_IF(outcome == "failure" AND @timestamp >= NOW() - 1 hour), + total_1h = COUNT_IF(@timestamp >= NOW() - 1 hour), + // HIGH window pair: 30 min fast signal, 6 hours sustained confirmation + errors_30m = COUNT_IF(outcome == "failure" AND @timestamp >= NOW() - 30 minutes), + total_30m = COUNT_IF(@timestamp >= NOW() - 30 minutes), + errors_6h = COUNT_IF(outcome == "failure" AND @timestamp >= NOW() - 6 hours), + total_6h = COUNT_IF(@timestamp >= NOW() - 6 hours) + BY slo.id +| EVAL + burn_5m = errors_5m / total_5m, + burn_1h = errors_1h / total_1h, + burn_30m = errors_30m / total_30m, + burn_6h = errors_6h / total_6h +| EVAL severity = CASE( + burn_5m > 14.4 AND burn_1h > 14.4, "critical", + burn_30m > 6.0 AND burn_6h > 6.0, "high", + "none" + ) +| WHERE severity != "none" +| KEEP slo.id, severity, burn_5m, burn_1h, burn_30m, burn_6h +``` + +The rule's lookback window must cover the longest window in the query. In this example that's 3 days, driven by the 6-hour window pair. + +The `severity` column in `KEEP` maps directly to the `severity` field on each resulting alert episode. For accepted values and matching rules, refer to [Severity](configure-rule-severity.md). diff --git a/explore-analyze/alerting/experimental-alerting-system/rules/esql-threshold-queries.md b/explore-analyze/alerting/experimental-alerting-system/rules/esql-threshold-queries.md new file mode 100644 index 0000000000..ffaf304936 --- /dev/null +++ b/explore-analyze/alerting/experimental-alerting-system/rules/esql-threshold-queries.md @@ -0,0 +1,59 @@ +--- +navigation_title: Threshold queries +applies_to: + stack: experimental 9.5+ + serverless: experimental +products: + - id: kibana +description: "Write ES|QL threshold queries for rules in Kibana's experimental alerting system. Covers single-series and grouped rules using STATS aggregation." +--- + +# Threshold queries in the {{alerting-v2-system}} [esql-threshold-queries] + +A threshold query aggregates your data first, then applies an alert condition to the result. Use this pattern when a single matching event isn't enough to warrant an alert. You want to know whether a metric (count, rate, average) has crossed a limit over a time window. + +This page covers two variants: a single-series threshold that produces one result for all your data, and a grouped threshold that tracks each subject (host, service, user) independently. + +## Single-series threshold + +This query counts HTTP 5xx responses and error rates over the lookback window and alerts when the error rate for any service exceeds 10%. + +```esql +FROM logs-* +| WHERE @timestamp >= ?_tstart AND @timestamp < ?_tend // Scope to the rule's configured lookback window +| STATS + error_count = COUNT_IF(http.response.status_code >= 500), // Count only error responses + total_count = COUNT(*) // Count all requests for the denominator + BY service.name +| EVAL error_rate = error_count / total_count // Compute error rate as a fraction (0–1) +| WHERE error_rate > 0.10 // Alert condition: services above 10% error rate are breaches +| KEEP service.name, error_rate, error_count, total_count +``` + +One window, one aggregate per service, one threshold check. The result is either a breach or no breach for each service. + +## Grouped threshold + +Adding `BY` to the `STATS` command splits the result into one row per unique field value. Each row is evaluated independently against the alert condition, and each breach creates its own alert series. + +This query tracks average CPU usage per host and alerts when any host exceeds 90%: + +```esql +FROM metrics-* +| WHERE @timestamp >= ?_tstart AND @timestamp < ?_tend +| STATS avg_cpu = AVG(system.cpu.total.pct) BY host.name // One result row per host +| WHERE avg_cpu > 0.90 // Each host above the threshold is a breach +| KEEP host.name, avg_cpu +``` + +Without the `BY host.name` clause, the query would produce a single average across all hosts combined. A cluster-wide spike might push the average above the threshold even if no single host is the problem. Grouping by host gives each host its own alert episode with its own lifecycle. If host A recovers but host B stays critical, those are tracked separately. + +The `BY` fields you use here must match the grouping configuration in the rule. Refer to [Rule grouping](configure-rule-grouping.md) for how to align them. + +## Next steps + +If both of these patterns don't fit your use case, the next pages cover more specific detection problems: + +- [No-data detection](esql-no-data-detection.md): when a host or source stops reporting entirely +- [SLO burn rate](esql-slo-burn-rate.md): when you need to check error budget consumption across multiple time windows +- [Persistent breach detection](esql-persistent-breach.md): when you only want to alert if a condition has been continuously true diff --git a/explore-analyze/alerting/experimental-alerting-system/rules/review-rule-execution-history.md b/explore-analyze/alerting/experimental-alerting-system/rules/review-rule-execution-history.md new file mode 100644 index 0000000000..396593b52b --- /dev/null +++ b/explore-analyze/alerting/experimental-alerting-system/rules/review-rule-execution-history.md @@ -0,0 +1,31 @@ +--- +navigation_title: Review execution history +applies_to: + stack: experimental 9.5+ + serverless: experimental +products: + - id: kibana +description: "Use the Execution History page in Kibana's experimental alerting system to monitor rule and action policy execution outcomes across all rules in a space." +--- + +# Review execution history in the {{alerting-v2-system}} [review-rule-execution-history] + +Execution history gives you a cross-rule, filterable log of every rule run and action policy dispatch across the space. Rule executions and action policy dispatcher decisions are shown separately, with different scopes. + +## Rule executions [rule-execution-records] + +Rule execution history shows one row per rule evaluation across all rules in the space. Use it to spot patterns that aren't visible when looking at individual rules, for example, a cluster of failures at the same timestamp that points to a shared dependency issue. + +| Column | Description | +|---|---| +| **Timestamp** | When the rule execution ran. | +| **Rule** | The rule that ran. Selecting the rule name opens a summary so you can inspect the rule without leaving the page. | +| **Duration** | How long the execution took. | +| **Response** | The outcome of the run: `success` or `failure`. | +| **Message** | An optional message included with the execution result, typically an error description for failed runs. | + +Use the outcome filter to view only successful or failed executions. Filtering is applied server-side. Results are paginated up to 100 per page. You can page through up to 10,000 records — this is a pagination ceiling, not a retention limit. Deeper history exists in the event log but is not reachable by paging further. + +## Action policy dispatcher decisions [policy-execution-records] + +Action policy execution history shows one row per action policy dispatcher decision and covers the **last 24 hours** only. Use it to audit whether action policies are dispatching as expected. Results are paginated up to 100 per page. diff --git a/explore-analyze/alerting/experimental-alerting-system/rules/rule-event-field-reference.md b/explore-analyze/alerting/experimental-alerting-system/rules/rule-event-field-reference.md new file mode 100644 index 0000000000..42a157e16c --- /dev/null +++ b/explore-analyze/alerting/experimental-alerting-system/rules/rule-event-field-reference.md @@ -0,0 +1,44 @@ +--- +navigation_title: Rule events +applies_to: + stack: experimental 9.5+ + serverless: experimental +products: + - id: kibana +description: "How the experimental alerting system in Kibana writes rule events to .rule-events: signal and alert document types, shared base fields, episode fields, and the append-only data stream behavior." +--- + +# Rule events in {{alerting-v2-system}} [rule-reference] + +This page explains the two types of documents the {{alerting-v2-system}} writes to `.rule-events` and how the data stream behaves, so you can write {{esql}} queries against `.rule-events` with confidence, for example, to replay an episode's history, investigate a signal, or build dashboards from rule output. + + + +:::{important} +The `.rule-events` and `.alert-actions` data streams are [system indices](/reference/glossary/index.md#glossary-system-index). {{kib}} manages their versioning, retention, and lifecycle through [index lifecycle management (ILM)](/manage-data/lifecycle/index-lifecycle-management.md). Older backing indices are deleted automatically when the retention window expires. Do not change mappings or index settings for these streams yourself. +::: + +## Rule event documents + +Each time a rule evaluates, {{kib}} writes one document per matched series to `.rule-events`. The `type` field determines the document kind: + +- **`signal`** - A point-in-time record that the query matched. Useful for querying history or chaining into follow-on rules. Signal documents don't include `episode.*` fields. +- **`alert`** - A lifecycle-tracked episode visible in the alert inbox, episode details, and triage views. Alert documents include `episode.*` fields and represent a breach that stays open until the condition clears. + +Both kinds share base fields. Only `alert` documents add episode fields that carry the lifecycle state for the matched series. + +:::{note} +The `.rule-events` data stream is append-only. A new document is written on every rule evaluation. Existing documents are never updated. Each document is a snapshot of that moment. The `episode.status` field records the lifecycle stage the episode was in at that evaluation. To view the full history of an episode, query `.rule-events` filtered by `episode.id`, for example: + +```esql +FROM .rule-events +| WHERE episode.id == "" +| SORT @timestamp ASC +``` + + +::: \ No newline at end of file diff --git a/explore-analyze/alerting/experimental-alerting-system/rules/use-rule-builder.md b/explore-analyze/alerting/experimental-alerting-system/rules/use-rule-builder.md new file mode 100644 index 0000000000..bc5c59dd44 --- /dev/null +++ b/explore-analyze/alerting/experimental-alerting-system/rules/use-rule-builder.md @@ -0,0 +1,19 @@ +--- +navigation_title: Create rules using the rule builder +applies_to: + stack: experimental 9.5+ + serverless: experimental +products: + - id: kibana +description: "Create Threshold Alert rules in Kibana's experimental alerting system using a guided form that generates ES|QL automatically." +--- + +# Create a rule using the rule builder in the {{alerting-v2-system}} [use-rule-builder] + +The rule builder provides a guided form for creating rules without writing {{esql}} by hand. The builder generates the {{esql}} query automatically from structured inputs for the data source, aggregation, filters, and alert conditions. + +For details on configurable rule settings and guidance on how to configure them, refer to [Configure a rule](configure-a-rule.md). + +## Threshold Alert [use-threshold-alert-builder] + +Threshold Alert is the rule type currently available in the rule builder. Use it to monitor metrics against one or more threshold conditions. Custom aggregations let you control how metric values are computed before they are compared to the threshold. \ No newline at end of file diff --git a/explore-analyze/alerting/experimental-alerting-system/rules/view-manage-rules.md b/explore-analyze/alerting/experimental-alerting-system/rules/view-manage-rules.md new file mode 100644 index 0000000000..9a5b58915f --- /dev/null +++ b/explore-analyze/alerting/experimental-alerting-system/rules/view-manage-rules.md @@ -0,0 +1,45 @@ +--- +navigation_title: View and manage rules +applies_to: + stack: experimental 9.5+ + serverless: experimental +products: + - id: kibana +description: "Search, filter, and bulk-manage rules in Kibana's experimental alerting system. Use inline editing, the rule summary flyout, and the rule details page to manage rules." +--- + +# View and manage rules in the {{alerting-v2-system}} [manage-rules] + +Rule management is part of the {{alerting-v2-system}} in {{kib}}. This page covers how to find and filter rules in the rules list, quick-edit settings without leaving the list, use the rule summary flyout, and navigate the rule details page including the alert activity timeline. + +## Find and filter rules [find-filter-rules] + +Use the search bar to find rules by name or description. Each space-separated term is matched independently using prefix matching. Tags and grouping fields appear in results but aren't searchable. + +Combine text search with filter controls to narrow by rule type, status, or tags. Select any column header to sort, or use bulk actions to enable, disable, or delete multiple rules at once. + +## Edit a rule inline [quick-edit-rule] + +To update common rule settings without opening the full rule details page, use the inline edit option on any row in the rules list. The inline editor also opens from the rule summary flyout header. + +Use inline edit when you need to adjust metadata or scheduling settings quickly without navigating away from the list. + +## Inspect a rule with the summary flyout [rule-summary-flyout] + +To inspect a rule without navigating away from the rules list, select the expand icon on any row. The rule summary flyout opens alongside the list and shows a snapshot of the rule: its status, last run time, recent alert episode activity, and quick actions such as enable, disable, and snooze. + +Use the flyout when you want to confirm a rule is healthy or take a quick action without committing to a full page load. To open the complete rule configuration with all settings and edit controls, select the rule name in the table row or in the flyout header. + +## Review rule configuration and activity [rule-details-page] + +The rule details page is organized into tabs that let you review a rule's configuration and activity history. + +- **Overview** (Alert mode only): Shows a color-coded alert activity timeline per series, with summary statistics (episodes started, recovered, still open, and median duration) and a link to view matching episodes. +- **Conditions**: The rule's base query, alert condition, schedule, lookback, grouping, and recovery settings. +- **Runbook**: The rule's investigation guide, if one has been added. Use it to document steps for diagnosing or responding to alerts produced by this rule. + +Use **Edit** to modify the rule, or the actions menu to enable, disable, clone, or delete it. + +## Disable or snooze a rule [disable-snooze-rule] + +Use **Disable** when you want the rule to stop running entirely until you re-enable it. This is different from snoozing, which suppresses notifications or quiets a series or action policy without stopping rule evaluation. \ No newline at end of file diff --git a/explore-analyze/alerting/experimental-alerting-system/rules/yaml-rule-schema-reference.md b/explore-analyze/alerting/experimental-alerting-system/rules/yaml-rule-schema-reference.md new file mode 100644 index 0000000000..4519c8208e --- /dev/null +++ b/explore-analyze/alerting/experimental-alerting-system/rules/yaml-rule-schema-reference.md @@ -0,0 +1,130 @@ +--- +navigation_title: YAML rule schema reference +applies_to: + stack: experimental 9.5+ + serverless: experimental +products: + - id: kibana +description: "YAML rule definitions in Kibana's experimental alerting system support fields for detection mode, schedule, query, grouping, and recovery. Reference tables list all valid field values." +--- + +# YAML rule schema reference for the {{alerting-v2-system}} [yaml-rule-schema-reference] + + +YAML rule schema is part of the {{alerting-v2-system}} in {{kib}}. This page lists valid fields for YAML rule definitions. For examples and authoring guidance, refer to [Create an ES|QL rule](create-esql-rule.md#yaml-editor). + +## Base rule fields + +These four fields are required on every rule, regardless of format or mode. The value of `query.format` determines which additional query fields are required. + +| Field | Type | Accepted values | Description | +|---|---|---|---| +| `kind` | string | `alert` or `signal` | Whether the rule tracks ongoing episodes (`alert`) or records point-in-time observations (`signal`). | +| `metadata.name` | string | Any string | The name of the rule. Max 256 characters. | +| `schedule.every` | duration | Any duration string | How often the rule runs. For example: `5s`, `1m`, `5m`. Minimum interval applies. | +| `query.format` | string | `composed` or `standalone` | The query structure the rule uses. `standalone` means each condition (breach, recovery, no-data) is a separate, self-contained ES\|QL query. `composed` means you write one base query and each condition is a pipe segment appended to it. The UI always creates `standalone` rules. | + +### Fields for `query.format: composed` + +Use `composed` when breach, recovery, and no-data conditions all start from the same data shape. Define that shape once in the base query and each condition adds only what differs. + +| Field | Type | Description | +|---|---|---| +| `query.base` | ES\|QL string | Base query that runs on every evaluation. Time filters are applied automatically using the lookback window. Required. | +| `query.breach.segment` | ES\|QL segment string | ES\|QL segment appended to the base query for breach detection. Written as a pipe command, for example `\| WHERE count > 5`. Required. | +| `query.recovery.segment` | ES\|QL segment string | ES\|QL segment appended to the base query for recovery detection. Required when `recovery_strategy` is `query`. | + +### Fields for `query.format: standalone` + +Use `standalone` when conditions need full independence. Each query can target different indices, apply different filters, or return a completely different shape. + +| Field | Type | Description | +|---|---|---| +| `query.breach.query` | Full ES\|QL string | Full ES\|QL query for breach detection. Required. | +| `query.recovery.query` | Full ES\|QL string | Full ES\|QL query for recovery detection. Required when `recovery_strategy` is `query`. | +| `query.no_data.query` | Full ES\|QL string | Full ES\|QL query that detects presence of data. Required when `no_data_strategy` is not `none`. Only supported on `standalone` format. | + +## Metadata fields + +These optional fields add descriptive information to a rule for identification, ownership, and filtering. None affect rule evaluation behavior. + +| Field | Type | Accepted values | Description | +|---|---|---|---| +| `metadata.description` | string | Any string | Optional description of what the rule monitors. Max 1,024 characters. | +| `metadata.owner` | string | Any string | Team or person responsible for the rule. Max 256 characters. | +| `metadata.tags` | array of strings | Array of strings | Labels for filtering and organization. Max 20 tags, each max 128 characters. | + +## Schedule fields + +These fields control how far back each evaluation looks and which timestamp field is used for the time range filter. Both are optional, but omitting `schedule.lookback` means the query runs without a time bound. + +| Field | Type | Accepted values | Description | +|---|---|---|---| +| `schedule.lookback` | duration | Any duration string | How far back in time the query searches on each run. For example: `5m`, `24h`. | +| `time_field` | string | Any field name | The timestamp field used for the lookback window filter. Max 128 characters. Defaults to `@timestamp`. | + +## Recovery strategy [recovery-strategy] + +The `recovery_strategy` field is optional. When omitted, the rule emits no recovery events and active alert episodes don't close automatically. + +| Field | Type | Accepted values | Description | +|---|---|---|---| +| `recovery_strategy` | string | `no_breach`, `query`, or `none` | How recovery is detected.

-`no_breach`: Recovers an episode when its active group no longer appears in the breach results.
- `query`: Evaluates a separate recovery query defined in `query.recovery.segment` (composed) or `query.recovery.query` (standalone)
- `none`: Turns off recovery. | + +:::{note} +Signal-mode rules (`kind: signal`) must omit `recovery_strategy` or set it to `none`. Any other value fails validation. +::: + +## State transition fields [state-transition-fields] + +Only valid when `kind: alert`. Controls how many consecutive detections are required before an episode becomes active or recovers. + +| Field | Type | Accepted values | Description | +|---|---|---|---| +| `state_transition.pending_operator` | string | `AND` or `OR` | Whether both the count and timeframe must be met (`AND`) or either one (`OR`) before becoming active. | +| `state_transition.pending_count` | integer | Integer, 0–1000 | Number of consecutive breaches required before the episode becomes active. Set to `0` to skip the pending phase and transition directly to active on the first breach. | +| `state_transition.pending_timeframe` | duration | Any duration string | Time window within which the breach count must be met. For example: `5m`. | +| `state_transition.recovering_operator` | string | `AND` or `OR` | Whether both the count and timeframe must be met (`AND`) or either one (`OR`) before recovering. | +| `state_transition.recovering_count` | integer | Integer, 0–1000 | Number of consecutive clear evaluations required before the episode recovers. Set to `0` to skip the recovering phase and transition directly to inactive on recovery. | +| `state_transition.recovering_timeframe` | duration | Any duration string | Time window within which the recovery count must be met. For example: `5m`. | + +## Grouping fields + +Use grouping to split a rule's detections into independent series, one per unique combination of field values. This lets a single rule track multiple subjects without creating a separate rule for each, for example, tracking CPU usage per host. Each series maintains its own alert episode lifecycle. + +| Field | Type | Accepted values | Description | +|---|---|---|---| +| `grouping.fields` | array of strings | Array of field names | Fields to group results by. Each unique combination becomes its own series. Max 16 fields, each max 256 characters. | + +## No-data strategy + +Use `no_data_strategy` to control what the rule does when an evaluation returns no results. This matters when data sources can go silent: without a no-data strategy, a quiet data source and a healthy one look identical to the rule. + +| Field | Type | Accepted values | Description | +|---|---|---|---| +| `no_data_strategy` | string | `emit`, `last_known_status`, `recover`, or `none` | Optional. What happens when the rule evaluates and returns no results. `emit` records a no-data event. `last_known_status` holds the last known status. `recover` forces recovery. `none` disables no-data detection. | + +:::{note} +No-data detection is only supported with `query.format: standalone`. Setting `no_data_strategy` to any active value on a `composed` rule has no effect because `query.no_data.query` can only be defined on a standalone query. Signal-mode rules (`kind: signal`) must omit `no_data_strategy` or set it to `none`. +::: + +## Artifact fields + +Artifacts let you attach reference material directly to a rule, such as a runbook. The content is stored with the rule and displayed in the rule detail view so responders have context when an alert fires. All artifact fields are optional. + +| Field | Type | Accepted values | Description | +|---|---|---|---| +| `artifacts[].id` | string | Any string | Artifact identifier. Required. Max 256 characters. | +| `artifacts[].type` | string | Any string | The type of artifact being attached. For example: `runbook`. | +| `artifacts[].value` | string | Any string | The content of the artifact. Accepts markdown. Runbooks are rendered as markdown in the rule detail view. | + +## Duration format [duration-format] + +All duration fields accept the following units: + +| Unit | Example | Meaning | +|---|---|---| +| `s` | `30s` | Seconds | +| `m` | `5m` | Minutes | +| `h` | `1h` | Hours | +| `d` | `7d` | Days | diff --git a/explore-analyze/toc.yml b/explore-analyze/toc.yml index 01dddb02ed..4be535c3b2 100644 --- a/explore-analyze/toc.yml +++ b/explore-analyze/toc.yml @@ -385,6 +385,36 @@ toc: - file: report-and-share/reporting-troubleshooting-pdf.md - file: alerting.md children: + - file: alerting/experimental-alerting-system/rules.md + children: + - file: alerting/experimental-alerting-system/rules/create-a-rule.md + children: + - file: alerting/experimental-alerting-system/rules/create-esql-rule.md + children: + - file: alerting/experimental-alerting-system/rules/yaml-rule-schema-reference.md + - file: alerting/experimental-alerting-system/rules/create-rules-action-policies-agent-builder.md + - file: alerting/experimental-alerting-system/rules/use-rule-builder.md + - file: alerting/experimental-alerting-system/rules/create-rule-from-discover.md + - file: alerting/experimental-alerting-system/rules/configure-a-rule.md + children: + - file: alerting/experimental-alerting-system/rules/configure-rule-mode.md + - file: alerting/experimental-alerting-system/rules/configure-rule-query.md + - file: alerting/experimental-alerting-system/rules/configure-rule-severity.md + - file: alerting/experimental-alerting-system/rules/configure-rule-grouping.md + - file: alerting/experimental-alerting-system/rules/configure-rule-schedule.md + - file: alerting/experimental-alerting-system/rules/configure-rule-thresholds.md + - file: alerting/experimental-alerting-system/rules/configure-no-data-handling.md + - file: alerting/experimental-alerting-system/rules/configure-rule-tags.md + - file: alerting/experimental-alerting-system/rules/view-manage-rules.md + - file: alerting/experimental-alerting-system/rules/review-rule-execution-history.md + - file: alerting/experimental-alerting-system/rules/esql-query-patterns.md + children: + - file: alerting/experimental-alerting-system/rules/esql-first-rule-query.md + - file: alerting/experimental-alerting-system/rules/esql-threshold-queries.md + - file: alerting/experimental-alerting-system/rules/esql-no-data-detection.md + - file: alerting/experimental-alerting-system/rules/esql-slo-burn-rate.md + - file: alerting/experimental-alerting-system/rules/esql-persistent-breach.md + - file: alerting/experimental-alerting-system/rules/rule-event-field-reference.md - hidden: alerting/compare-alerting-systems.md - hidden: alerting/system-overview.md - hidden: alerting/experimental-alerting-system/how-it-works.md