[Logs UI] Remove UUID from Alert Instances (#71340)

* [Logs UI] Remove UUID from Alert Instances

* Fix bad template string

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
This commit is contained in:
Zacqary Adam Xeper 2020-07-14 05:55:05 -05:00 committed by GitHub
parent 5ef8d3f509
commit 6c4fc9ca20
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 31 additions and 34 deletions

View file

@ -29,3 +29,5 @@ export const validateIsStringElasticsearchJSONFilter = (value: string) => {
return errorMessage;
}
};
export const UNGROUPED_FACTORY_KEY = '*';

View file

@ -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 };
}
};

View file

@ -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<void>;
@ -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);
});
});

View file

@ -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)) {

View file

@ -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 },

View file

@ -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
}
};