Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Synthetics] copy alert state to alert context and implement alert recovery #128693

Merged
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
a8269d2
copy alert state to alert context
dominiqueclarke Mar 28, 2022
c3c5bf5
adjust alert translations
dominiqueclarke Mar 29, 2022
bb7d151
Merge branch 'main' into feature/uptime-alert-context
kibanamachine Apr 12, 2022
d33244a
Merge branch 'main' of github.com:elastic/kibana into feature/uptime-…
dominiqueclarke Apr 15, 2022
b8b863d
Merge branch 'main' into feature/uptime-alert-context
kibanamachine Apr 19, 2022
a0ee04d
Merge branch 'main' of github.com:elastic/kibana into feature/uptime-…
dominiqueclarke Apr 20, 2022
a0c50fa
Merge branch 'feature/uptime-alert-context' of https://github.com/dom…
dominiqueclarke Apr 20, 2022
a7b7633
Merge branch 'main' of github.com:elastic/kibana into feature/uptime-…
dominiqueclarke Apr 20, 2022
a60a2c7
uptime - implement alert recovery
dominiqueclarke Apr 25, 2022
b19fc8b
adjust tests
dominiqueclarke Apr 25, 2022
0cadd9e
merge upstream
dominiqueclarke Apr 25, 2022
8b9fc05
Merge branch 'main' into feature/uptime-alert-context
kibanamachine Apr 25, 2022
ad9d68e
[CI] Auto-commit changed files from 'node scripts/eslint --no-cache -…
kibanamachine Apr 25, 2022
1981be9
remove unused constant
dominiqueclarke Apr 26, 2022
f29c8ba
Merge branch 'feature/uptime-alert-context' of https://github.com/dom…
dominiqueclarke Apr 26, 2022
75bd15c
update snapshot
dominiqueclarke Apr 26, 2022
c00d2e7
Merge branch 'main' of github.com:elastic/kibana into feature/uptime-…
dominiqueclarke Apr 27, 2022
a1e4abe
add default recovery messages
dominiqueclarke Apr 27, 2022
b25cb9b
update snapshot
dominiqueclarke Apr 29, 2022
0fbdbee
Merge branch 'main' of github.com:elastic/kibana into feature/uptime-…
dominiqueclarke May 1, 2022
a102eb6
Merge branch 'main' into feature/uptime-alert-context
kibanamachine May 5, 2022
5eda8d2
Merge branch 'main' of github.com:elastic/kibana into feature/uptime-…
dominiqueclarke May 9, 2022
434fd36
add doesSetRecoveryContext to uptime duration anomaly alert
dominiqueclarke May 9, 2022
7784f15
Merge branch 'feature/uptime-alert-context' of https://github.com/dom…
dominiqueclarke May 9, 2022
7d2daad
Merge branch 'main' into feature/uptime-alert-context
kibanamachine May 9, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 50 additions & 19 deletions x-pack/plugins/synthetics/common/translations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,23 @@ export const MonitorStatusTranslations = {
defaultMessage:
'Monitor {monitorName} with url {monitorUrl} from {observerLocation} {statusMessage} The latest error message is {latestErrorMessage}',
values: {
monitorName: '{{state.monitorName}}',
monitorUrl: '{{{state.monitorUrl}}}',
statusMessage: '{{{state.statusMessage}}}',
latestErrorMessage: '{{{state.latestErrorMessage}}}',
observerLocation: '{{state.observerLocation}}',
monitorName: '{{context.monitorName}}',
monitorUrl: '{{{context.monitorUrl}}}',
statusMessage: '{{{context.statusMessage}}}',
latestErrorMessage: '{{{context.latestErrorMessage}}}',
observerLocation: '{{context.observerLocation}}',
},
}
),
defaultRecoveryMessage: i18n.translate(
'xpack.synthetics.alerts.monitorStatus.defaultRecoveryMessage',
{
defaultMessage:
'Alert for monitor {monitorName} with url {monitorUrl} from {observerLocation} has recovered',
values: {
monitorName: '{{context.monitorName}}',
monitorUrl: '{{{context.monitorUrl}}}',
observerLocation: '{{context.observerLocation}}',
},
}
),
Expand All @@ -46,13 +58,19 @@ export const MonitorStatusTranslations = {

export const TlsTranslations = {
defaultActionMessage: i18n.translate('xpack.synthetics.alerts.tls.defaultActionMessage', {
defaultMessage: `Detected TLS certificate {commonName} from issuer {issuer} is {status}. Certificate {summary}
`,
defaultMessage: `Detected TLS certificate {commonName} from issuer {issuer} is {status}. Certificate {summary}`,
values: {
commonName: '{{state.commonName}}',
issuer: '{{state.issuer}}',
summary: '{{state.summary}}',
status: '{{state.status}}',
commonName: '{{context.commonName}}',
issuer: '{{context.issuer}}',
summary: '{{context.summary}}',
status: '{{context.status}}',
},
}),
defaultRecoveryMessage: i18n.translate('xpack.synthetics.alerts.tls.defaultRecoveryMessage', {
defaultMessage: `Alert for TLS certificate {commonName} from issuer {issuer} has recovered`,
values: {
commonName: '{{context.commonName}}',
issuer: '{{context.issuer}}',
},
}),
name: i18n.translate('xpack.synthetics.alerts.tls.clientName', {
Expand Down Expand Up @@ -103,14 +121,27 @@ export const DurationAnomalyTranslations = {
defaultMessage: `Abnormal ({severity} level) response time detected on {monitor} with url {monitorUrl} at {anomalyStartTimestamp}. Anomaly severity score is {severityScore}.
Response times as high as {slowestAnomalyResponse} have been detected from location {observerLocation}. Expected response time is {expectedResponseTime}.`,
values: {
severity: '{{state.severity}}',
anomalyStartTimestamp: '{{state.anomalyStartTimestamp}}',
monitor: '{{state.monitor}}',
monitorUrl: '{{{state.monitorUrl}}}',
slowestAnomalyResponse: '{{state.slowestAnomalyResponse}}',
expectedResponseTime: '{{state.expectedResponseTime}}',
severityScore: '{{state.severityScore}}',
observerLocation: '{{state.observerLocation}}',
severity: '{{context.severity}}',
anomalyStartTimestamp: '{{context.anomalyStartTimestamp}}',
monitor: '{{context.monitor}}',
monitorUrl: '{{{context.monitorUrl}}}',
slowestAnomalyResponse: '{{context.slowestAnomalyResponse}}',
expectedResponseTime: '{{context.expectedResponseTime}}',
severityScore: '{{context.severityScore}}',
observerLocation: '{{context.observerLocation}}',
},
}
),
defaultRecoveryMessage: i18n.translate(
'xpack.synthetics.alerts.durationAnomaly.defaultRecoveryMessage',
{
defaultMessage: `Alert for abnormal ({severity} level) response time detected on monitor {monitor} with url {monitorUrl} from location {observerLocation} at {anomalyStartTimestamp} has recovered`,
values: {
severity: '{{context.severity}}',
anomalyStartTimestamp: '{{context.anomalyStartTimestamp}}',
monitor: '{{context.monitor}}',
monitorUrl: '{{{context.monitorUrl}}}',
observerLocation: '{{context.observerLocation}}',
},
}
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { getMonitorRouteFromMonitorId } from '../../../../common/utils/get_monit
import { CLIENT_ALERT_TYPES } from '../../../../common/constants/alerts';
import { DurationAnomalyTranslations } from '../../../../common/translations';

const { defaultActionMessage, description } = DurationAnomalyTranslations;
const { defaultActionMessage, defaultRecoveryMessage, description } = DurationAnomalyTranslations;
const DurationAnomalyAlert = React.lazy(() => import('./lazy_wrapper/duration_anomaly'));

export const initDurationAnomalyAlertType: AlertTypeInitializer = ({
Expand All @@ -34,6 +34,7 @@ export const initDurationAnomalyAlertType: AlertTypeInitializer = ({
description,
validate: () => ({ errors: {} }),
defaultActionMessage,
defaultRecoveryMessage,
requiresAppContext: true,
format: ({ fields }) => ({
reason: fields[ALERT_REASON] || '',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,8 @@ describe('monitor status alert type', () => {
})
).toMatchInlineSnapshot(`
Object {
"defaultActionMessage": "Monitor {{state.monitorName}} with url {{{state.monitorUrl}}} from {{state.observerLocation}} {{{state.statusMessage}}} The latest error message is {{{state.latestErrorMessage}}}",
"defaultActionMessage": "Monitor {{context.monitorName}} with url {{{context.monitorUrl}}} from {{context.observerLocation}} {{{context.statusMessage}}} The latest error message is {{{context.latestErrorMessage}}}",
"defaultRecoveryMessage": "Alert for monitor {{context.monitorName}} with url {{{context.monitorUrl}}} from {{context.observerLocation}} has recovered",
"description": "Alert when a monitor is down or an availability threshold is breached.",
"documentationUrl": [Function],
"format": [Function],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import { getMonitorRouteFromMonitorId } from '../../../../common/utils/get_monit
import { MonitorStatusTranslations } from '../../../../common/translations';
import { CLIENT_ALERT_TYPES } from '../../../../common/constants/alerts';

const { defaultActionMessage, description } = MonitorStatusTranslations;
const { defaultActionMessage, defaultRecoveryMessage, description } = MonitorStatusTranslations;

const MonitorStatusAlert = React.lazy(() => import('./lazy_wrapper/monitor_status'));

Expand Down Expand Up @@ -54,6 +54,7 @@ export const initMonitorStatusAlertType: AlertTypeInitializer = ({
return validateFunc ? validateFunc(ruleParams) : ({} as ValidationResult);
},
defaultActionMessage,
defaultRecoveryMessage,
requiresAppContext: false,
format: ({ fields }) => ({
reason: fields[ALERT_REASON] || '',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { AlertTypeInitializer } from '.';

import { CERTIFICATES_ROUTE } from '../../../../common/constants/ui';

const { defaultActionMessage, description } = TlsTranslations;
const { defaultActionMessage, defaultRecoveryMessage, description } = TlsTranslations;
const TLSAlert = React.lazy(() => import('./lazy_wrapper/tls_alert'));
export const initTlsAlertType: AlertTypeInitializer = ({
core,
Expand All @@ -29,6 +29,7 @@ export const initTlsAlertType: AlertTypeInitializer = ({
description,
validate: () => ({ errors: {} }),
defaultActionMessage,
defaultRecoveryMessage,
requiresAppContext: false,
format: ({ fields }) => ({
reason: fields[ALERT_REASON] || '',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ describe('Alert Actions factory', () => {
eventAction: 'trigger',
severity: 'error',
summary:
'Monitor {{state.monitorName}} with url {{{state.monitorUrl}}} from {{state.observerLocation}} {{{state.statusMessage}}} The latest error message is {{{state.latestErrorMessage}}}',
'Monitor {{context.monitorName}} with url {{{context.monitorUrl}}} from {{context.observerLocation}} {{{context.statusMessage}}} The latest error message is {{{context.latestErrorMessage}}}',
},
id: 'f2a3b195-ed76-499a-805d-82d24d4eeba9',
},
Expand All @@ -75,7 +75,7 @@ describe('Alert Actions factory', () => {
eventAction: 'trigger',
severity: 'error',
summary:
'Monitor {{state.monitorName}} with url {{{state.monitorUrl}}} from {{state.observerLocation}} {{{state.statusMessage}}} The latest error message is {{{state.latestErrorMessage}}}',
'Monitor {{context.monitorName}} with url {{{context.monitorUrl}}} from {{context.observerLocation}} {{{context.statusMessage}}} The latest error message is {{{context.latestErrorMessage}}}',
},
},
]);
Expand All @@ -93,7 +93,7 @@ describe('Alert Actions factory', () => {
eventAction: 'trigger',
severity: 'error',
summary:
'Monitor {{state.monitorName}} with url {{{state.monitorUrl}}} from {{state.observerLocation}} {{{state.statusMessage}}} The latest error message is {{{state.latestErrorMessage}}}',
'Monitor {{context.monitorName}} with url {{{context.monitorUrl}}} from {{context.observerLocation}} {{{context.statusMessage}}} The latest error message is {{{context.latestErrorMessage}}}',
},
id: 'f2a3b195-ed76-499a-805d-82d24d4eeba9',
},
Expand All @@ -118,7 +118,7 @@ describe('Alert Actions factory', () => {
eventAction: 'trigger',
severity: 'error',
summary:
'Monitor {{state.monitorName}} with url {{{state.monitorUrl}}} from {{state.observerLocation}} {{{state.statusMessage}}} The latest error message is {{{state.latestErrorMessage}}}',
'Monitor {{context.monitorName}} with url {{{context.monitorUrl}}} from {{context.observerLocation}} {{{context.statusMessage}}} The latest error message is {{{context.latestErrorMessage}}}',
},
},
]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,11 +127,11 @@ function getIndexActionParams(selectedMonitor: Ping, recovery = false): IndexAct
return {
documents: [
{
monitorName: '{{state.monitorName}}',
monitorUrl: '{{{state.monitorUrl}}}',
monitorName: '{{context.monitorName}}',
monitorUrl: '{{{context.monitorUrl}}}',
statusMessage: getRecoveryMessage(selectedMonitor),
latestErrorMessage: '',
observerLocation: '{{state.observerLocation}}',
observerLocation: '{{context.observerLocation}}',
},
],
indexOverride: null,
Expand All @@ -140,11 +140,11 @@ function getIndexActionParams(selectedMonitor: Ping, recovery = false): IndexAct
return {
documents: [
{
monitorName: '{{state.monitorName}}',
monitorUrl: '{{{state.monitorUrl}}}',
statusMessage: '{{{state.statusMessage}}}',
latestErrorMessage: '{{{state.latestErrorMessage}}}',
observerLocation: '{{state.observerLocation}}',
monitorName: '{{context.monitorName}}',
monitorUrl: '{{{context.monitorUrl}}}',
statusMessage: '{{{context.statusMessage}}}',
latestErrorMessage: '{{{context.latestErrorMessage}}}',
observerLocation: '{{context.observerLocation}}',
},
],
indexOverride: null,
Expand Down
11 changes: 10 additions & 1 deletion x-pack/plugins/synthetics/server/lib/alerts/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import { isRight } from 'fp-ts/lib/Either';
import Mustache from 'mustache';
import { IBasePath } from '@kbn/core/server';
import { RuleExecutorServices } from '@kbn/alerting-plugin/server';
import { UptimeCommonState, UptimeCommonStateType } from '../../../common/runtime_types';

export type UpdateUptimeAlertState = (
Expand Down Expand Up @@ -59,9 +60,17 @@ export const updateState: UpdateUptimeAlertState = (state, isTriggeredNow) => {
};

export const generateAlertMessage = (messageTemplate: string, fields: Record<string, any>) => {
return Mustache.render(messageTemplate, { state: { ...fields } });
return Mustache.render(messageTemplate, { context: { ...fields }, state: { ...fields } });
};
export const getViewInAppUrl = (relativeViewInAppUrl: string, basePath: IBasePath) =>
basePath.publicBaseUrl
? new URL(basePath.prepend(relativeViewInAppUrl), basePath.publicBaseUrl).toString()
: relativeViewInAppUrl;

export const setRecoveredAlertsContext = (alertFactory: RuleExecutorServices['alertFactory']) => {
const { getRecoveredAlerts } = alertFactory.done();
for (const alert of getRecoveredAlerts()) {
const state = alert.getState();
alert.setContext(state);
}
};
Loading