Added defaultActionMessage
to index threshold alert UI type definition (#80936)
* resolves https://github.com/elastic/kibana/issues/78148 Adds a `defaultActionMessage` to the index threshold alert, so that the `message` parameter for actions will be pre-filled with a useful message
This commit is contained in:
parent
f2f76e104a
commit
c78cf35ba8
|
@ -25,6 +25,7 @@ describe('ActionContext', () => {
|
|||
date: '2020-01-01T00:00:00.000Z',
|
||||
group: '[group]',
|
||||
value: 42,
|
||||
function: 'count > 4',
|
||||
};
|
||||
const context = addMessages({ name: '[alert-name]' }, base, params);
|
||||
expect(context.title).toMatchInlineSnapshot(
|
||||
|
@ -53,6 +54,7 @@ describe('ActionContext', () => {
|
|||
date: '2020-01-01T00:00:00.000Z',
|
||||
group: '[group]',
|
||||
value: 42,
|
||||
function: 'avg([aggField]) > 4.2',
|
||||
};
|
||||
const context = addMessages({ name: '[alert-name]' }, base, params);
|
||||
expect(context.title).toMatchInlineSnapshot(
|
||||
|
@ -80,6 +82,7 @@ describe('ActionContext', () => {
|
|||
date: '2020-01-01T00:00:00.000Z',
|
||||
group: '[group]',
|
||||
value: 4,
|
||||
function: 'count between 4,5',
|
||||
};
|
||||
const context = addMessages({ name: '[alert-name]' }, base, params);
|
||||
expect(context.title).toMatchInlineSnapshot(
|
||||
|
|
|
@ -27,6 +27,8 @@ export interface BaseActionContext extends AlertInstanceContext {
|
|||
date: string;
|
||||
// the value that met the threshold
|
||||
value: number;
|
||||
// the function that is used
|
||||
function: string;
|
||||
}
|
||||
|
||||
export function addMessages(
|
||||
|
@ -42,9 +44,6 @@ export function addMessages(
|
|||
},
|
||||
});
|
||||
|
||||
const agg = params.aggField ? `${params.aggType}(${params.aggField})` : `${params.aggType}`;
|
||||
const humanFn = `${agg} ${params.thresholdComparator} ${params.threshold.join(',')}`;
|
||||
|
||||
const window = `${params.timeWindowSize}${params.timeWindowUnit}`;
|
||||
const message = i18n.translate(
|
||||
'xpack.stackAlerts.indexThreshold.alertTypeContextMessageDescription',
|
||||
|
@ -55,7 +54,7 @@ export function addMessages(
|
|||
name: alertInfo.name,
|
||||
group: baseContext.group,
|
||||
value: baseContext.value,
|
||||
function: humanFn,
|
||||
function: baseContext.function,
|
||||
window,
|
||||
date: baseContext.date,
|
||||
},
|
||||
|
|
|
@ -46,6 +46,10 @@ describe('alertType', () => {
|
|||
"description": "The value that exceeded the threshold.",
|
||||
"name": "value",
|
||||
},
|
||||
Object {
|
||||
"description": "A string describing the threshold comparator and threshold",
|
||||
"name": "function",
|
||||
},
|
||||
],
|
||||
"params": Array [
|
||||
Object {
|
||||
|
|
|
@ -83,6 +83,13 @@ export function getAlertType(service: Service): AlertType<Params, {}, {}, Action
|
|||
}
|
||||
);
|
||||
|
||||
const actionVariableContextFunctionLabel = i18n.translate(
|
||||
'xpack.stackAlerts.indexThreshold.actionVariableContextFunctionLabel',
|
||||
{
|
||||
defaultMessage: 'A string describing the threshold comparator and threshold',
|
||||
}
|
||||
);
|
||||
|
||||
const alertParamsVariables = Object.keys(CoreQueryParamsSchemaProperties).map(
|
||||
(propKey: string) => {
|
||||
return {
|
||||
|
@ -107,6 +114,7 @@ export function getAlertType(service: Service): AlertType<Params, {}, {}, Action
|
|||
{ name: 'group', description: actionVariableContextGroupLabel },
|
||||
{ name: 'date', description: actionVariableContextDateLabel },
|
||||
{ name: 'value', description: actionVariableContextValueLabel },
|
||||
{ name: 'function', description: actionVariableContextFunctionLabel },
|
||||
],
|
||||
params: [
|
||||
{ name: 'threshold', description: actionVariableContextThresholdLabel },
|
||||
|
@ -160,10 +168,14 @@ export function getAlertType(service: Service): AlertType<Params, {}, {}, Action
|
|||
|
||||
if (!met) continue;
|
||||
|
||||
const agg = params.aggField ? `${params.aggType}(${params.aggField})` : `${params.aggType}`;
|
||||
const humanFn = `${agg} ${params.thresholdComparator} ${params.threshold.join(',')}`;
|
||||
|
||||
const baseContext: BaseActionContext = {
|
||||
date,
|
||||
group: instanceId,
|
||||
value,
|
||||
function: humanFn,
|
||||
};
|
||||
const actionContext = addMessages(options, baseContext, params);
|
||||
const alertInstance = options.services.alertInstanceFactory(instanceId);
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
*/
|
||||
import { lazy } from 'react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
import { AlertTypeModel } from '../../../../types';
|
||||
import { validateExpression } from './validation';
|
||||
import { IndexThresholdAlertParams } from './types';
|
||||
|
@ -26,6 +25,12 @@ export function getAlertType(): AlertTypeModel<IndexThresholdAlertParams, Alerts
|
|||
},
|
||||
alertParamsExpression: lazy(() => import('./expression')),
|
||||
validate: validateExpression,
|
||||
defaultActionMessage: i18n.translate(
|
||||
'xpack.triggersActionsUI.components.builtinAlertTypes.threshold.alertDefaultActionMessage',
|
||||
{
|
||||
defaultMessage: `alert \\{\\{alertName\\}\\} group \\{\\{context.group\\}\\} value \\{\\{context.value\\}\\} exceeded threshold \\{\\{context.function\\}\\} over \\{\\{params.timeWindowSize\\}\\}\\{\\{params.timeWindowUnit\\}\\} on \\{\\{context.date\\}\\}`,
|
||||
}
|
||||
),
|
||||
requiresAppContext: false,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ import {
|
|||
ObjectRemover,
|
||||
} from '../../../../../common/lib';
|
||||
import { createEsDocuments } from './create_test_data';
|
||||
import { getAlertType } from '../../../../../../../plugins/triggers_actions_ui/public/application/components/builtin_alert_types/threshold/';
|
||||
|
||||
const ALERT_TYPE_ID = '.index-threshold';
|
||||
const ACTION_TYPE_ID = '.index';
|
||||
|
@ -26,6 +27,8 @@ const ALERT_INTERVALS_TO_WRITE = 5;
|
|||
const ALERT_INTERVAL_SECONDS = 3;
|
||||
const ALERT_INTERVAL_MILLIS = ALERT_INTERVAL_SECONDS * 1000;
|
||||
|
||||
const DefaultActionMessage = getAlertType().defaultActionMessage;
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default function alertTests({ getService }: FtrProviderContext) {
|
||||
const supertest = getService('supertest');
|
||||
|
@ -62,6 +65,10 @@ export default function alertTests({ getService }: FtrProviderContext) {
|
|||
await esTestIndexToolOutput.destroy();
|
||||
});
|
||||
|
||||
it('has a default action message', () => {
|
||||
expect(DefaultActionMessage).to.be.ok();
|
||||
});
|
||||
|
||||
// The tests below create two alerts, one that will fire, one that will
|
||||
// never fire; the tests ensure the ones that should fire, do fire, and
|
||||
// those that shouldn't fire, do not fire.
|
||||
|
@ -85,7 +92,7 @@ export default function alertTests({ getService }: FtrProviderContext) {
|
|||
const docs = await waitForDocs(2);
|
||||
for (const doc of docs) {
|
||||
const { group } = doc._source;
|
||||
const { name, value, title, message } = doc._source.params;
|
||||
const { name, title, message } = doc._source.params;
|
||||
|
||||
expect(name).to.be('always fire');
|
||||
expect(group).to.be('all documents');
|
||||
|
@ -93,9 +100,8 @@ export default function alertTests({ getService }: FtrProviderContext) {
|
|||
// 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');
|
||||
|
||||
const expectedPrefix = `alert always fire group all documents value ${value} exceeded threshold count > -1 over`;
|
||||
const messagePrefix = message.substr(0, expectedPrefix.length);
|
||||
expect(messagePrefix).to.be(expectedPrefix);
|
||||
const messagePattern = /alert always fire group all documents value \d+ exceeded threshold count > -1 over 15s on \d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z/;
|
||||
expect(message).to.match(messagePattern);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -128,10 +134,13 @@ export default function alertTests({ getService }: FtrProviderContext) {
|
|||
|
||||
for (const doc of docs) {
|
||||
const { group } = doc._source;
|
||||
const { name } = doc._source.params;
|
||||
const { name, message } = doc._source.params;
|
||||
|
||||
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/;
|
||||
expect(message).to.match(messagePattern);
|
||||
}
|
||||
|
||||
// there should be 2 docs in group-0, rando split between others
|
||||
|
@ -163,9 +172,12 @@ export default function alertTests({ getService }: FtrProviderContext) {
|
|||
|
||||
const docs = await waitForDocs(2);
|
||||
for (const doc of docs) {
|
||||
const { name } = doc._source.params;
|
||||
const { name, message } = doc._source.params;
|
||||
|
||||
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/;
|
||||
expect(message).to.match(messagePattern);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -195,9 +207,12 @@ export default function alertTests({ getService }: FtrProviderContext) {
|
|||
|
||||
const docs = await waitForDocs(4);
|
||||
for (const doc of docs) {
|
||||
const { name } = doc._source.params;
|
||||
const { name, message } = doc._source.params;
|
||||
|
||||
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/;
|
||||
expect(message).to.match(messagePattern);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -232,10 +247,13 @@ export default function alertTests({ getService }: FtrProviderContext) {
|
|||
|
||||
for (const doc of docs) {
|
||||
const { group } = doc._source;
|
||||
const { name } = doc._source.params;
|
||||
const { name, message } = doc._source.params;
|
||||
|
||||
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/;
|
||||
expect(message).to.match(messagePattern);
|
||||
}
|
||||
|
||||
// there should be 2 docs in group-2, rando split between others
|
||||
|
@ -274,10 +292,13 @@ export default function alertTests({ getService }: FtrProviderContext) {
|
|||
|
||||
for (const doc of docs) {
|
||||
const { group } = doc._source;
|
||||
const { name } = doc._source.params;
|
||||
const { name, message } = doc._source.params;
|
||||
|
||||
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/;
|
||||
expect(message).to.match(messagePattern);
|
||||
}
|
||||
|
||||
// there should be 2 docs in group-0, rando split between others
|
||||
|
@ -329,7 +350,7 @@ export default function alertTests({ getService }: FtrProviderContext) {
|
|||
name: '{{{alertName}}}',
|
||||
value: '{{{context.value}}}',
|
||||
title: '{{{context.title}}}',
|
||||
message: '{{{context.message}}}',
|
||||
message: DefaultActionMessage,
|
||||
},
|
||||
date: '{{{context.date}}}',
|
||||
// TODO: I wanted to write the alert value here, but how?
|
||||
|
|
|
@ -79,10 +79,13 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
|
|||
await find.clickByCssSelector('[data-test-subj="saveActionButtonModal"]:not(disabled)');
|
||||
const createdConnectorToastTitle = await pageObjects.common.closeToast();
|
||||
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}}'
|
||||
);
|
||||
await testSubjects.setValue('messageTextArea', 'test message ');
|
||||
await testSubjects.click('messageAddVariableButton');
|
||||
await testSubjects.click('variableMenuButton-0');
|
||||
const messageTextArea = await find.byCssSelector('[data-test-subj="messageTextArea"]');
|
||||
expect(await messageTextArea.getAttribute('value')).to.eql('test message {{alertId}}');
|
||||
await messageTextArea.type(' some additional text ');
|
||||
|
||||
|
|
Loading…
Reference in a new issue