-
Notifications
You must be signed in to change notification settings - Fork 8.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[SLO] Set "budget consumed mode" as the default mode for burn rate ru…
…le configuration (#171433) ## Summary This PR sets the "budget consumed" mode as the default mode for configuring the SLO Burn Rate Rule. This PR also adds a time table to help the user understand when they can expect their SLO to fire based on the burn rate windows and sample error rates. <img width="549" alt="image" src="https://github.com/elastic/kibana/assets/41702/01035b5d-60b9-40c8-9034-7ecd6a904bd5"> --------- Co-authored-by: Kibana Machine <[email protected]>
- Loading branch information
1 parent
d922ae0
commit 426d8ac
Showing
4 changed files
with
231 additions
and
20 deletions.
There are no files selected for viewing
101 changes: 101 additions & 0 deletions
101
x-pack/plugins/observability/public/components/burn_rate_rule_editor/alert_time_table.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
/* | ||
* 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 { EuiBasicTable, EuiSpacer, EuiText, EuiTitle, HorizontalAlignment } from '@elastic/eui'; | ||
import { SLOResponse } from '@kbn/slo-schema'; | ||
import React from 'react'; | ||
import { i18n } from '@kbn/i18n'; | ||
import numeral from '@elastic/numeral'; | ||
import { WindowSchema } from '../../typings'; | ||
import { toDuration, toMinutes } from '../../utils/slo/duration'; | ||
|
||
interface AlertTimeTableProps { | ||
slo: SLOResponse; | ||
windows: WindowSchema[]; | ||
} | ||
|
||
const ERROR_RATES = [0.01, 0.1, 0.2, 0.5, 1]; | ||
|
||
function formatTime(minutes: number) { | ||
if (minutes > 59) { | ||
const mins = minutes % 60; | ||
const hours = (minutes - mins) / 60; | ||
return i18n.translate('xpack.observability.slo.rules.timeTable.minuteHoursLabel', { | ||
defaultMessage: '{hours}h {mins}m', | ||
values: { hours, mins }, | ||
}); | ||
} | ||
return i18n.translate('xpack.observability.slo.rules.timeTable.minuteLabel', { | ||
defaultMessage: '{minutes}m', | ||
values: { minutes }, | ||
}); | ||
} | ||
|
||
export function AlertTimeTable({ windows, slo }: AlertTimeTableProps) { | ||
const rows = ERROR_RATES.map((rate) => { | ||
const windowTimes = windows.reduce((acc, windowDef, index) => { | ||
const windowInMinutes = toMinutes( | ||
toDuration(`${windowDef.longWindow.value}${windowDef.longWindow.unit}`) | ||
); | ||
const timeInMinutes = Math.round( | ||
((1 - slo.objective.target) / rate) * windowInMinutes * windowDef.burnRateThreshold | ||
); | ||
return { | ||
...acc, | ||
[`column_${index + 1}`]: timeInMinutes < windowInMinutes ? timeInMinutes : null, | ||
}; | ||
}, {}); | ||
return { rate, ...windowTimes }; | ||
}) as Array<{ rate: number } & WindowSchema>; | ||
|
||
const columns = [ | ||
{ | ||
field: 'rate', | ||
name: i18n.translate('xpack.observability.slo.rules.timeTable.rateColumnLabel', { | ||
defaultMessage: 'Error rate', | ||
}), | ||
render: (rate: number) => numeral(rate).format('0%'), | ||
}, | ||
...windows.map((windowDef, index) => ({ | ||
field: `column_${index + 1}`, | ||
name: `${windowDef.longWindow.value}h @ ${numeral(windowDef.burnRateThreshold).format( | ||
'0[.0]' | ||
)}x`, | ||
align: 'right' as HorizontalAlignment, | ||
render: (time: number | null) => (time ? formatTime(time) : '-'), | ||
})), | ||
]; | ||
return ( | ||
<> | ||
<EuiTitle size="xs"> | ||
<h5> | ||
{i18n.translate('xpack.observability.slo.rules.timeTable.title', { | ||
defaultMessage: 'How long will it take for the alert to fire?', | ||
})} | ||
</h5> | ||
</EuiTitle> | ||
<EuiSpacer size="s" /> | ||
<EuiText size="s"> | ||
<p> | ||
{i18n.translate('xpack.observability.slo.rules.timeTable.description', { | ||
defaultMessage: | ||
'The table below lists the error rates and approximately how long it would take to receive your first alert with the current configuration.', | ||
})} | ||
</p> | ||
</EuiText> | ||
<EuiSpacer size="m" /> | ||
<EuiBasicTable<{ rate: number } & WindowSchema> | ||
tableCaption={i18n.translate('xpack.observability.slo.rules.tableCaption', { | ||
defaultMessage: 'Alerting time table', | ||
})} | ||
items={rows} | ||
columns={columns} | ||
/> | ||
<EuiSpacer size="l" /> | ||
</> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
107 changes: 107 additions & 0 deletions
107
x-pack/plugins/observability/public/components/burn_rate_rule_editor/constants.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
/* | ||
* 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 { | ||
ALERT_ACTION, | ||
HIGH_PRIORITY_ACTION, | ||
LOW_PRIORITY_ACTION, | ||
MEDIUM_PRIORITY_ACTION, | ||
} from '../../../common/constants'; | ||
|
||
import { WindowSchema } from '../../typings'; | ||
|
||
type PartialWindowSchema = Partial<WindowSchema>; | ||
|
||
const WEEKLY: PartialWindowSchema[] = [ | ||
{ | ||
burnRateThreshold: 3.36, | ||
longWindow: { value: 1, unit: 'h' }, | ||
shortWindow: { value: 5, unit: 'm' }, | ||
actionGroup: ALERT_ACTION.id, | ||
}, | ||
{ | ||
burnRateThreshold: 1.4, | ||
longWindow: { value: 6, unit: 'h' }, | ||
shortWindow: { value: 30, unit: 'm' }, | ||
actionGroup: HIGH_PRIORITY_ACTION.id, | ||
}, | ||
{ | ||
burnRateThreshold: 0.7, | ||
longWindow: { value: 24, unit: 'h' }, | ||
shortWindow: { value: 120, unit: 'm' }, | ||
actionGroup: MEDIUM_PRIORITY_ACTION.id, | ||
}, | ||
{ | ||
burnRateThreshold: 0.234, | ||
longWindow: { value: 72, unit: 'h' }, | ||
shortWindow: { value: 260, unit: 'm' }, | ||
actionGroup: LOW_PRIORITY_ACTION.id, | ||
}, | ||
]; | ||
|
||
const MONTHLY: PartialWindowSchema[] = [ | ||
{ | ||
burnRateThreshold: 14.4, | ||
longWindow: { value: 1, unit: 'h' }, | ||
shortWindow: { value: 5, unit: 'm' }, | ||
actionGroup: ALERT_ACTION.id, | ||
}, | ||
{ | ||
burnRateThreshold: 6, | ||
longWindow: { value: 6, unit: 'h' }, | ||
shortWindow: { value: 30, unit: 'm' }, | ||
actionGroup: HIGH_PRIORITY_ACTION.id, | ||
}, | ||
{ | ||
burnRateThreshold: 3, | ||
longWindow: { value: 24, unit: 'h' }, | ||
shortWindow: { value: 120, unit: 'm' }, | ||
actionGroup: MEDIUM_PRIORITY_ACTION.id, | ||
}, | ||
{ | ||
burnRateThreshold: 1, | ||
longWindow: { value: 72, unit: 'h' }, | ||
shortWindow: { value: 260, unit: 'm' }, | ||
actionGroup: LOW_PRIORITY_ACTION.id, | ||
}, | ||
]; | ||
|
||
const QUARTERLY: PartialWindowSchema[] = [ | ||
{ | ||
burnRateThreshold: 43.2, | ||
longWindow: { value: 1, unit: 'h' }, | ||
shortWindow: { value: 5, unit: 'm' }, | ||
actionGroup: ALERT_ACTION.id, | ||
}, | ||
{ | ||
burnRateThreshold: 18, | ||
longWindow: { value: 6, unit: 'h' }, | ||
shortWindow: { value: 30, unit: 'm' }, | ||
actionGroup: HIGH_PRIORITY_ACTION.id, | ||
}, | ||
{ | ||
burnRateThreshold: 9, | ||
longWindow: { value: 24, unit: 'h' }, | ||
shortWindow: { value: 120, unit: 'm' }, | ||
actionGroup: MEDIUM_PRIORITY_ACTION.id, | ||
}, | ||
{ | ||
burnRateThreshold: 3, | ||
longWindow: { value: 72, unit: 'h' }, | ||
shortWindow: { value: 260, unit: 'm' }, | ||
actionGroup: LOW_PRIORITY_ACTION.id, | ||
}, | ||
]; | ||
|
||
export const BURN_RATE_DEFAULTS: Record<string, PartialWindowSchema[]> = { | ||
// Calendar Aligned | ||
'1M': MONTHLY, | ||
'1w': WEEKLY, | ||
'90d': QUARTERLY, | ||
'30d': MONTHLY, | ||
'7d': WEEKLY, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters