-
Notifications
You must be signed in to change notification settings - Fork 8.3k
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
[Uptime] migrate to observability rules registry #100699
Changes from all commits
52564d2
18683b5
73a2dd7
995cb88
881a1cc
1753bbc
d5a597b
8e247b5
31ac049
7f8f6ef
493b55e
fbb530e
d9b3294
804ad55
17aa286
53a05bc
cbc95a6
24036d5
96e1ddb
c303eea
6d1e628
95ea9f7
b9a7c78
e5c0304
764f9d0
4d71a8c
5811306
2e04e0b
411dbdf
555c237
5964ac0
de27cbc
bded189
93e68c4
4a7e70d
38c5842
e9a2a17
994c42d
26c5516
1bac613
416e50c
bd98bd4
16c27c9
5149ba4
835caab
36248a1
ddd18bd
cf40852
bedd91b
2ca90e2
cef6cb4
8302df4
664f122
992c04f
36c8a4c
64c2091
d541c85
294137a
1f4f4d7
4ce1026
7d41f4f
dcdc486
d350d81
ed532b6
1cf9f33
ee2468b
e5b5d0f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0; you may not use this file except in compliance with the Elastic License | ||
* 2.0. | ||
*/ | ||
|
||
export const uptimeRuleFieldMap = { | ||
// common fields | ||
'monitor.id': { | ||
type: 'keyword', | ||
}, | ||
'url.full': { | ||
type: 'keyword', | ||
}, | ||
'observer.geo.name': { | ||
type: 'keyword', | ||
}, | ||
reason: { | ||
type: 'text', | ||
}, | ||
// monitor status alert fields | ||
'error.message': { | ||
type: 'text', | ||
}, | ||
'agent.name': { | ||
type: 'keyword', | ||
}, | ||
'monitor.name': { | ||
type: 'keyword', | ||
}, | ||
'monitor.type': { | ||
type: 'keyword', | ||
}, | ||
// tls alert fields | ||
'tls.server.x509.issuer.common_name': { | ||
type: 'keyword', | ||
}, | ||
'tls.server.x509.subject.common_name': { | ||
type: 'keyword', | ||
}, | ||
'tls.server.x509.not_after': { | ||
type: 'date', | ||
}, | ||
'tls.server.x509.not_before': { | ||
type: 'date', | ||
}, | ||
'tls.server.hash.sha256': { | ||
type: 'keyword', | ||
}, | ||
// anomaly alert fields | ||
'anomaly.start': { | ||
type: 'date', | ||
}, | ||
'anomaly.bucket_span.minutes': { | ||
type: 'keyword', | ||
}, | ||
} as const; | ||
|
||
export type UptimeRuleFieldMap = typeof uptimeRuleFieldMap; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -37,3 +37,78 @@ export const MonitorStatusTranslations = { | |
defaultMessage: 'Alert when a monitor is down or an availability threshold is breached.', | ||
}), | ||
}; | ||
|
||
export const TlsTranslations = { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Moved alert translations to common, in order to use them within server to derive reason message. |
||
defaultActionMessage: i18n.translate('xpack.uptime.alerts.tls.legacy.defaultActionMessage', { | ||
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}}', | ||
}, | ||
}), | ||
name: i18n.translate('xpack.uptime.alerts.tls.legacy.clientName', { | ||
defaultMessage: 'Uptime TLS (Legacy)', | ||
}), | ||
description: i18n.translate('xpack.uptime.alerts.tls.legacy.description', { | ||
defaultMessage: | ||
'Alert when the TLS certificate of an Uptime monitor is about to expire. This alert will be deprecated in a future version.', | ||
}), | ||
}; | ||
|
||
export const TlsTranslationsLegacy = { | ||
defaultActionMessage: i18n.translate('xpack.uptime.alerts.tls.defaultActionMessage', { | ||
defaultMessage: `Detected {count} TLS certificates expiring or becoming too old. | ||
{expiringConditionalOpen} | ||
Expiring cert count: {expiringCount} | ||
Expiring Certificates: {expiringCommonNameAndDate} | ||
{expiringConditionalClose} | ||
{agingConditionalOpen} | ||
Aging cert count: {agingCount} | ||
Aging Certificates: {agingCommonNameAndDate} | ||
{agingConditionalClose} | ||
`, | ||
values: { | ||
count: '{{state.count}}', | ||
expiringCount: '{{state.expiringCount}}', | ||
expiringCommonNameAndDate: '{{state.expiringCommonNameAndDate}}', | ||
expiringConditionalOpen: '{{#state.hasExpired}}', | ||
expiringConditionalClose: '{{/state.hasExpired}}', | ||
agingCount: '{{state.agingCount}}', | ||
agingCommonNameAndDate: '{{state.agingCommonNameAndDate}}', | ||
agingConditionalOpen: '{{#state.hasAging}}', | ||
agingConditionalClose: '{{/state.hasAging}}', | ||
}, | ||
}), | ||
name: i18n.translate('xpack.uptime.alerts.tls.clientName', { | ||
defaultMessage: 'Uptime TLS', | ||
}), | ||
description: i18n.translate('xpack.uptime.alerts.tls.description', { | ||
defaultMessage: 'Alert when the TLS certificate of an Uptime monitor is about to expire.', | ||
}), | ||
}; | ||
|
||
export const DurationAnomalyTranslations = { | ||
defaultActionMessage: i18n.translate('xpack.uptime.alerts.durationAnomaly.defaultActionMessage', { | ||
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}}', | ||
}, | ||
}), | ||
name: i18n.translate('xpack.uptime.alerts.durationAnomaly.clientName', { | ||
defaultMessage: 'Uptime Duration Anomaly', | ||
}), | ||
description: i18n.translate('xpack.uptime.alerts.durationAnomaly.description', { | ||
defaultMessage: 'Alert when the Uptime monitor duration is anaomalous.', | ||
}), | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,24 +1,41 @@ | ||
{ | ||
"configPath": ["xpack", "uptime"], | ||
"configPath": [ | ||
"xpack", | ||
"uptime" | ||
], | ||
"id": "uptime", | ||
"kibanaVersion": "kibana", | ||
"optionalPlugins": ["data", "home", "ml", "fleet"], | ||
"optionalPlugins": [ | ||
"data", | ||
"home", | ||
"ml", | ||
"fleet" | ||
], | ||
"requiredPlugins": [ | ||
"alerting", | ||
"embeddable", | ||
"features", | ||
"licensing", | ||
"triggersActionsUi", | ||
"usageCollection", | ||
"ruleRegistry", | ||
"observability" | ||
], | ||
"server": true, | ||
"ui": true, | ||
"version": "8.0.0", | ||
"requiredBundles": ["observability", "kibanaReact", "kibanaUtils", "home", "data", "ml", "fleet"], | ||
"requiredBundles": [ | ||
"observability", | ||
"kibanaReact", | ||
"kibanaUtils", | ||
"home", | ||
"data", | ||
"ml", | ||
"fleet" | ||
], | ||
"owner": { | ||
"name": "Uptime", | ||
"githubTeam": "uptime" | ||
}, | ||
"description": "This plugin visualizes data from Synthetics and Heartbeat, and integrates with other Observability solutions." | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,7 +4,6 @@ | |
* 2.0; you may not use this file except in compliance with the Elastic License | ||
* 2.0. | ||
*/ | ||
|
||
import { | ||
CoreSetup, | ||
CoreStart, | ||
|
@@ -29,7 +28,7 @@ import { | |
DataPublicPluginSetup, | ||
DataPublicPluginStart, | ||
} from '../../../../../src/plugins/data/public'; | ||
import { alertTypeInitializers } from '../lib/alert_types'; | ||
import { alertTypeInitializers, legacyAlertTypeInitializers } from '../lib/alert_types'; | ||
import { FleetStart } from '../../../fleet/public'; | ||
import { | ||
FetchDataParams, | ||
|
@@ -141,6 +140,36 @@ export class UptimePlugin | |
) | ||
); | ||
|
||
const { observabilityRuleTypeRegistry } = plugins.observability; | ||
|
||
core.getStartServices().then(([coreStart, clientPluginsStart]) => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. our alert initializers depend on coreStart and corePlugins, so initializing async after fetching coreStart and corePluginsStart There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i am not sure why we moved thisfrom setup to start? in start we already have There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @shahzad31 you are right. However, |
||
alertTypeInitializers.forEach((init) => { | ||
const alertInitializer = init({ | ||
core: coreStart, | ||
plugins: clientPluginsStart, | ||
}); | ||
if ( | ||
clientPluginsStart.triggersActionsUi && | ||
!clientPluginsStart.triggersActionsUi.alertTypeRegistry.has(alertInitializer.id) | ||
) { | ||
observabilityRuleTypeRegistry.register(alertInitializer); | ||
} | ||
}); | ||
|
||
legacyAlertTypeInitializers.forEach((init) => { | ||
const alertInitializer = init({ | ||
core: coreStart, | ||
plugins: clientPluginsStart, | ||
}); | ||
if ( | ||
clientPluginsStart.triggersActionsUi && | ||
!clientPluginsStart.triggersActionsUi.alertTypeRegistry.has(alertInitializer.id) | ||
) { | ||
plugins.triggersActionsUi.alertTypeRegistry.register(alertInitializer); | ||
} | ||
}); | ||
}); | ||
|
||
core.application.register({ | ||
id: PLUGIN.ID, | ||
euiIconType: 'logoObservability', | ||
|
@@ -171,26 +200,12 @@ export class UptimePlugin | |
const [coreStart, corePlugins] = await core.getStartServices(); | ||
|
||
const { renderApp } = await import('./render_app'); | ||
|
||
return renderApp(coreStart, plugins, corePlugins, params); | ||
}, | ||
}); | ||
} | ||
|
||
public start(start: CoreStart, plugins: ClientPluginsStart): void { | ||
alertTypeInitializers.forEach((init) => { | ||
const alertInitializer = init({ | ||
core: start, | ||
plugins, | ||
}); | ||
if ( | ||
plugins.triggersActionsUi && | ||
!plugins.triggersActionsUi.alertTypeRegistry.has(alertInitializer.id) | ||
) { | ||
plugins.triggersActionsUi.alertTypeRegistry.register(alertInitializer); | ||
} | ||
}); | ||
|
||
if (plugins.fleet) { | ||
const { registerExtension } = plugins.fleet; | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0; you may not use this file except in compliance with the Elastic License | ||
* 2.0. | ||
*/ | ||
|
||
import { stringify } from 'querystring'; | ||
|
||
export const format = ({ | ||
pathname, | ||
query, | ||
}: { | ||
pathname: string; | ||
query: Record<string, any>; | ||
}): string => { | ||
return `${pathname}?${stringify(query)}`; | ||
}; | ||
|
||
export const getMonitorRouteFromMonitorId = ({ | ||
monitorId, | ||
dateRangeStart, | ||
dateRangeEnd, | ||
filters = {}, | ||
}: { | ||
monitorId: string; | ||
dateRangeStart: string; | ||
dateRangeEnd: string; | ||
filters?: Record<string, string[]>; | ||
}) => | ||
format({ | ||
pathname: `/app/uptime/monitor/${btoa(monitorId)}`, | ||
query: { | ||
dateRangeEnd, | ||
dateRangeStart, | ||
...(Object.keys(filters).length | ||
? { filters: JSON.stringify(Object.keys(filters).map((key) => [key, filters[key]])) } | ||
: {}), | ||
}, | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we need more fields for anomaly?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the majority of the anomaly fields have been transitioned to use RAC technical fields, as well as ecs fields listed in the
common
section. You can see the change in theanomaly_duration.ts
server file.