Skip to content

Commit c78cf35

Browse files
authored
Added defaultActionMessage to index threshold alert UI type definition (elastic#80936)
* resolves elastic#78148 Adds a `defaultActionMessage` to the index threshold alert, so that the `message` parameter for actions will be pre-filled with a useful message
1 parent f2f76e1 commit c78cf35

File tree

7 files changed

+63
-16
lines changed

7 files changed

+63
-16
lines changed

x-pack/plugins/stack_alerts/server/alert_types/index_threshold/action_context.test.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ describe('ActionContext', () => {
2525
date: '2020-01-01T00:00:00.000Z',
2626
group: '[group]',
2727
value: 42,
28+
function: 'count > 4',
2829
};
2930
const context = addMessages({ name: '[alert-name]' }, base, params);
3031
expect(context.title).toMatchInlineSnapshot(
@@ -53,6 +54,7 @@ describe('ActionContext', () => {
5354
date: '2020-01-01T00:00:00.000Z',
5455
group: '[group]',
5556
value: 42,
57+
function: 'avg([aggField]) > 4.2',
5658
};
5759
const context = addMessages({ name: '[alert-name]' }, base, params);
5860
expect(context.title).toMatchInlineSnapshot(
@@ -80,6 +82,7 @@ describe('ActionContext', () => {
8082
date: '2020-01-01T00:00:00.000Z',
8183
group: '[group]',
8284
value: 4,
85+
function: 'count between 4,5',
8386
};
8487
const context = addMessages({ name: '[alert-name]' }, base, params);
8588
expect(context.title).toMatchInlineSnapshot(

x-pack/plugins/stack_alerts/server/alert_types/index_threshold/action_context.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ export interface BaseActionContext extends AlertInstanceContext {
2727
date: string;
2828
// the value that met the threshold
2929
value: number;
30+
// the function that is used
31+
function: string;
3032
}
3133

3234
export function addMessages(
@@ -42,9 +44,6 @@ export function addMessages(
4244
},
4345
});
4446

45-
const agg = params.aggField ? `${params.aggType}(${params.aggField})` : `${params.aggType}`;
46-
const humanFn = `${agg} ${params.thresholdComparator} ${params.threshold.join(',')}`;
47-
4847
const window = `${params.timeWindowSize}${params.timeWindowUnit}`;
4948
const message = i18n.translate(
5049
'xpack.stackAlerts.indexThreshold.alertTypeContextMessageDescription',
@@ -55,7 +54,7 @@ export function addMessages(
5554
name: alertInfo.name,
5655
group: baseContext.group,
5756
value: baseContext.value,
58-
function: humanFn,
57+
function: baseContext.function,
5958
window,
6059
date: baseContext.date,
6160
},

x-pack/plugins/stack_alerts/server/alert_types/index_threshold/alert_type.test.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ describe('alertType', () => {
4646
"description": "The value that exceeded the threshold.",
4747
"name": "value",
4848
},
49+
Object {
50+
"description": "A string describing the threshold comparator and threshold",
51+
"name": "function",
52+
},
4953
],
5054
"params": Array [
5155
Object {

x-pack/plugins/stack_alerts/server/alert_types/index_threshold/alert_type.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,13 @@ export function getAlertType(service: Service): AlertType<Params, {}, {}, Action
8383
}
8484
);
8585

86+
const actionVariableContextFunctionLabel = i18n.translate(
87+
'xpack.stackAlerts.indexThreshold.actionVariableContextFunctionLabel',
88+
{
89+
defaultMessage: 'A string describing the threshold comparator and threshold',
90+
}
91+
);
92+
8693
const alertParamsVariables = Object.keys(CoreQueryParamsSchemaProperties).map(
8794
(propKey: string) => {
8895
return {
@@ -107,6 +114,7 @@ export function getAlertType(service: Service): AlertType<Params, {}, {}, Action
107114
{ name: 'group', description: actionVariableContextGroupLabel },
108115
{ name: 'date', description: actionVariableContextDateLabel },
109116
{ name: 'value', description: actionVariableContextValueLabel },
117+
{ name: 'function', description: actionVariableContextFunctionLabel },
110118
],
111119
params: [
112120
{ name: 'threshold', description: actionVariableContextThresholdLabel },
@@ -160,10 +168,14 @@ export function getAlertType(service: Service): AlertType<Params, {}, {}, Action
160168

161169
if (!met) continue;
162170

171+
const agg = params.aggField ? `${params.aggType}(${params.aggField})` : `${params.aggType}`;
172+
const humanFn = `${agg} ${params.thresholdComparator} ${params.threshold.join(',')}`;
173+
163174
const baseContext: BaseActionContext = {
164175
date,
165176
group: instanceId,
166177
value,
178+
function: humanFn,
167179
};
168180
const actionContext = addMessages(options, baseContext, params);
169181
const alertInstance = options.services.alertInstanceFactory(instanceId);

x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/threshold/index.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
*/
66
import { lazy } from 'react';
77
import { i18n } from '@kbn/i18n';
8-
98
import { AlertTypeModel } from '../../../../types';
109
import { validateExpression } from './validation';
1110
import { IndexThresholdAlertParams } from './types';
@@ -26,6 +25,12 @@ export function getAlertType(): AlertTypeModel<IndexThresholdAlertParams, Alerts
2625
},
2726
alertParamsExpression: lazy(() => import('./expression')),
2827
validate: validateExpression,
28+
defaultActionMessage: i18n.translate(
29+
'xpack.triggersActionsUI.components.builtinAlertTypes.threshold.alertDefaultActionMessage',
30+
{
31+
defaultMessage: `alert \\{\\{alertName\\}\\} group \\{\\{context.group\\}\\} value \\{\\{context.value\\}\\} exceeded threshold \\{\\{context.function\\}\\} over \\{\\{params.timeWindowSize\\}\\}\\{\\{params.timeWindowUnit\\}\\} on \\{\\{context.date\\}\\}`,
32+
}
33+
),
2934
requiresAppContext: false,
3035
};
3136
}

x-pack/test/alerting_api_integration/spaces_only/tests/alerting/builtin_alert_types/index_threshold/alert.ts

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
ObjectRemover,
1616
} from '../../../../../common/lib';
1717
import { createEsDocuments } from './create_test_data';
18+
import { getAlertType } from '../../../../../../../plugins/triggers_actions_ui/public/application/components/builtin_alert_types/threshold/';
1819

1920
const ALERT_TYPE_ID = '.index-threshold';
2021
const ACTION_TYPE_ID = '.index';
@@ -26,6 +27,8 @@ const ALERT_INTERVALS_TO_WRITE = 5;
2627
const ALERT_INTERVAL_SECONDS = 3;
2728
const ALERT_INTERVAL_MILLIS = ALERT_INTERVAL_SECONDS * 1000;
2829

30+
const DefaultActionMessage = getAlertType().defaultActionMessage;
31+
2932
// eslint-disable-next-line import/no-default-export
3033
export default function alertTests({ getService }: FtrProviderContext) {
3134
const supertest = getService('supertest');
@@ -62,6 +65,10 @@ export default function alertTests({ getService }: FtrProviderContext) {
6265
await esTestIndexToolOutput.destroy();
6366
});
6467

68+
it('has a default action message', () => {
69+
expect(DefaultActionMessage).to.be.ok();
70+
});
71+
6572
// The tests below create two alerts, one that will fire, one that will
6673
// never fire; the tests ensure the ones that should fire, do fire, and
6774
// those that shouldn't fire, do not fire.
@@ -85,17 +92,16 @@ export default function alertTests({ getService }: FtrProviderContext) {
8592
const docs = await waitForDocs(2);
8693
for (const doc of docs) {
8794
const { group } = doc._source;
88-
const { name, value, title, message } = doc._source.params;
95+
const { name, title, message } = doc._source.params;
8996

9097
expect(name).to.be('always fire');
9198
expect(group).to.be('all documents');
9299

93100
// we'll check title and message in this test, but not subsequent ones
94101
expect(title).to.be('alert always fire group all documents exceeded threshold');
95102

96-
const expectedPrefix = `alert always fire group all documents value ${value} exceeded threshold count > -1 over`;
97-
const messagePrefix = message.substr(0, expectedPrefix.length);
98-
expect(messagePrefix).to.be(expectedPrefix);
103+
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/;
104+
expect(message).to.match(messagePattern);
99105
}
100106
});
101107

@@ -128,10 +134,13 @@ export default function alertTests({ getService }: FtrProviderContext) {
128134

129135
for (const doc of docs) {
130136
const { group } = doc._source;
131-
const { name } = doc._source.params;
137+
const { name, message } = doc._source.params;
132138

133139
expect(name).to.be('always fire');
134140
if (group === 'group-0') inGroup0++;
141+
142+
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/;
143+
expect(message).to.match(messagePattern);
135144
}
136145

137146
// there should be 2 docs in group-0, rando split between others
@@ -163,9 +172,12 @@ export default function alertTests({ getService }: FtrProviderContext) {
163172

164173
const docs = await waitForDocs(2);
165174
for (const doc of docs) {
166-
const { name } = doc._source.params;
175+
const { name, message } = doc._source.params;
167176

168177
expect(name).to.be('always fire');
178+
179+
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/;
180+
expect(message).to.match(messagePattern);
169181
}
170182
});
171183

@@ -195,9 +207,12 @@ export default function alertTests({ getService }: FtrProviderContext) {
195207

196208
const docs = await waitForDocs(4);
197209
for (const doc of docs) {
198-
const { name } = doc._source.params;
210+
const { name, message } = doc._source.params;
199211

200212
expect(name).to.be('always fire');
213+
214+
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/;
215+
expect(message).to.match(messagePattern);
201216
}
202217
});
203218

@@ -232,10 +247,13 @@ export default function alertTests({ getService }: FtrProviderContext) {
232247

233248
for (const doc of docs) {
234249
const { group } = doc._source;
235-
const { name } = doc._source.params;
250+
const { name, message } = doc._source.params;
236251

237252
expect(name).to.be('always fire');
238253
if (group === 'group-2') inGroup2++;
254+
255+
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/;
256+
expect(message).to.match(messagePattern);
239257
}
240258

241259
// there should be 2 docs in group-2, rando split between others
@@ -274,10 +292,13 @@ export default function alertTests({ getService }: FtrProviderContext) {
274292

275293
for (const doc of docs) {
276294
const { group } = doc._source;
277-
const { name } = doc._source.params;
295+
const { name, message } = doc._source.params;
278296

279297
expect(name).to.be('always fire');
280298
if (group === 'group-0') inGroup0++;
299+
300+
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/;
301+
expect(message).to.match(messagePattern);
281302
}
282303

283304
// there should be 2 docs in group-0, rando split between others
@@ -329,7 +350,7 @@ export default function alertTests({ getService }: FtrProviderContext) {
329350
name: '{{{alertName}}}',
330351
value: '{{{context.value}}}',
331352
title: '{{{context.title}}}',
332-
message: '{{{context.message}}}',
353+
message: DefaultActionMessage,
333354
},
334355
date: '{{{context.date}}}',
335356
// TODO: I wanted to write the alert value here, but how?

x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/alert_create_flyout.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,13 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
7979
await find.clickByCssSelector('[data-test-subj="saveActionButtonModal"]:not(disabled)');
8080
const createdConnectorToastTitle = await pageObjects.common.closeToast();
8181
expect(createdConnectorToastTitle).to.eql(`Created '${slackConnectorName}'`);
82+
const messageTextArea = await find.byCssSelector('[data-test-subj="messageTextArea"]');
83+
expect(await messageTextArea.getAttribute('value')).to.eql(
84+
'alert {{alertName}} group {{context.group}} value {{context.value}} exceeded threshold {{context.function}} over {{params.timeWindowSize}}{{params.timeWindowUnit}} on {{context.date}}'
85+
);
8286
await testSubjects.setValue('messageTextArea', 'test message ');
8387
await testSubjects.click('messageAddVariableButton');
8488
await testSubjects.click('variableMenuButton-0');
85-
const messageTextArea = await find.byCssSelector('[data-test-subj="messageTextArea"]');
8689
expect(await messageTextArea.getAttribute('value')).to.eql('test message {{alertId}}');
8790
await messageTextArea.type(' some additional text ');
8891

0 commit comments

Comments
 (0)