diff --git a/docs/user/alerting/rule-types/es-query.asciidoc b/docs/user/alerting/rule-types/es-query.asciidoc index e3ce35687260f..dba8a4878cb26 100644 --- a/docs/user/alerting/rule-types/es-query.asciidoc +++ b/docs/user/alerting/rule-types/es-query.asciidoc @@ -2,12 +2,17 @@ [[rule-type-es-query]] === {es} query -The {es} query rule type runs a user-configured {es} query, compares the number of matches to a configured threshold, and schedules actions to run when the threshold condition is met. +The {es} query rule type runs a user-configured query, compares the number of +matches to a configured threshold, and schedules actions to run when the +threshold condition is met. + [float] ==== Create the rule -Fill in the <>, then select *{es} query*. +Fill in the <>, then select +*{es} query*. + [float] ==== Define the conditions @@ -17,30 +22,55 @@ Define properties to detect the condition. [role="screenshot"] image::user/alerting/images/rule-types-es-query-conditions.png[Five clauses define the condition to detect] -Index:: This clause requires an *index or data view* and a *time field* that will be used for the *time window*. -Size:: This clause specifies the number of documents to pass to the configured actions when the the threshold condition is met. -{es} query:: This clause specifies the ES DSL query to execute. The number of documents that match this query will be evaluated against the threshold -condition. Aggregations are not supported at this time. -Threshold:: This clause defines a threshold value and a comparison operator (`is above`, `is above or equals`, `is below`, `is below or equals`, or `is between`). The number of documents that match the specified query is compared to this threshold. -Time window:: This clause determines how far back to search for documents, using the *time field* set in the *index* clause. Generally this value should be set to a value higher than the *check every* value in the <>, to avoid gaps in detection. +Index:: Specifies an *index or data view* and a *time field* that is used for +the *time window*. +Size:: Specifies the number of documents to pass to the configured actions when +the threshold condition is met. +{es} query:: Specifies the ES DSL query to execute. The number of documents that +match this query is evaluated against the threshold condition. Only the `query` +field is used, other DSL fields are not considered. +Threshold:: Defines a threshold value and a comparison operator (`is above`, +`is above or equals`, `is below`, `is below or equals`, or `is between`). The +number of documents that match the specified query is compared to this +threshold. +Time window:: Defines how far back to search for documents, using the +*time field* set in the *index* clause. Generally this value should be set to a +value higher than the *check every* value in the +<>, to avoid gaps in +detection. + [float] ==== Add action variables -<> to run when the rule condition is met. The following variables are specific to the {es} query rule. You can also specify <>. +<> to run when the rule condition +is met. The following variables are specific to the {es} query rule. You can +also specify +<>. + +`context.title`:: A preconstructed title for the rule. Example: +`rule term match alert query matched`. -`context.title`:: A preconstructed title for the rule. Example: `rule term match alert query matched`. `context.message`:: A preconstructed message for the rule. Example: + -`rule 'term match alert' is active:` + -`- Value: 42` + -`- Conditions Met: count greater than 4 over 5m` + -`- Timestamp: 2020-01-01T00:00:00.000Z` +`rule 'my es-query' is active:` + +`- Value: 2` + +`- Conditions Met: Number of matching documents is greater than 1 over 5m` + +`- Timestamp: 2022-02-03T20:29:27.732Z` + +`context.group`:: The name of the action group associated with the condition. +Example: `query matched`. + +`context.date`:: The date, in ISO format, that the rule met the condition. +Example: `2022-02-03T20:29:27.732Z`. -`context.group`:: The name of the action group associated with the condition. Example: `query matched`. -`context.date`:: The date, in ISO format, that the rule met the condition. Example: `2020-01-01T00:00:00.000Z`. `context.value`:: The value of the rule that met the condition. -`context.conditions`:: A description of the condition. Example: `count greater than 4`. -`context.hits`:: The most recent ES documents that matched the query. Using the https://mustache.github.io/[Mustache] template array syntax, you can iterate over these hits to get values from the ES documents into your actions. + +`context.conditions`:: A description of the condition. Example: +`count greater than 4`. + +`context.hits`:: The most recent documents that matched the query. Using the +https://mustache.github.io/[Mustache] template array syntax, you can iterate +over these hits to get values from the ES documents into your actions. + [role="screenshot"] image::images/rule-types-es-query-example-action-variable.png[Iterate over hits using Mustache template syntax] @@ -51,8 +81,8 @@ image::images/rule-types-es-query-example-action-variable.png[Iterate over hits Use the *Test query* feature to verify that your query DSL is valid. -* Valid queries are executed against the configured *index* using the configured *time window*. The number of documents that -match the query will be displayed. +* Valid queries are executed against the configured *index* using the configured +*time window*. The number of documents that match the query is displayed. + [role="screenshot"] image::user/alerting/images/rule-types-es-query-valid.png[Test {es} query returns number of matches when valid] @@ -63,29 +93,35 @@ image::user/alerting/images/rule-types-es-query-valid.png[Test {es} query return image::user/alerting/images/rule-types-es-query-invalid.png[Test {es} query shows error when invalid] [float] -==== Match de-duplication +==== Handling multiple matches of the same document + +This rule type checks for duplication of document matches across rule +executions. If you configure the rule with a schedule interval smaller than the +time window, and a document matches a query in multiple rule executions, it is +alerted on only once. -The {es} query rule type performs de-duplication of document matches across rule executions. If you configure the rule with a schedule interval smaller than the time window, and a document matches a query in multiple rule executions, it will be alerted on only once. +The rule uses the timestamp of the matches to avoid alerting on the same match +multiple times. The timestamp of the latest match is used for evaluating the +rule conditions when the rule is executed. Only matches between the latest +timestamp from the previous execution and the actual rule execution are +considered. -Suppose you have a rule configured to run every minute. The rule uses a time window of 1 hour and checks if there are more than 99 matches for the query. The {es} query rule type will do the following: +Suppose you have a rule configured to run every minute. The rule uses a time +window of 1 hour and checks if there are more than 99 matches for the query. The +{es} query rule type does the following: [cols="3*<"] |=== - | `Execution 1 (0:00)` | Rule finds 113 matches in the last hour: `113 > 99` -| Rule is active and user will be alerted. - +| Rule is active and user is alerted. | `Execution 2 (0:01)` -| Rule finds 127 matches in the last hour. 105 of the matches are duplicates that were alerted on in Execution 1, so you actually have 22 matches: `22 !> 99` +| Rule finds 127 matches in the last hour. 105 of the matches are duplicates that were already alerted on previously, so you actually have 22 matches: `22 !> 99` | No alert. - | `Execution 3 (0:02)` -| Rule finds 159 matches in the last hour. 88 of the matches are duplicates that were alerted on in Execution 1, so you actually have 71 matches: `71 !> 99` +| Rule finds 159 matches in the last hour. 88 of the matches are duplicates that were already alerted on previously, so you actually have 71 matches: `71 !> 99` | No alert. - | `Execution 4 (0:03)` -| Rule finds 190 matches in the last hour. 71 of them are duplicates that were alerted on in Exeuction 1, so you actually have 119 matches: `119 > 99` -| Rule is active and user will be alerted. - +| Rule finds 190 matches in the last hour. 71 of them are duplicates that were already alerted on previously, so you actually have 119 matches: `119 > 99` +| Rule is active and user is alerted. |=== \ No newline at end of file diff --git a/examples/embeddable_explorer/public/plugin.tsx b/examples/embeddable_explorer/public/plugin.tsx index 55c2a215e436d..ea8c412e443ee 100644 --- a/examples/embeddable_explorer/public/plugin.tsx +++ b/examples/embeddable_explorer/public/plugin.tsx @@ -34,7 +34,12 @@ export class EmbeddableExplorerPlugin implements Plugin export const MovingAverageAgg = (props) => { const { siblings, fields, indexPattern } = props; + const [model, setModel] = useState({ ...DEFAULTS, ...props.model }); + const onModelChange = useCallback( + (newModel) => { + props.onChange(newModel); + setModel(newModel); + }, + [props] + ); - const model = { ...DEFAULTS, ...props.model }; const modelOptions = [ { label: i18n.translate('visTypeTimeseries.movingAverage.modelOptions.simpleLabel', { @@ -81,7 +88,7 @@ export const MovingAverageAgg = (props) => { }, ]; - const handleChange = createChangeHandler(props.onChange, model); + const handleChange = createChangeHandler(onModelChange, model); const handleSelectChange = createSelectHandler(handleChange); const handleNumberChange = createNumberHandler(handleChange); @@ -188,15 +195,12 @@ export const MovingAverageAgg = (props) => { }) } > - {/* - EUITODO: The following input couldn't be converted to EUI because of type mis-match. - Should it be text or number? - */} - diff --git a/src/plugins/vis_types/timeseries/public/application/components/aggs/serial_diff.js b/src/plugins/vis_types/timeseries/public/application/components/aggs/serial_diff.js index 7bd673e1f8175..e1f26e99d0e84 100644 --- a/src/plugins/vis_types/timeseries/public/application/components/aggs/serial_diff.js +++ b/src/plugins/vis_types/timeseries/public/application/components/aggs/serial_diff.js @@ -22,10 +22,14 @@ import { EuiFormLabel, EuiFormRow, EuiSpacer, + EuiFieldNumber, + EuiIconTip, } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; import { getIndexPatternKey } from '../../../../common/index_patterns_utils'; +const SERIAL_DIFF_DEFAULT_VALUE = 1; + export const SerialDiffAgg = (props) => { const { siblings, fields, indexPattern, model } = props; @@ -85,24 +89,33 @@ export const SerialDiffAgg = (props) => { + />{' '} + + } + type="questionInCircle" + /> + } > - {/* - EUITODO: The following input couldn't be converted to EUI because of type mis-match. - Should it be text or number? - */} - diff --git a/src/plugins/vis_types/timeseries/public/application/components/lib/create_number_handler.ts b/src/plugins/vis_types/timeseries/public/application/components/lib/create_number_handler.ts index 8c46e6ac96f2a..f8ab371d060f1 100644 --- a/src/plugins/vis_types/timeseries/public/application/components/lib/create_number_handler.ts +++ b/src/plugins/vis_types/timeseries/public/application/components/lib/create_number_handler.ts @@ -12,6 +12,12 @@ import { TimeseriesVisParams } from '../../../types'; export const createNumberHandler = ( handleChange: (partialModel: Partial) => void ) => { - return (name: keyof Metric, defaultValue?: string) => (e: React.ChangeEvent) => - handleChange?.({ [name]: Number(e.target.value ?? defaultValue) }); + return (name: keyof Metric, params?: { defaultValue?: string; isClearable?: boolean }) => + (e: React.ChangeEvent) => + handleChange?.({ + [name]: + params?.isClearable && !e.target.value + ? undefined + : Number(e.target.value ?? params?.defaultValue), + }); }; diff --git a/src/plugins/vis_types/timeseries/server/lib/vis_data/helpers/bucket_transform.js b/src/plugins/vis_types/timeseries/server/lib/vis_data/helpers/bucket_transform.js index 13b890189325c..0d5012b11a351 100644 --- a/src/plugins/vis_types/timeseries/server/lib/vis_data/helpers/bucket_transform.js +++ b/src/plugins/vis_types/timeseries/server/lib/vis_data/helpers/bucket_transform.js @@ -192,8 +192,8 @@ export const bucketTransform = { }, }; if (bucket.gap_policy) body.serial_diff.gap_policy = bucket.gap_policy; - if (bucket.lag) { - body.serial_diff.lag = /^([\d]+)$/.test(bucket.lag) ? bucket.lag : 0; + if (bucket.lag && /^([\d]+)$/.test(bucket.lag)) { + body.serial_diff.lag = bucket.lag; } return body; },