Skip to content

Commit

Permalink
[Logs UI] Remove UUID from Alert Instances (#71340)
Browse files Browse the repository at this point in the history
* [Logs UI] Remove UUID from Alert Instances

* Fix bad template string

Co-authored-by: Elastic Machine <[email protected]>
  • Loading branch information
Zacqary and elasticmachine authored Jul 14, 2020
1 parent 5ef8d3f commit 6c4fc9c
Show file tree
Hide file tree
Showing 6 changed files with 31 additions and 34 deletions.
2 changes: 2 additions & 0 deletions x-pack/plugins/infra/server/lib/alerting/common/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,5 @@ export const validateIsStringElasticsearchJSONFilter = (value: string) => {
return errorMessage;
}
};

export const UNGROUPED_FACTORY_KEY = '*';
Original file line number Diff line number Diff line change
Expand Up @@ -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[];
Expand Down Expand Up @@ -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 };
}
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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>;
Expand Down Expand Up @@ -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);
});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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: {
Expand All @@ -34,15 +34,15 @@ 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;
const { groupBy } = params;

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);
Expand All @@ -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) {
Expand All @@ -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)) {
Expand Down Expand Up @@ -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;

Expand All @@ -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)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -71,8 +70,6 @@ export async function registerLogThresholdAlertType(
);
}

const alertUUID = uuid.v4();

alertingPlugin.registerType({
id: LOG_DOCUMENT_COUNT_ALERT_TYPE_ID,
name: 'Log threshold',
Expand All @@ -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 },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand Down Expand Up @@ -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
}
};

Expand Down

0 comments on commit 6c4fc9c

Please sign in to comment.