mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[APM] alert details - add alert start annotation to all visualizations (#184677)
## Summary Summarize your PR. If it involves visual changes include a screenshot or gif. SLO APM latency alert details page  SLO APM error rate alert details page  APM latency alert details page  ### Testing 1. Create an APM latency rule that fires. Navigate to the alert details page and confirm the annotations appear correctly. 2. Create an SLO burn rate rule for the APM latency SLI that fires. Navigate to the alert details page and confirm the annotations appear correctly 3. Create an SLO burn rate rule for the APM error rate SLI that fires. Navigate to the alert details page and confirm the annotations appear correctly --------- Co-authored-by: Carlos Crespo <crespocarlos@users.noreply.github.com>
This commit is contained in:
parent
7e344a766d
commit
9e52d98d2b
6 changed files with 101 additions and 47 deletions
|
@ -7,7 +7,6 @@
|
|||
/* Error Rate */
|
||||
|
||||
import React from 'react';
|
||||
import chroma from 'chroma-js';
|
||||
import {
|
||||
EuiFlexItem,
|
||||
EuiPanel,
|
||||
|
@ -16,13 +15,11 @@ import {
|
|||
EuiIconTip,
|
||||
RecursivePartial,
|
||||
useEuiTheme,
|
||||
transparentize,
|
||||
} from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { BoolQuery } from '@kbn/es-query';
|
||||
import { UI_SETTINGS } from '@kbn/data-plugin/public';
|
||||
import { Theme } from '@elastic/charts';
|
||||
import { AlertActiveTimeRangeAnnotation, AlertAnnotation } from '@kbn/observability-alert-details';
|
||||
import { useKibana } from '@kbn/kibana-react-plugin/public';
|
||||
import { DEFAULT_DATE_FORMAT } from './constants';
|
||||
import { useFetcher } from '../../../../hooks/use_fetcher';
|
||||
|
@ -36,6 +33,7 @@ import { usePreferredDataSourceAndBucketSize } from '../../../../hooks/use_prefe
|
|||
import { ApmDocumentType } from '../../../../../common/document_type';
|
||||
import { TransactionTypeSelect } from './transaction_type_select';
|
||||
import { ViewInAPMButton } from './view_in_apm_button';
|
||||
import { getAlertStartAnnotation } from './get_alert_start_annotation';
|
||||
|
||||
type ErrorRate =
|
||||
APIReturnType<'GET /internal/apm/services/{serviceName}/transactions/charts/error_rate'>;
|
||||
|
@ -75,12 +73,12 @@ function FailedTransactionChart({
|
|||
environment: string;
|
||||
start: string;
|
||||
end: string;
|
||||
alertStart?: number;
|
||||
alertEnd?: number;
|
||||
comparisonChartTheme: RecursivePartial<Theme>;
|
||||
timeZone: string;
|
||||
kuery?: string;
|
||||
filters?: BoolQuery;
|
||||
alertStart?: number;
|
||||
alertEnd?: number;
|
||||
}) {
|
||||
const { euiTheme } = useEuiTheme();
|
||||
const {
|
||||
|
@ -151,25 +149,14 @@ function FailedTransactionChart({
|
|||
const showTransactionTypeSelect = setTransactionType && transactionTypes;
|
||||
const getFailedTransactionChartAdditionalData = () => {
|
||||
if (alertStart) {
|
||||
return [
|
||||
<AlertActiveTimeRangeAnnotation
|
||||
alertStart={alertStart}
|
||||
alertEnd={alertEnd}
|
||||
color={chroma(transparentize('#F04E981A', 0.2)).hex().toUpperCase()}
|
||||
id={'alertActiveRect'}
|
||||
key={'alertActiveRect'}
|
||||
/>,
|
||||
<AlertAnnotation
|
||||
key={'alertAnnotationStart'}
|
||||
id={'alertAnnotationStart'}
|
||||
alertStart={alertStart}
|
||||
color={euiTheme.colors.danger}
|
||||
dateFormat={
|
||||
(uiSettings && uiSettings.get(UI_SETTINGS.DATE_FORMAT)) || DEFAULT_DATE_FORMAT
|
||||
}
|
||||
/>,
|
||||
];
|
||||
return getAlertStartAnnotation({
|
||||
alertStart,
|
||||
alertEnd,
|
||||
color: euiTheme.colors.danger,
|
||||
dateFormat: (uiSettings && uiSettings.get(UI_SETTINGS.DATE_FORMAT)) || DEFAULT_DATE_FORMAT,
|
||||
});
|
||||
}
|
||||
return [];
|
||||
};
|
||||
return (
|
||||
<EuiFlexItem>
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* 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 React from 'react';
|
||||
import { AlertActiveTimeRangeAnnotation, AlertAnnotation } from '@kbn/observability-alert-details';
|
||||
|
||||
export function getAlertStartAnnotation({
|
||||
alertStart,
|
||||
alertEnd,
|
||||
dateFormat,
|
||||
color,
|
||||
}: {
|
||||
alertStart: number;
|
||||
alertEnd?: number;
|
||||
dateFormat: string;
|
||||
color: string;
|
||||
}) {
|
||||
return [
|
||||
<AlertActiveTimeRangeAnnotation
|
||||
alertStart={alertStart}
|
||||
alertEnd={alertEnd}
|
||||
color={color}
|
||||
id="alertActiveRect"
|
||||
key="alertActiveRect"
|
||||
/>,
|
||||
<AlertAnnotation
|
||||
key="alertAnnotationStart"
|
||||
id="alertAnnotationStart"
|
||||
alertStart={alertStart}
|
||||
color={color}
|
||||
dateFormat={dateFormat}
|
||||
/>,
|
||||
];
|
||||
}
|
|
@ -4,7 +4,7 @@
|
|||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import moment from 'moment';
|
||||
import { EuiFlexGroup, EuiFlexItem, EuiSpacer } from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { formatAlertEvaluationValue } from '@kbn/observability-plugin/public';
|
||||
|
@ -145,6 +145,8 @@ export function AlertDetailsAppSection({
|
|||
);
|
||||
}
|
||||
|
||||
const alertEnd = alert.fields[ALERT_END] ? moment(alert.fields[ALERT_END]).valueOf() : undefined;
|
||||
|
||||
return (
|
||||
<EuiFlexGroup direction="column" gutterSize="s">
|
||||
<TimeRangeMetadataContextProvider
|
||||
|
@ -179,6 +181,8 @@ export function AlertDetailsAppSection({
|
|||
environment={environment}
|
||||
start={from}
|
||||
end={to}
|
||||
alertStart={alert.start}
|
||||
alertEnd={alertEnd}
|
||||
comparisonChartTheme={comparisonChartTheme}
|
||||
comparisonEnabled={false}
|
||||
offset={''}
|
||||
|
@ -191,6 +195,8 @@ export function AlertDetailsAppSection({
|
|||
environment={environment}
|
||||
start={from}
|
||||
end={to}
|
||||
alertStart={alert.start}
|
||||
alertEnd={alertEnd}
|
||||
comparisonChartTheme={comparisonChartTheme}
|
||||
timeZone={timeZone}
|
||||
/>
|
||||
|
|
|
@ -15,10 +15,8 @@ import { getDurationFormatter } from '@kbn/observability-plugin/common';
|
|||
import { ALERT_RULE_TYPE_ID, ALERT_EVALUATION_THRESHOLD, ALERT_END } from '@kbn/rule-data-utils';
|
||||
import type { TopAlert } from '@kbn/observability-plugin/public';
|
||||
import {
|
||||
AlertActiveTimeRangeAnnotation,
|
||||
AlertThresholdAnnotation,
|
||||
AlertThresholdTimeRangeRect,
|
||||
AlertAnnotation,
|
||||
} from '@kbn/observability-alert-details';
|
||||
import { useEuiTheme } from '@elastic/eui';
|
||||
import { useKibana } from '@kbn/kibana-react-plugin/public';
|
||||
|
@ -41,6 +39,7 @@ import { usePreferredDataSourceAndBucketSize } from '../../../../hooks/use_prefe
|
|||
import { DEFAULT_DATE_FORMAT } from './constants';
|
||||
import { TransactionTypeSelect } from './transaction_type_select';
|
||||
import { ViewInAPMButton } from './view_in_apm_button';
|
||||
import { getAlertStartAnnotation } from './get_alert_start_annotation';
|
||||
|
||||
function LatencyChart({
|
||||
alert,
|
||||
|
@ -160,26 +159,20 @@ function LatencyChart({
|
|||
isLatencyThresholdRuleType(alert.fields[ALERT_RULE_TYPE_ID]) ||
|
||||
customAlertEvaluationThreshold
|
||||
) {
|
||||
return [
|
||||
<AlertActiveTimeRangeAnnotation
|
||||
alertStart={alert.start}
|
||||
alertEnd={alertEnd}
|
||||
color={euiTheme.colors.danger}
|
||||
id={'alertActiveRect'}
|
||||
key={'alertActiveRect'}
|
||||
/>,
|
||||
<AlertAnnotation
|
||||
key={'alertAnnotationStart'}
|
||||
id={'alertAnnotationStart'}
|
||||
alertStart={alert.start}
|
||||
color={euiTheme.colors.danger}
|
||||
dateFormat={
|
||||
(uiSettings && uiSettings.get(UI_SETTINGS.DATE_FORMAT)) || DEFAULT_DATE_FORMAT
|
||||
}
|
||||
/>,
|
||||
...alertEvalThresholdChartData,
|
||||
];
|
||||
return [...alertEvalThresholdChartData];
|
||||
}
|
||||
return [];
|
||||
};
|
||||
const getLatencyChartAlertStartData = () => {
|
||||
if (alert.start) {
|
||||
return getAlertStartAnnotation({
|
||||
alertStart: alert.start,
|
||||
alertEnd,
|
||||
color: euiTheme.colors.danger,
|
||||
dateFormat: (uiSettings && uiSettings.get(UI_SETTINGS.DATE_FORMAT)) || DEFAULT_DATE_FORMAT,
|
||||
});
|
||||
}
|
||||
return [];
|
||||
};
|
||||
const memoizedData = useMemo(
|
||||
() =>
|
||||
|
@ -247,7 +240,7 @@ function LatencyChart({
|
|||
</EuiFlexGroup>
|
||||
<TimeseriesChart
|
||||
id="latencyChart"
|
||||
annotations={getLatencyChartAdditionalData()}
|
||||
annotations={[...getLatencyChartAdditionalData(), ...getLatencyChartAlertStartData()]}
|
||||
height={200}
|
||||
comparisonEnabled={comparisonEnabled}
|
||||
offset={offset}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
import React from 'react';
|
||||
import { Theme } from '@elastic/charts';
|
||||
import { BoolQuery } from '@kbn/es-query';
|
||||
import { UI_SETTINGS } from '@kbn/data-plugin/public';
|
||||
import {
|
||||
RecursivePartial,
|
||||
EuiFlexItem,
|
||||
|
@ -15,7 +16,9 @@ import {
|
|||
EuiFlexGroup,
|
||||
EuiTitle,
|
||||
EuiIconTip,
|
||||
useEuiTheme,
|
||||
} from '@elastic/eui';
|
||||
import { useKibana } from '@kbn/kibana-react-plugin/public';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
import { ChartType, getTimeSeriesColor } from '../../../shared/charts/helper/get_timeseries_color';
|
||||
|
@ -26,6 +29,8 @@ import { ApmDocumentType } from '../../../../../common/document_type';
|
|||
import { asExactTransactionRate } from '../../../../../common/utils/formatters';
|
||||
import { TransactionTypeSelect } from './transaction_type_select';
|
||||
import { ViewInAPMButton } from './view_in_apm_button';
|
||||
import { getAlertStartAnnotation } from './get_alert_start_annotation';
|
||||
import { DEFAULT_DATE_FORMAT } from './constants';
|
||||
|
||||
const INITIAL_STATE = {
|
||||
currentPeriod: [],
|
||||
|
@ -40,6 +45,8 @@ function ThroughputChart({
|
|||
environment,
|
||||
start,
|
||||
end,
|
||||
alertStart,
|
||||
alertEnd,
|
||||
comparisonChartTheme,
|
||||
comparisonEnabled,
|
||||
offset,
|
||||
|
@ -55,6 +62,8 @@ function ThroughputChart({
|
|||
environment: string;
|
||||
start: string;
|
||||
end: string;
|
||||
alertStart?: number;
|
||||
alertEnd?: number;
|
||||
comparisonChartTheme: RecursivePartial<Theme>;
|
||||
comparisonEnabled: boolean;
|
||||
offset: string;
|
||||
|
@ -62,6 +71,10 @@ function ThroughputChart({
|
|||
kuery?: string;
|
||||
filters?: BoolQuery;
|
||||
}) {
|
||||
const { euiTheme } = useEuiTheme();
|
||||
const {
|
||||
services: { uiSettings },
|
||||
} = useKibana();
|
||||
const preferred = usePreferredDataSourceAndBucketSize({
|
||||
start,
|
||||
end,
|
||||
|
@ -129,6 +142,17 @@ function ThroughputChart({
|
|||
]
|
||||
: []),
|
||||
];
|
||||
const getThroughputChartAdditionalData = () => {
|
||||
if (alertStart) {
|
||||
return getAlertStartAnnotation({
|
||||
alertStart,
|
||||
alertEnd,
|
||||
color: euiTheme.colors.danger,
|
||||
dateFormat: (uiSettings && uiSettings.get(UI_SETTINGS.DATE_FORMAT)) || DEFAULT_DATE_FORMAT,
|
||||
});
|
||||
}
|
||||
return [];
|
||||
};
|
||||
|
||||
const showTransactionTypeSelect = setTransactionType && transactionTypes;
|
||||
|
||||
|
@ -190,6 +214,7 @@ function ThroughputChart({
|
|||
timeseries={timeseriesThroughput}
|
||||
yLabelFormat={asExactTransactionRate}
|
||||
timeZone={timeZone}
|
||||
annotations={getThroughputChartAdditionalData()}
|
||||
/>
|
||||
</EuiPanel>
|
||||
</EuiFlexItem>
|
||||
|
|
|
@ -4,8 +4,9 @@
|
|||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import moment from 'moment';
|
||||
import React from 'react';
|
||||
import { ALERT_END } from '@kbn/rule-data-utils';
|
||||
import { ENVIRONMENT_ALL } from '../../../../common/environment_filter_values';
|
||||
import ThroughputChart from '../../../components/alerting/ui_components/alert_details_app_section/throughput_chart';
|
||||
import { EmbeddableApmAlertingVizProps } from '../types';
|
||||
|
@ -15,6 +16,7 @@ import { ServiceNameCallout } from '../service_name_callout';
|
|||
|
||||
export function APMAlertingThroughputChart({
|
||||
rule,
|
||||
alert,
|
||||
rangeFrom = 'now-15m',
|
||||
rangeTo = 'now',
|
||||
transactionName,
|
||||
|
@ -46,6 +48,8 @@ export function APMAlertingThroughputChart({
|
|||
return <ServiceNameCallout />;
|
||||
}
|
||||
|
||||
const alertEnd = alert.fields[ALERT_END] ? moment(alert.fields[ALERT_END]).valueOf() : undefined;
|
||||
|
||||
return (
|
||||
<ThroughputChart
|
||||
transactionType={currentTransactionType}
|
||||
|
@ -56,6 +60,8 @@ export function APMAlertingThroughputChart({
|
|||
environment={environment}
|
||||
start={rangeFrom}
|
||||
end={rangeTo}
|
||||
alertStart={alert.start}
|
||||
alertEnd={alertEnd}
|
||||
comparisonChartTheme={comparisonChartTheme}
|
||||
timeZone={timeZone}
|
||||
comparisonEnabled={false}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue