[Alerting UI] Updating defaultActionMessage for Index Threshold Alert (#83934) (#84162)

* Renaming function to conditions

* Making comparators human readable. Tests

* i18n fix

* Fixing tests

* Fixing tests

* i18n fix

* PR comments
# Conflicts:
#	x-pack/plugins/translations/translations/ja-JP.json
#	x-pack/plugins/translations/translations/zh-CN.json
This commit is contained in:
ymao1 2020-11-23 19:26:13 -05:00 committed by GitHub
parent cfe312aa9a
commit 6b686e2ef8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 1137 additions and 1097 deletions

View file

@ -27,7 +27,11 @@ export function getAlertType(): AlertTypeModel<IndexThresholdAlertParams, Alerts
defaultActionMessage: i18n.translate(
'xpack.stackAlerts.threshold.ui.alertType.defaultActionMessage',
{
defaultMessage: `alert \\{\\{alertName\\}\\} group \\{\\{context.group\\}\\} value \\{\\{context.value\\}\\} exceeded threshold \\{\\{context.function\\}\\} over \\{\\{params.timeWindowSize\\}\\}\\{\\{params.timeWindowUnit\\}\\} on \\{\\{context.date\\}\\}`,
defaultMessage: `alert '\\{\\{alertName\\}\\}' is active for group '\\{\\{context.group\\}\\}':
- Value: \\{\\{context.value\\}\\}
- Conditions Met: \\{\\{context.conditions\\}\\} over \\{\\{params.timeWindowSize\\}\\}\\{\\{params.timeWindowUnit\\}\\}
- Timestamp: \\{\\{context.date\\}\\}`,
}
),
requiresAppContext: false,

View file

@ -25,14 +25,16 @@ describe('ActionContext', () => {
date: '2020-01-01T00:00:00.000Z',
group: '[group]',
value: 42,
function: 'count > 4',
conditions: 'count greater than 4',
};
const context = addMessages({ name: '[alert-name]' }, base, params);
expect(context.title).toMatchInlineSnapshot(
`"alert [alert-name] group [group] exceeded threshold"`
);
expect(context.message).toMatchInlineSnapshot(
`"alert [alert-name] group [group] value 42 exceeded threshold count > 4 over 5m on 2020-01-01T00:00:00.000Z"`
expect(context.title).toMatchInlineSnapshot(`"alert [alert-name] group [group] met threshold"`);
expect(context.message).toEqual(
`alert '[alert-name]' is active for group '[group]':
- Value: 42
- Conditions Met: count greater than 4 over 5m
- Timestamp: 2020-01-01T00:00:00.000Z`
);
});
@ -54,14 +56,16 @@ describe('ActionContext', () => {
date: '2020-01-01T00:00:00.000Z',
group: '[group]',
value: 42,
function: 'avg([aggField]) > 4.2',
conditions: 'avg([aggField]) greater than 4.2',
};
const context = addMessages({ name: '[alert-name]' }, base, params);
expect(context.title).toMatchInlineSnapshot(
`"alert [alert-name] group [group] exceeded threshold"`
);
expect(context.message).toMatchInlineSnapshot(
`"alert [alert-name] group [group] value 42 exceeded threshold avg([aggField]) > 4.2 over 5m on 2020-01-01T00:00:00.000Z"`
expect(context.title).toMatchInlineSnapshot(`"alert [alert-name] group [group] met threshold"`);
expect(context.message).toEqual(
`alert '[alert-name]' is active for group '[group]':
- Value: 42
- Conditions Met: avg([aggField]) greater than 4.2 over 5m
- Timestamp: 2020-01-01T00:00:00.000Z`
);
});
@ -82,14 +86,16 @@ describe('ActionContext', () => {
date: '2020-01-01T00:00:00.000Z',
group: '[group]',
value: 4,
function: 'count between 4,5',
conditions: 'count between 4 and 5',
};
const context = addMessages({ name: '[alert-name]' }, base, params);
expect(context.title).toMatchInlineSnapshot(
`"alert [alert-name] group [group] exceeded threshold"`
);
expect(context.message).toMatchInlineSnapshot(
`"alert [alert-name] group [group] value 4 exceeded threshold count between 4,5 over 5m on 2020-01-01T00:00:00.000Z"`
expect(context.title).toMatchInlineSnapshot(`"alert [alert-name] group [group] met threshold"`);
expect(context.message).toEqual(
`alert '[alert-name]' is active for group '[group]':
- Value: 4
- Conditions Met: count between 4 and 5 over 5m
- Timestamp: 2020-01-01T00:00:00.000Z`
);
});
});

View file

@ -27,8 +27,8 @@ export interface BaseActionContext extends AlertInstanceContext {
date: string;
// the value that met the threshold
value: number;
// the function that is used
function: string;
// threshold conditions
conditions: string;
}
export function addMessages(
@ -37,7 +37,7 @@ export function addMessages(
params: Params
): ActionContext {
const title = i18n.translate('xpack.stackAlerts.indexThreshold.alertTypeContextSubjectTitle', {
defaultMessage: 'alert {name} group {group} exceeded threshold',
defaultMessage: 'alert {name} group {group} met threshold',
values: {
name: alertInfo.name,
group: baseContext.group,
@ -48,13 +48,16 @@ export function addMessages(
const message = i18n.translate(
'xpack.stackAlerts.indexThreshold.alertTypeContextMessageDescription',
{
defaultMessage:
'alert {name} group {group} value {value} exceeded threshold {function} over {window} on {date}',
defaultMessage: `alert '{name}' is active for group '{group}':
- Value: {value}
- Conditions Met: {conditions} over {window}
- Timestamp: {date}`,
values: {
name: alertInfo.name,
group: baseContext.group,
value: baseContext.value,
function: baseContext.function,
conditions: baseContext.conditions,
window,
date: baseContext.date,
},

View file

@ -46,7 +46,7 @@ describe('alertType', () => {
},
Object {
"description": "A string describing the threshold comparator and threshold",
"name": "function",
"name": "conditions",
},
],
"params": Array [

View file

@ -17,6 +17,24 @@ import {
export const ID = '.index-threshold';
enum Comparator {
GT = '>',
LT = '<',
GT_OR_EQ = '>=',
LT_OR_EQ = '<=',
BETWEEN = 'between',
NOT_BETWEEN = 'notBetween',
}
const humanReadableComparators = new Map<string, string>([
[Comparator.LT, 'less than'],
[Comparator.LT_OR_EQ, 'less than or equal to'],
[Comparator.GT_OR_EQ, 'greater than or equal to'],
[Comparator.GT, 'greater than'],
[Comparator.BETWEEN, 'between'],
[Comparator.NOT_BETWEEN, 'not between'],
]);
const ActionGroupId = 'threshold met';
const ComparatorFns = getComparatorFns();
export const ComparatorFnNames = new Set(ComparatorFns.keys());
@ -86,8 +104,8 @@ export function getAlertType(
}
);
const actionVariableContextFunctionLabel = i18n.translate(
'xpack.stackAlerts.indexThreshold.actionVariableContextFunctionLabel',
const actionVariableContextConditionsLabel = i18n.translate(
'xpack.stackAlerts.indexThreshold.actionVariableContextConditionsLabel',
{
defaultMessage: 'A string describing the threshold comparator and threshold',
}
@ -117,7 +135,7 @@ export function getAlertType(
{ name: 'group', description: actionVariableContextGroupLabel },
{ name: 'date', description: actionVariableContextDateLabel },
{ name: 'value', description: actionVariableContextValueLabel },
{ name: 'function', description: actionVariableContextFunctionLabel },
{ name: 'conditions', description: actionVariableContextConditionsLabel },
],
params: [
{ name: 'threshold', description: actionVariableContextThresholdLabel },
@ -172,13 +190,15 @@ export function getAlertType(
if (!met) continue;
const agg = params.aggField ? `${params.aggType}(${params.aggField})` : `${params.aggType}`;
const humanFn = `${agg} ${params.thresholdComparator} ${params.threshold.join(',')}`;
const humanFn = `${agg} is ${getHumanReadableComparator(
params.thresholdComparator
)} ${params.threshold.join(' and ')}`;
const baseContext: BaseActionContext = {
date,
group: instanceId,
value,
function: humanFn,
conditions: humanFn,
};
const actionContext = addMessages(options, baseContext, params);
const alertInstance = options.services.alertInstanceFactory(instanceId);
@ -201,12 +221,13 @@ type ComparatorFn = (value: number, threshold: number[]) => boolean;
function getComparatorFns(): Map<string, ComparatorFn> {
const fns: Record<string, ComparatorFn> = {
'<': (value: number, threshold: number[]) => value < threshold[0],
'<=': (value: number, threshold: number[]) => value <= threshold[0],
'>=': (value: number, threshold: number[]) => value >= threshold[0],
'>': (value: number, threshold: number[]) => value > threshold[0],
between: (value: number, threshold: number[]) => value >= threshold[0] && value <= threshold[1],
notBetween: (value: number, threshold: number[]) =>
[Comparator.LT]: (value: number, threshold: number[]) => value < threshold[0],
[Comparator.LT_OR_EQ]: (value: number, threshold: number[]) => value <= threshold[0],
[Comparator.GT_OR_EQ]: (value: number, threshold: number[]) => value >= threshold[0],
[Comparator.GT]: (value: number, threshold: number[]) => value > threshold[0],
[Comparator.BETWEEN]: (value: number, threshold: number[]) =>
value >= threshold[0] && value <= threshold[1],
[Comparator.NOT_BETWEEN]: (value: number, threshold: number[]) =>
value < threshold[0] || value > threshold[1],
};
@ -217,3 +238,9 @@ function getComparatorFns(): Map<string, ComparatorFn> {
return result;
}
function getHumanReadableComparator(comparator: string) {
return humanReadableComparators.has(comparator)
? humanReadableComparators.get(comparator)
: comparator;
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -26,8 +26,6 @@ const ALERT_INTERVALS_TO_WRITE = 5;
const ALERT_INTERVAL_SECONDS = 3;
const ALERT_INTERVAL_MILLIS = ALERT_INTERVAL_SECONDS * 1000;
const DefaultActionMessage = `alert {{alertName}} group {{context.group}} value {{context.value}} exceeded threshold {{context.function}} over {{params.timeWindowSize}}{{params.timeWindowUnit}} on {{context.date}}`;
// eslint-disable-next-line import/no-default-export
export default function alertTests({ getService }: FtrProviderContext) {
const supertest = getService('supertest');
@ -93,9 +91,9 @@ export default function alertTests({ getService }: FtrProviderContext) {
expect(group).to.be('all documents');
// we'll check title and message in this test, but not subsequent ones
expect(title).to.be('alert always fire group all documents exceeded threshold');
expect(title).to.be('alert always fire group all documents met threshold');
const messagePattern = /alert always fire group all documents value \d+ exceeded threshold count &gt; -1 over 15s on \d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z/;
const messagePattern = /alert 'always fire' is active for group \'all documents\':\n\n- Value: \d+\n- Conditions Met: count is greater than -1 over 15s\n- Timestamp: \d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z/;
expect(message).to.match(messagePattern);
}
});
@ -134,7 +132,7 @@ export default function alertTests({ getService }: FtrProviderContext) {
expect(name).to.be('always fire');
if (group === 'group-0') inGroup0++;
const messagePattern = /alert always fire group group-\d value \d+ exceeded threshold count .+ over 15s on \d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z/;
const messagePattern = /alert 'always fire' is active for group \'group-\d\':\n\n- Value: \d+\n- Conditions Met: count is greater than or equal to 0 over 15s\n- Timestamp: \d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z/;
expect(message).to.match(messagePattern);
}
@ -171,7 +169,7 @@ export default function alertTests({ getService }: FtrProviderContext) {
expect(name).to.be('always fire');
const messagePattern = /alert always fire group all documents value \d+ exceeded threshold sum\(testedValue\) between 0,1000000 over 15s on \d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z/;
const messagePattern = /alert 'always fire' is active for group \'all documents\':\n\n- Value: \d+\n- Conditions Met: sum\(testedValue\) is between 0 and 1000000 over 15s\n- Timestamp: \d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z/;
expect(message).to.match(messagePattern);
}
});
@ -206,7 +204,7 @@ export default function alertTests({ getService }: FtrProviderContext) {
expect(name).to.be('always fire');
const messagePattern = /alert always fire group all documents value .+ exceeded threshold avg\(testedValue\) .+ 0 over 15s on \d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z/;
const messagePattern = /alert 'always fire' is active for group \'all documents\':\n\n- Value: .*\n- Conditions Met: avg\(testedValue\) is greater than or equal to 0 over 15s\n- Timestamp: \d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z/;
expect(message).to.match(messagePattern);
}
});
@ -247,7 +245,7 @@ export default function alertTests({ getService }: FtrProviderContext) {
expect(name).to.be('always fire');
if (group === 'group-2') inGroup2++;
const messagePattern = /alert always fire group group-. value \d+ exceeded threshold max\(testedValue\) .* 0 over 15s on \d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z/;
const messagePattern = /alert 'always fire' is active for group \'group-\d\':\n\n- Value: \d+\n- Conditions Met: max\(testedValue\) is greater than or equal to 0 over 15s\n- Timestamp: \d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z/;
expect(message).to.match(messagePattern);
}
@ -292,7 +290,7 @@ export default function alertTests({ getService }: FtrProviderContext) {
expect(name).to.be('always fire');
if (group === 'group-0') inGroup0++;
const messagePattern = /alert always fire group group-. value \d+ exceeded threshold min\(testedValue\) .* 0 over 15s on \d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z/;
const messagePattern = /alert 'always fire' is active for group \'group-\d\':\n\n- Value: \d+\n- Conditions Met: min\(testedValue\) is greater than or equal to 0 over 15s\n- Timestamp: \d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z/;
expect(message).to.match(messagePattern);
}
@ -345,7 +343,7 @@ export default function alertTests({ getService }: FtrProviderContext) {
name: '{{{alertName}}}',
value: '{{{context.value}}}',
title: '{{{context.title}}}',
message: DefaultActionMessage,
message: '{{{context.message}}}',
},
date: '{{{context.date}}}',
// TODO: I wanted to write the alert value here, but how?

View file

@ -81,7 +81,11 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
expect(createdConnectorToastTitle).to.eql(`Created '${slackConnectorName}'`);
const messageTextArea = await find.byCssSelector('[data-test-subj="messageTextArea"]');
expect(await messageTextArea.getAttribute('value')).to.eql(
'alert {{alertName}} group {{context.group}} value {{context.value}} exceeded threshold {{context.function}} over {{params.timeWindowSize}}{{params.timeWindowUnit}} on {{context.date}}'
`alert '{{alertName}}' is active for group '{{context.group}}':
- Value: {{context.value}}
- Conditions Met: {{context.conditions}} over {{params.timeWindowSize}}{{params.timeWindowUnit}}
- Timestamp: {{context.date}}`
);
await testSubjects.setValue('messageTextArea', 'test message ');
await testSubjects.click('messageAddVariableButton');