diff --git a/x-pack/plugins/infra/server/lib/alerting/metric_threshold/metric_threshold_executor.test.ts b/x-pack/plugins/infra/server/lib/alerting/metric_threshold/metric_threshold_executor.test.ts index bd9c0afefa3f..d204782957f3 100644 --- a/x-pack/plugins/infra/server/lib/alerting/metric_threshold/metric_threshold_executor.test.ts +++ b/x-pack/plugins/infra/server/lib/alerting/metric_threshold/metric_threshold_executor.test.ts @@ -232,6 +232,50 @@ describe('The metric threshold alert type', () => { ); expect(stateResult3.groups).toEqual(expect.arrayContaining(['a', 'b'])); }); + + const executeWithFilter = ( + comparator: Comparator, + threshold: number[], + filterQuery: string, + metric?: string, + state?: any + ) => + executor({ + ...mockOptions, + services, + params: { + groupBy: ['something'], + criteria: [ + { + ...baseNonCountCriterion, + comparator, + threshold, + metric: metric ?? baseNonCountCriterion.metric, + }, + ], + }, + state: state ?? mockOptions.state.wrapped, + }); + test('persists previous groups that go missing, until the filterQuery param changes', async () => { + const stateResult1 = await executeWithFilter(Comparator.GT, [0.75], 'query', 'test.metric.2'); + expect(stateResult1.groups).toEqual(expect.arrayContaining(['a', 'b', 'c'])); + const stateResult2 = await executeWithFilter( + Comparator.GT, + [0.75], + 'query', + 'test.metric.1', + stateResult1 + ); + expect(stateResult2.groups).toEqual(expect.arrayContaining(['a', 'b', 'c'])); + const stateResult3 = await executeWithFilter( + Comparator.GT, + [0.75], + 'different query', + 'test.metric.1', + stateResult2 + ); + expect(stateResult3.groups).toEqual(expect.arrayContaining(['a', 'b'])); + }); }); describe('querying with multiple criteria', () => { diff --git a/x-pack/plugins/infra/server/lib/alerting/metric_threshold/metric_threshold_executor.ts b/x-pack/plugins/infra/server/lib/alerting/metric_threshold/metric_threshold_executor.ts index e4887e922bb6..0abf4c41e7cc 100644 --- a/x-pack/plugins/infra/server/lib/alerting/metric_threshold/metric_threshold_executor.ts +++ b/x-pack/plugins/infra/server/lib/alerting/metric_threshold/metric_threshold_executor.ts @@ -33,6 +33,7 @@ export type MetricThresholdAlertTypeParams = Record; export type MetricThresholdAlertTypeState = AlertTypeState & { groups: string[]; groupBy?: string | string[]; + filterQuery?: string; }; export type MetricThresholdAlertInstanceState = AlertInstanceState; // no specific instace state used export type MetricThresholdAlertInstanceContext = AlertInstanceContext; // no specific instace state used @@ -94,8 +95,11 @@ export const createMetricThresholdExecutor = (libs: InfraBackendLibs) => const config = source.configuration; const previousGroupBy = state.groupBy; + const previousFilterQuery = state.filterQuery; const prevGroups = - alertOnGroupDisappear && isEqual(previousGroupBy, params.groupBy) + alertOnGroupDisappear && + isEqual(previousGroupBy, params.groupBy) && + isEqual(previousFilterQuery, params.filterQuery) ? // Filter out the * key from the previous groups, only include it if it's one of // the current groups. In case of a groupBy alert that starts out with no data and no // groups, we don't want to persist the existence of the * alert instance @@ -220,7 +224,7 @@ export const createMetricThresholdExecutor = (libs: InfraBackendLibs) => } } - return { groups, groupBy: params.groupBy }; + return { groups, groupBy: params.groupBy, filterQuery: params.filterQuery }; }); export const FIRED_ACTIONS = {