Skip to content

Commit

Permalink
[Alerting] add more alert properties to action parameter templating (#…
Browse files Browse the repository at this point in the history
…59718)

This is a pre-cursor to #58529

I realized a bit ago that we weren't making quite enough info available
in the action parameter templating that happens when alerts schedule
actions to execute.  Missing were alert name, tags, and spaceId.

For the index threshold alert, I had added them to it's context, but
then every other action would have to do the same if they also
wanted those values.

So I added these as additional top-level variables that can be
used in templates, along with the alert id, alert instance id,
context, and state.  The other bits in RawAlert didn't seem
that interesting, to be used as an action parameter.
  • Loading branch information
pmuellr authored Mar 10, 2020
1 parent 8c0da24 commit 7db4196
Show file tree
Hide file tree
Showing 12 changed files with 264 additions and 74 deletions.
15 changes: 12 additions & 3 deletions x-pack/plugins/alerting/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,15 @@ This factory returns an instance of `AlertInstance`. The alert instance class ha

There needs to be a way to map alert context into action parameters. For this, we started off by adding template support. Any string within the `params` of an alert saved object's `actions` will be processed as a template and can inject context or state values.

When an alert instance executes, the first argument is the `group` of actions to execute and the second is the context the alert exposes to templates. We iterate through each action params attributes recursively and render templates if they are a string. Templates have access to the `context` (provided by second argument of `.scheduleActions(...)` on an alert instance) and the alert instance's `state` (provided by the most recent `replaceState` call on an alert instance) as well as `alertId` and `alertInstanceId`.
When an alert instance executes, the first argument is the `group` of actions to execute and the second is the context the alert exposes to templates. We iterate through each action params attributes recursively and render templates if they are a string. Templates have access to the following "variables":

- `context` - provided by second argument of `.scheduleActions(...)` on an alert instance
- `state` - the alert instance's `state` provided by the most recent `replaceState` call on an alert instance
- `alertId` - the id of the alert
- `alertInstanceId` - the alert instance id
- `alertName` - the name of the alert
- `spaceId` - the id of the space the alert exists in
- `tags` - the tags set in the alert

## Examples

Expand All @@ -410,6 +418,7 @@ Below is an example of an alert that takes advantage of templating:
{
...
id: "123",
name: "cpu alert",
actions: [
{
"group": "default",
Expand All @@ -418,7 +427,7 @@ Below is an example of an alert that takes advantage of templating:
"from": "[email protected]",
"to": ["[email protected]"],
"subject": "A notification about {{context.server}}"
"body": "The server {{context.server}} has a CPU usage of {{state.cpuUsage}}%. This message for {{alertInstanceId}} was created by the alert {{alertId}}."
"body": "The server {{context.server}} has a CPU usage of {{state.cpuUsage}}%. This message for {{alertInstanceId}} was created by the alert {{alertId}} {{alertName}}."
}
}
]
Expand All @@ -432,7 +441,7 @@ The templating system will take the alert and alert type as described above and
"from": "[email protected]",
"to": ["[email protected]"],
"subject": "A notification about server_1"
"body": "The server server_1 has a CPU usage of 80%. This message for server_1 was created by the alert 123"
"body": "The server server_1 has a CPU usage of 80%. This message for server_1 was created by the alert 123 cpu alert"
}
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ const createExecutionHandlerParams = {
executeAction: jest.fn(),
spaceId: 'default',
alertId: '1',
alertName: 'name-of-alert',
tags: ['tag-A', 'tag-B'],
apiKey: 'MTIzOmFiYw==',
spaceIdToNamespace: jest.fn().mockReturnValue(undefined),
getBasePath: jest.fn().mockReturnValue(undefined),
Expand All @@ -37,6 +39,7 @@ const createExecutionHandlerParams = {
foo: true,
contextVal: 'My {{context.value}} goes here',
stateVal: 'My {{state.value}} goes here',
alertVal: 'My {{alertId}} {{alertName}} {{spaceId}} {{tags}} {{alertInstanceId}} goes here',
},
},
],
Expand All @@ -59,6 +62,7 @@ test('calls executeAction per selected action', async () => {
"apiKey": "MTIzOmFiYw==",
"id": "1",
"params": Object {
"alertVal": "My 1 name-of-alert default tag-A,tag-B 2 goes here",
"contextVal": "My goes here",
"foo": true,
"stateVal": "My goes here",
Expand Down Expand Up @@ -95,6 +99,7 @@ test('context attribute gets parameterized', async () => {
"apiKey": "MTIzOmFiYw==",
"id": "1",
"params": Object {
"alertVal": "My 1 name-of-alert default tag-A,tag-B 2 goes here",
"contextVal": "My context-val goes here",
"foo": true,
"stateVal": "My goes here",
Expand All @@ -120,6 +125,7 @@ test('state attribute gets parameterized', async () => {
"apiKey": "MTIzOmFiYw==",
"id": "1",
"params": Object {
"alertVal": "My 1 name-of-alert default tag-A,tag-B 2 goes here",
"contextVal": "My goes here",
"foo": true,
"stateVal": "My state-val goes here",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import { PluginStartContract as ActionsPluginStartContract } from '../../../../p

interface CreateExecutionHandlerOptions {
alertId: string;
alertName: string;
tags?: string[];
executeAction: ActionsPluginStartContract['execute'];
actions: AlertAction[];
spaceId: string;
Expand All @@ -30,6 +32,8 @@ interface ExecutionHandlerOptions {
export function createExecutionHandler({
logger,
alertId,
alertName,
tags,
executeAction,
actions: alertActions,
spaceId,
Expand All @@ -49,9 +53,12 @@ export function createExecutionHandler({
...action,
params: transformActionParams({
alertId,
alertName,
spaceId,
tags,
alertInstanceId,
context,
params: action.params,
actionParams: action.params,
state,
}),
};
Expand Down
8 changes: 7 additions & 1 deletion x-pack/plugins/alerting/server/task_runner/task_runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,10 @@ export class TaskRunner {
return this.context.getServices(fakeRequest);
}

getExecutionHandler(
private getExecutionHandler(
alertId: string,
alertName: string,
tags: string[] | undefined,
spaceId: string,
apiKey: string | null,
actions: RawAlert['actions'],
Expand All @@ -114,6 +116,8 @@ export class TaskRunner {

return createExecutionHandler({
alertId,
alertName,
tags,
logger: this.logger,
executeAction: this.context.executeAction,
apiKey,
Expand Down Expand Up @@ -225,6 +229,8 @@ export class TaskRunner {
const params = validateAlertTypeParams(this.alertType, attributes.params);
const executionHandler = this.getExecutionHandler(
alertId,
attributes.name,
attributes.tags,
spaceId,
apiKey,
attributes.actions,
Expand Down
Loading

0 comments on commit 7db4196

Please sign in to comment.