From 3c2101a80bfd28f2171e6ec6f2f0874035378e59 Mon Sep 17 00:00:00 2001 From: Chris Cowan Date: Mon, 15 May 2023 09:28:43 -0600 Subject: [PATCH] Adding ALERT_CONTEXT to Metric Threshold Rule AAD documents --- .../metric_threshold_executor.test.ts.snap | 53 +++++++++++++++++++ .../metric_threshold_executor.test.ts | 11 ++-- .../metric_threshold_executor.ts | 53 ++++++++++++------- 3 files changed, 93 insertions(+), 24 deletions(-) create mode 100644 x-pack/plugins/infra/server/lib/alerting/metric_threshold/__snapshots__/metric_threshold_executor.test.ts.snap diff --git a/x-pack/plugins/infra/server/lib/alerting/metric_threshold/__snapshots__/metric_threshold_executor.test.ts.snap b/x-pack/plugins/infra/server/lib/alerting/metric_threshold/__snapshots__/metric_threshold_executor.test.ts.snap new file mode 100644 index 0000000000000..1fd2c51aec56d --- /dev/null +++ b/x-pack/plugins/infra/server/lib/alerting/metric_threshold/__snapshots__/metric_threshold_executor.test.ts.snap @@ -0,0 +1,53 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`The metric threshold alert type querying with a groupBy parameter sends an alert when all groups pass the threshold 1`] = ` +Object { + "alertDetailsUrl": "http://localhost:5601/app/observability/alerts/mock-alert-uuid", + "alertState": "ALERT", + "group": "a", + "groupByKeys": Object { + "something": "a", + }, + "metric": Object { + "condition0": "test.metric.1", + }, + "reason": "test.metric.1 is 1 in the last 1 min for a. Alert when > 0.75.", + "tags": Array [], + "threshold": Object { + "condition0": Array [ + "0.75", + ], + }, + "timestamp": "2023-05-15T15:27:23.789Z", + "value": Object { + "condition0": "1", + }, + "viewInAppUrl": "http://localhost:5601/app/metrics/explorer", +} +`; + +exports[`The metric threshold alert type querying with a groupBy parameter sends an alert when all groups pass the threshold 2`] = ` +Object { + "alertDetailsUrl": "http://localhost:5601/app/observability/alerts/mock-alert-uuid", + "alertState": "ALERT", + "group": "b", + "groupByKeys": Object { + "something": "b", + }, + "metric": Object { + "condition0": "test.metric.1", + }, + "reason": "test.metric.1 is 1 in the last 1 min for b. Alert when > 0.75.", + "tags": Array [], + "threshold": Object { + "condition0": Array [ + "0.75", + ], + }, + "timestamp": "2023-05-15T15:27:23.789Z", + "value": Object { + "condition0": "1", + }, + "viewInAppUrl": "http://localhost:5601/app/metrics/explorer", +} +`; 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 fb8121d224187..3a3d759f180d2 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 @@ -130,8 +130,7 @@ const setEvaluationResults = (response: Array>) => { jest.requireMock('./lib/evaluate_rule').evaluateRule.mockImplementation(() => response); }; -// FAILING: https://github.com/elastic/kibana/issues/155534 -describe.skip('The metric threshold alert type', () => { +describe('The metric threshold alert type', () => { describe('querying the entire infrastructure', () => { afterAll(() => clearInstances()); const instanceID = '*'; @@ -296,8 +295,12 @@ describe.skip('The metric threshold alert type', () => { }, ]); await execute(Comparator.GT, [0.75]); - expect(mostRecentAction(instanceIdA)).toBeAlertAction(); - expect(mostRecentAction(instanceIdB)).toBeAlertAction(); + const recentActionA = mostRecentAction(instanceIdA); + const recentActionB = mostRecentAction(instanceIdB); + expect(recentActionA).toBeAlertAction(); + expect(recentActionB).toBeAlertAction(); + expect(recentActionA.action).toMatchSnapshot(); + expect(recentActionB.action).toMatchSnapshot(); }); test('sends an alert when only some groups pass the threshold', async () => { setEvaluationResults([ 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 46d2766777d21..73ce0668c7783 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 @@ -6,7 +6,12 @@ */ import { i18n } from '@kbn/i18n'; -import { ALERT_ACTION_GROUP, ALERT_EVALUATION_VALUES, ALERT_REASON } from '@kbn/rule-data-utils'; +import { + ALERT_ACTION_GROUP, + ALERT_CONTEXT, + ALERT_EVALUATION_VALUES, + ALERT_REASON, +} from '@kbn/rule-data-utils'; import { isEqual } from 'lodash'; import { ActionGroupIdsOf, @@ -78,7 +83,8 @@ type MetricThresholdAlertFactory = ( id: string, reason: string, actionGroup: MetricThresholdActionGroup, - additionalContext?: AdditionalContext | null, + alertContext?: AdditionalContext | null, + rootLevelContext?: AdditionalContext | null, evaluationValues?: Array ) => MetricThresholdAlert; @@ -116,7 +122,8 @@ export const createMetricThresholdExecutor = (libs: InfraBackendLibs) => id, reason, actionGroup, - additionalContext, + alertContext, + rootLevelContext, evaluationValues ) => alertWithLifecycle({ @@ -125,7 +132,8 @@ export const createMetricThresholdExecutor = (libs: InfraBackendLibs) => [ALERT_REASON]: reason, [ALERT_ACTION_GROUP]: actionGroup, [ALERT_EVALUATION_VALUES]: evaluationValues, - ...flattenAdditionalContext(additionalContext), + [ALERT_CONTEXT]: alertContext, + ...flattenAdditionalContext(rootLevelContext), }, }); @@ -148,10 +156,8 @@ export const createMetricThresholdExecutor = (libs: InfraBackendLibs) => const timestamp = startedAt.toISOString(); const actionGroupId = FIRED_ACTIONS_ID; // Change this to an Error action group when able const reason = buildInvalidQueryAlertReason(params.filterQueryText); - const alert = alertFactory(UNGROUPED_FACTORY_KEY, reason, actionGroupId); const alertUuid = getAlertUuid(UNGROUPED_FACTORY_KEY); - - alert.scheduleActions(actionGroupId, { + const alertContext = { alertDetailsUrl: getAlertDetailsUrl(libs.basePath, spaceId, alertUuid), alertState: stateToAlertMessage[AlertStates.ERROR], group: UNGROUPED_FACTORY_KEY, @@ -160,7 +166,10 @@ export const createMetricThresholdExecutor = (libs: InfraBackendLibs) => timestamp, value: null, viewInAppUrl: getViewInMetricsAppUrl(libs.basePath, spaceId), - }); + }; + const alert = alertFactory(UNGROUPED_FACTORY_KEY, reason, actionGroupId, alertContext); + + alert.scheduleActions(actionGroupId, alertContext); return { state: { @@ -297,21 +306,14 @@ export const createMetricThresholdExecutor = (libs: InfraBackendLibs) => ); const evaluationValues = alertResults.reduce((acc: Array, result) => { - acc.push(result[group].currentValue); + if (result[group]) { + acc.push(result[group].currentValue); + } return acc; }, []); - const alert = alertFactory( - `${group}`, - reason, - actionGroupId, - additionalContext, - evaluationValues - ); const alertUuid = getAlertUuid(group); - scheduledActionsCount++; - - alert.scheduleActions(actionGroupId, { + const alertContext = { alertDetailsUrl: getAlertDetailsUrl(libs.basePath, spaceId, alertUuid), alertState: stateToAlertMessage[nextState], group, @@ -342,7 +344,18 @@ export const createMetricThresholdExecutor = (libs: InfraBackendLibs) => }), viewInAppUrl: getViewInMetricsAppUrl(libs.basePath, spaceId), ...additionalContext, - }); + }; + + const alert = alertFactory( + `${group}`, + reason, + actionGroupId, + alertContext, + additionalContext, + evaluationValues + ); + scheduledActionsCount++; + alert.scheduleActions(actionGroupId, alertContext); } }