diff --git a/x-pack/plugins/infra/server/lib/alerting/metric_threshold/register_metric_threshold_alert_type.ts b/x-pack/plugins/infra/server/lib/alerting/metric_threshold/register_metric_threshold_alert_type.ts index 9bc54c1a49c8f..2d7c7cb12b690 100644 --- a/x-pack/plugins/infra/server/lib/alerting/metric_threshold/register_metric_threshold_alert_type.ts +++ b/x-pack/plugins/infra/server/lib/alerting/metric_threshold/register_metric_threshold_alert_type.ts @@ -7,7 +7,7 @@ import uuid from 'uuid'; import { i18n } from '@kbn/i18n'; import { schema } from '@kbn/config-schema'; import { - MetricThresholdAlertTypeParams, + MetricExpressionParams, Comparator, AlertStates, METRIC_THRESHOLD_ALERT_TYPE_ID, @@ -23,7 +23,7 @@ const FIRED_ACTIONS = { async function getMetric( { callCluster }: AlertServices, - { metric, aggType, timeUnit, timeSize, indexPattern }: MetricThresholdAlertTypeParams + { metric, aggType, timeUnit, timeSize, indexPattern }: MetricExpressionParams ) { const interval = `${timeSize}${timeUnit}`; const searchBody = { @@ -95,37 +95,49 @@ export async function registerMetricThresholdAlertType(alertingPlugin: PluginSet name: 'Metric Alert - Threshold', validate: { params: schema.object({ - threshold: schema.arrayOf(schema.number()), - comparator: schema.string(), - aggType: schema.string(), - metric: schema.string(), - timeUnit: schema.string(), - timeSize: schema.number(), - indexPattern: schema.string(), + criteria: schema.arrayOf( + schema.object({ + threshold: schema.arrayOf(schema.number()), + comparator: schema.string(), + aggType: schema.string(), + metric: schema.string(), + timeUnit: schema.string(), + timeSize: schema.number(), + indexPattern: schema.string(), + }) + ), }), }, defaultActionGroupId: FIRED_ACTIONS.id, actionGroups: [FIRED_ACTIONS], async executor({ services, params }) { - const { threshold, comparator } = params as MetricThresholdAlertTypeParams; + const { criteria } = params as { criteria: MetricExpressionParams[] }; const alertInstance = services.alertInstanceFactory(alertUUID); - const currentValue = await getMetric(services, params as MetricThresholdAlertTypeParams); - if (typeof currentValue === 'undefined') - throw new Error('Could not get current value of metric'); - const comparisonFunction = comparatorMap[comparator]; + const alertResults = await Promise.all( + criteria.map(({ threshold, comparator }) => + (async () => { + const currentValue = await getMetric(services, params as MetricExpressionParams); + if (typeof currentValue === 'undefined') + throw new Error('Could not get current value of metric'); - const isValueInAlertState = comparisonFunction(currentValue, threshold); + const comparisonFunction = comparatorMap[comparator]; + return { shouldFire: comparisonFunction(currentValue, threshold), currentValue }; + })() + ) + ); - if (isValueInAlertState) { + const shouldAlertFire = alertResults.every(({ shouldFire }) => shouldFire); + + if (shouldAlertFire) { alertInstance.scheduleActions(FIRED_ACTIONS.id, { - value: currentValue, + value: alertResults.map(({ currentValue }) => currentValue), }); } // Future use: ability to fetch display current alert state alertInstance.replaceState({ - alertState: isValueInAlertState ? AlertStates.ALERT : AlertStates.OK, + alertState: shouldAlertFire ? AlertStates.ALERT : AlertStates.OK, }); }, }); diff --git a/x-pack/plugins/infra/server/lib/alerting/metric_threshold/types.ts b/x-pack/plugins/infra/server/lib/alerting/metric_threshold/types.ts index 2618469ff693c..9bb0d8963ac66 100644 --- a/x-pack/plugins/infra/server/lib/alerting/metric_threshold/types.ts +++ b/x-pack/plugins/infra/server/lib/alerting/metric_threshold/types.ts @@ -23,7 +23,7 @@ export enum AlertStates { export type TimeUnit = 's' | 'm' | 'h' | 'd'; -export interface MetricThresholdAlertTypeParams { +export interface MetricExpressionParams { aggType: MetricsExplorerAggregation; metric: string; timeSize: number;