diff --git a/x-pack/plugins/infra/server/lib/alerting/common/utils.ts b/x-pack/plugins/infra/server/lib/alerting/common/utils.ts index 100260c49967..27eaeb8eee5a 100644 --- a/x-pack/plugins/infra/server/lib/alerting/common/utils.ts +++ b/x-pack/plugins/infra/server/lib/alerting/common/utils.ts @@ -29,3 +29,5 @@ export const validateIsStringElasticsearchJSONFilter = (value: string) => { return errorMessage; } }; + +export const UNGROUPED_FACTORY_KEY = '*'; diff --git a/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/evaluate_condition.ts b/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/evaluate_condition.ts index 868ea5bfbffe..c991e482a62e 100644 --- a/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/evaluate_condition.ts +++ b/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/evaluate_condition.ts @@ -20,6 +20,7 @@ import { parseFilterQuery } from '../../../utils/serialized_query'; import { InventoryItemType, SnapshotMetricType } from '../../../../common/inventory_models/types'; import { InfraTimerangeInput } from '../../../../common/http_api/snapshot_api'; import { InfraSourceConfiguration } from '../../sources'; +import { UNGROUPED_FACTORY_KEY } from '../common/utils'; type ConditionResult = InventoryMetricConditions & { shouldFire: boolean | boolean[]; @@ -129,14 +130,14 @@ const getData = async ( const causedByType = e.body?.error?.caused_by?.type; if (causedByType === 'too_many_buckets_exception') { return { - '*': { + [UNGROUPED_FACTORY_KEY]: { [TOO_MANY_BUCKETS_PREVIEW_EXCEPTION]: true, maxBuckets: e.body.error.caused_by.max_buckets, }, }; } } - return { '*': undefined }; + return { [UNGROUPED_FACTORY_KEY]: undefined }; } }; diff --git a/x-pack/plugins/infra/server/lib/alerting/log_threshold/log_threshold_executor.test.ts b/x-pack/plugins/infra/server/lib/alerting/log_threshold/log_threshold_executor.test.ts index 4f1e81e0b2c4..940afd72f6c7 100644 --- a/x-pack/plugins/infra/server/lib/alerting/log_threshold/log_threshold_executor.test.ts +++ b/x-pack/plugins/infra/server/lib/alerting/log_threshold/log_threshold_executor.test.ts @@ -54,19 +54,19 @@ services.alertInstanceFactory.mockImplementation((instanceId: string) => { /* * Helper functions */ -function getAlertState(instanceId: string): AlertStates { - const alert = alertInstances.get(`${instanceId}-*`); +function getAlertState(): AlertStates { + const alert = alertInstances.get('*'); if (alert) { return alert.state.alertState; } else { - throw new Error('Could not find alert instance `' + instanceId + '`'); + throw new Error('Could not find alert instance'); } } /* * Executor instance (our test subject) */ -const executor = (createLogThresholdExecutor('test', libsMock) as unknown) as (opts: { +const executor = (createLogThresholdExecutor(libsMock) as unknown) as (opts: { params: LogDocumentCountAlertParams; services: { callCluster: AlertExecutorOptions['params']['callCluster'] }; }) => Promise; @@ -109,30 +109,30 @@ describe('Ungrouped alerts', () => { describe('Comparators trigger alerts correctly', () => { it('does not alert when counts do not reach the threshold', async () => { await callExecutor([0, Comparator.GT, 1]); - expect(getAlertState('test')).toBe(AlertStates.OK); + expect(getAlertState()).toBe(AlertStates.OK); await callExecutor([0, Comparator.GT_OR_EQ, 1]); - expect(getAlertState('test')).toBe(AlertStates.OK); + expect(getAlertState()).toBe(AlertStates.OK); await callExecutor([1, Comparator.LT, 0]); - expect(getAlertState('test')).toBe(AlertStates.OK); + expect(getAlertState()).toBe(AlertStates.OK); await callExecutor([1, Comparator.LT_OR_EQ, 0]); - expect(getAlertState('test')).toBe(AlertStates.OK); + expect(getAlertState()).toBe(AlertStates.OK); }); it('alerts when counts reach the threshold', async () => { await callExecutor([2, Comparator.GT, 1]); - expect(getAlertState('test')).toBe(AlertStates.ALERT); + expect(getAlertState()).toBe(AlertStates.ALERT); await callExecutor([1, Comparator.GT_OR_EQ, 1]); - expect(getAlertState('test')).toBe(AlertStates.ALERT); + expect(getAlertState()).toBe(AlertStates.ALERT); await callExecutor([1, Comparator.LT, 2]); - expect(getAlertState('test')).toBe(AlertStates.ALERT); + expect(getAlertState()).toBe(AlertStates.ALERT); await callExecutor([2, Comparator.LT_OR_EQ, 2]); - expect(getAlertState('test')).toBe(AlertStates.ALERT); + expect(getAlertState()).toBe(AlertStates.ALERT); }); }); diff --git a/x-pack/plugins/infra/server/lib/alerting/log_threshold/log_threshold_executor.ts b/x-pack/plugins/infra/server/lib/alerting/log_threshold/log_threshold_executor.ts index a2fd01f85938..85bb18e19919 100644 --- a/x-pack/plugins/infra/server/lib/alerting/log_threshold/log_threshold_executor.ts +++ b/x-pack/plugins/infra/server/lib/alerting/log_threshold/log_threshold_executor.ts @@ -21,8 +21,8 @@ import { InfraBackendLibs } from '../../infra_types'; import { getIntervalInSeconds } from '../../../utils/get_interval_in_seconds'; import { InfraSource } from '../../../../common/http_api/source_api'; import { decodeOrThrow } from '../../../../common/runtime_types'; +import { UNGROUPED_FACTORY_KEY } from '../common/utils'; -const UNGROUPED_FACTORY_KEY = '*'; const COMPOSITE_GROUP_SIZE = 40; const checkValueAgainstComparatorMap: { @@ -34,7 +34,7 @@ const checkValueAgainstComparatorMap: { [Comparator.LT_OR_EQ]: (a: number, b: number) => a <= b, }; -export const createLogThresholdExecutor = (alertId: string, libs: InfraBackendLibs) => +export const createLogThresholdExecutor = (libs: InfraBackendLibs) => async function ({ services, params }: AlertExecutorOptions) { const { alertInstanceFactory, savedObjectsClient, callCluster } = services; const { sources } = libs; @@ -42,7 +42,7 @@ export const createLogThresholdExecutor = (alertId: string, libs: InfraBackendLi const sourceConfiguration = await sources.getSourceConfiguration(savedObjectsClient, 'default'); const indexPattern = sourceConfiguration.configuration.logAlias; - const alertInstance = alertInstanceFactory(alertId); + const alertInstance = alertInstanceFactory(UNGROUPED_FACTORY_KEY); try { const validatedParams = decodeOrThrow(LogDocumentCountAlertParamsRT)(params); @@ -60,15 +60,13 @@ export const createLogThresholdExecutor = (alertId: string, libs: InfraBackendLi processGroupByResults( await getGroupedResults(query, callCluster), validatedParams, - alertInstanceFactory, - alertId + alertInstanceFactory ); } else { processUngroupedResults( await getUngroupedResults(query, callCluster), validatedParams, - alertInstanceFactory, - alertId + alertInstanceFactory ); } } catch (e) { @@ -83,12 +81,11 @@ export const createLogThresholdExecutor = (alertId: string, libs: InfraBackendLi const processUngroupedResults = ( results: UngroupedSearchQueryResponse, params: LogDocumentCountAlertParams, - alertInstanceFactory: AlertExecutorOptions['services']['alertInstanceFactory'], - alertId: string + alertInstanceFactory: AlertExecutorOptions['services']['alertInstanceFactory'] ) => { const { count, criteria } = params; - const alertInstance = alertInstanceFactory(`${alertId}-${UNGROUPED_FACTORY_KEY}`); + const alertInstance = alertInstanceFactory(UNGROUPED_FACTORY_KEY); const documentCount = results.hits.total.value; if (checkValueAgainstComparatorMap[count.comparator](documentCount, count.value)) { @@ -116,8 +113,7 @@ interface ReducedGroupByResults { const processGroupByResults = ( results: GroupedSearchQueryResponse['aggregations']['groups']['buckets'], params: LogDocumentCountAlertParams, - alertInstanceFactory: AlertExecutorOptions['services']['alertInstanceFactory'], - alertId: string + alertInstanceFactory: AlertExecutorOptions['services']['alertInstanceFactory'] ) => { const { count, criteria } = params; @@ -128,7 +124,7 @@ const processGroupByResults = ( }, []); groupResults.forEach((group) => { - const alertInstance = alertInstanceFactory(`${alertId}-${group.name}`); + const alertInstance = alertInstanceFactory(group.name); const documentCount = group.documentCount; if (checkValueAgainstComparatorMap[count.comparator](documentCount, count.value)) { diff --git a/x-pack/plugins/infra/server/lib/alerting/log_threshold/register_log_threshold_alert_type.ts b/x-pack/plugins/infra/server/lib/alerting/log_threshold/register_log_threshold_alert_type.ts index 43c298019b63..fbbb38da5392 100644 --- a/x-pack/plugins/infra/server/lib/alerting/log_threshold/register_log_threshold_alert_type.ts +++ b/x-pack/plugins/infra/server/lib/alerting/log_threshold/register_log_threshold_alert_type.ts @@ -3,7 +3,6 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import uuid from 'uuid'; import { i18n } from '@kbn/i18n'; import { schema } from '@kbn/config-schema'; import { PluginSetupContract } from '../../../../../alerts/server'; @@ -71,8 +70,6 @@ export async function registerLogThresholdAlertType( ); } - const alertUUID = uuid.v4(); - alertingPlugin.registerType({ id: LOG_DOCUMENT_COUNT_ALERT_TYPE_ID, name: 'Log threshold', @@ -87,7 +84,7 @@ export async function registerLogThresholdAlertType( }, defaultActionGroupId: FIRED_ACTIONS.id, actionGroups: [FIRED_ACTIONS], - executor: createLogThresholdExecutor(alertUUID, libs), + executor: createLogThresholdExecutor(libs), actionVariables: { context: [ { name: 'matchingDocuments', description: documentCountActionVariableDescription }, diff --git a/x-pack/plugins/infra/server/lib/alerting/metric_threshold/lib/evaluate_alert.ts b/x-pack/plugins/infra/server/lib/alerting/metric_threshold/lib/evaluate_alert.ts index 7f6bf9551e2c..d862f70c47ca 100644 --- a/x-pack/plugins/infra/server/lib/alerting/metric_threshold/lib/evaluate_alert.ts +++ b/x-pack/plugins/infra/server/lib/alerting/metric_threshold/lib/evaluate_alert.ts @@ -15,6 +15,7 @@ import { createAfterKeyHandler } from '../../../../utils/create_afterkey_handler import { AlertServices, AlertExecutorOptions } from '../../../../../../alerts/server'; import { getAllCompositeData } from '../../../../utils/get_all_composite_data'; import { DOCUMENT_COUNT_I18N } from '../../common/messages'; +import { UNGROUPED_FACTORY_KEY } from '../../common/utils'; import { MetricExpressionParams, Comparator, Aggregators } from '../types'; import { getElasticsearchMetricQuery } from './metric_query'; @@ -133,21 +134,21 @@ const getMetric: ( index, }); - return { '*': getValuesFromAggregations(result.aggregations, aggType) }; + return { [UNGROUPED_FACTORY_KEY]: getValuesFromAggregations(result.aggregations, aggType) }; } catch (e) { if (timeframe) { // This code should only ever be reached when previewing the alert, not executing it const causedByType = e.body?.error?.caused_by?.type; if (causedByType === 'too_many_buckets_exception') { return { - '*': { + [UNGROUPED_FACTORY_KEY]: { [TOO_MANY_BUCKETS_PREVIEW_EXCEPTION]: true, maxBuckets: e.body.error.caused_by.max_buckets, }, }; } } - return { '*': NaN }; // Trigger an Error state + return { [UNGROUPED_FACTORY_KEY]: NaN }; // Trigger an Error state } };