Skip to content

Commit

Permalink
[8.x] [Alert details page] Update source and status bar (#194842) (#1…
Browse files Browse the repository at this point in the history
…95096)

# Backport

This will backport the following commits from `main` to `8.x`:
- [[Alert details page] Update source and status bar
(#194842)](#194842)

<!--- Backport version: 9.4.3 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)

<!--BACKPORT [{"author":{"name":"Maryam
Saeidi","email":"[email protected]"},"sourceCommit":{"committedDate":"2024-10-04T14:52:07Z","message":"[Alert
details page] Update source and status bar (#194842)\n\nCloses
#187110\r\nCloses #187111\r\nCloses #153834\r\n\r\n##
Summary\r\n\r\nThis PR changes how we show source and alert status
information, as\r\nshown
below:\r\n\r\n\r\n![image](https://github.com/user-attachments/assets/7ab12e3a-f2e4-4bf8-8b47-955e2e1bb47f)\r\n\r\nAlso,
for the APM Latency rule type, we now have a threshold
component\r\nsimilar to other rules. For the SLO burn rate rule, the SLO
link is\r\nadded to the source list.\r\n\r\n|Rule
type|Screenshot|\r\n|---|---|\r\n|APM\r\nLatency|![image](https://github.com/user-attachments/assets/9846570a-46db-46a7-b3a0-96a1e63b58ad)|\r\n|SLO
burn\r\nrate|![image](https://github.com/user-attachments/assets/e0042a8a-e1c0-4dc0-a909-73140e8a0b21)|\r\n\r\n---------\r\n\r\nCo-authored-by:
kibanamachine
<[email protected]>","sha":"1a54aabd6d1806fbdd5309da9b06fefdd4fe0689","branchLabelMapping":{"^v9.0.0$":"main","^v8.16.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:skip","v9.0.0","backport:prev-minor","Feature:Alert
Details
Page","ci:project-deploy-observability","Team:obs-ux-infra_services","Team:obs-ux-management","rca"],"title":"[Alert
details page] Update source and status
bar","number":194842,"url":"https://github.com/elastic/kibana/pull/194842","mergeCommit":{"message":"[Alert
details page] Update source and status bar (#194842)\n\nCloses
#187110\r\nCloses #187111\r\nCloses #153834\r\n\r\n##
Summary\r\n\r\nThis PR changes how we show source and alert status
information, as\r\nshown
below:\r\n\r\n\r\n![image](https://github.com/user-attachments/assets/7ab12e3a-f2e4-4bf8-8b47-955e2e1bb47f)\r\n\r\nAlso,
for the APM Latency rule type, we now have a threshold
component\r\nsimilar to other rules. For the SLO burn rate rule, the SLO
link is\r\nadded to the source list.\r\n\r\n|Rule
type|Screenshot|\r\n|---|---|\r\n|APM\r\nLatency|![image](https://github.com/user-attachments/assets/9846570a-46db-46a7-b3a0-96a1e63b58ad)|\r\n|SLO
burn\r\nrate|![image](https://github.com/user-attachments/assets/e0042a8a-e1c0-4dc0-a909-73140e8a0b21)|\r\n\r\n---------\r\n\r\nCo-authored-by:
kibanamachine
<[email protected]>","sha":"1a54aabd6d1806fbdd5309da9b06fefdd4fe0689"}},"sourceBranch":"main","suggestedTargetBranches":[],"targetPullRequestStates":[{"branch":"main","label":"v9.0.0","branchLabelMappingKey":"^v9.0.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/194842","number":194842,"mergeCommit":{"message":"[Alert
details page] Update source and status bar (#194842)\n\nCloses
#187110\r\nCloses #187111\r\nCloses #153834\r\n\r\n##
Summary\r\n\r\nThis PR changes how we show source and alert status
information, as\r\nshown
below:\r\n\r\n\r\n![image](https://github.com/user-attachments/assets/7ab12e3a-f2e4-4bf8-8b47-955e2e1bb47f)\r\n\r\nAlso,
for the APM Latency rule type, we now have a threshold
component\r\nsimilar to other rules. For the SLO burn rate rule, the SLO
link is\r\nadded to the source list.\r\n\r\n|Rule
type|Screenshot|\r\n|---|---|\r\n|APM\r\nLatency|![image](https://github.com/user-attachments/assets/9846570a-46db-46a7-b3a0-96a1e63b58ad)|\r\n|SLO
burn\r\nrate|![image](https://github.com/user-attachments/assets/e0042a8a-e1c0-4dc0-a909-73140e8a0b21)|\r\n\r\n---------\r\n\r\nCo-authored-by:
kibanamachine
<[email protected]>","sha":"1a54aabd6d1806fbdd5309da9b06fefdd4fe0689"}}]}]
BACKPORT-->

Co-authored-by: Maryam Saeidi <[email protected]>
  • Loading branch information
kibanamachine and maryam-saeidi authored Oct 4, 2024
1 parent 9920506 commit 65df46b
Show file tree
Hide file tree
Showing 37 changed files with 489 additions and 483 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,11 @@
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import { SettingsSpec } from '@elastic/charts';

export const DEFAULT_DATE_FORMAT = 'HH:mm:ss';
export const CHART_ANNOTATION_RED_COLOR = '#BD271E';
export const CHART_SETTINGS: Partial<SettingsSpec> = {
showLegend: false,
};
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ 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 { CHART_SETTINGS, DEFAULT_DATE_FORMAT } from './constants';
import { useFetcher } from '../../../../hooks/use_fetcher';
import { ChartType } from '../../../shared/charts/helper/get_timeseries_color';
import * as get_timeseries_color from '../../../shared/charts/helper/get_timeseries_color';
Expand Down Expand Up @@ -226,6 +226,7 @@ function FailedTransactionChart({
comparisonEnabled={false}
customTheme={comparisonChartTheme}
timeZone={timeZone}
settings={CHART_SETTINGS}
/>
</EuiPanel>
</EuiFlexItem>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,22 @@
* 2.0.
*/

import React from 'react';
import { EuiFlexGroup, EuiFlexItem, EuiSpacer } from '@elastic/eui';
import { COMPARATORS } from '@kbn/alerting-comparators';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n-react';
import { formatAlertEvaluationValue } from '@kbn/observability-plugin/public';
import { useKibana } from '@kbn/kibana-react-plugin/public';
import { formatAlertEvaluationValue, Threshold } from '@kbn/observability-plugin/public';
import { useChartThemes } from '@kbn/observability-shared-plugin/public';
import { getPaddedAlertTimeRange } from '@kbn/observability-get-padded-alert-time-range-util';
import {
ALERT_END,
ALERT_EVALUATION_THRESHOLD,
ALERT_EVALUATION_VALUE,
ALERT_RULE_TYPE_ID,
ALERT_START,
} from '@kbn/rule-data-utils';
import React, { useEffect } from 'react';
import { useKibana } from '@kbn/kibana-react-plugin/public';
import { getPaddedAlertTimeRange } from '@kbn/observability-get-padded-alert-time-range-util';
import { EuiCallOut } from '@elastic/eui';
import { CoreStart } from '@kbn/core/public';
import {
Expand All @@ -36,12 +39,7 @@ import ThroughputChart from './throughput_chart';
import { AlertDetailsAppSectionProps } from './types';
import { createCallApmApi } from '../../../../services/rest/create_call_apm_api';

export function AlertDetailsAppSection({
rule,
alert,
timeZone,
setAlertSummaryFields,
}: AlertDetailsAppSectionProps) {
export function AlertDetailsAppSection({ rule, alert, timeZone }: AlertDetailsAppSectionProps) {
const { services } = useKibana();
createCallApmApi(services as CoreStart);

Expand All @@ -54,42 +52,25 @@ export function AlertDetailsAppSection({
const transactionName = alert.fields[TRANSACTION_NAME];
const transactionType = alert.fields[TRANSACTION_TYPE];

useEffect(() => {
const alertSummaryFields = [
{
label: (
<FormattedMessage
id="xpack.apm.pages.alertDetails.alertSummary.actualValue"
defaultMessage="Actual value"
/>
),
value: formatAlertEvaluationValue(alertRuleTypeId, alertEvaluationValue),
},
{
label: (
<FormattedMessage
id="xpack.apm.pages.alertDetails.alertSummary.expectedValue"
defaultMessage="Expected value"
/>
),
value: formatAlertEvaluationValue(alertRuleTypeId, alertEvaluationThreshold),
},
];
setAlertSummaryFields(alertSummaryFields);
}, [
alertRuleTypeId,
alertEvaluationValue,
alertEvaluationThreshold,
environment,
serviceName,
transactionName,
setAlertSummaryFields,
]);

const params = rule.params;
const latencyAggregationType = getAggsTypeFromRule(params.aggregationType);
const timeRange = getPaddedAlertTimeRange(alert.fields[ALERT_START]!, alert.fields[ALERT_END]);
const comparisonChartTheme = getComparisonChartTheme();
const chartThemes = useChartThemes();
const thresholdComponent =
alertEvaluationValue && alertEvaluationThreshold ? (
<Threshold
chartProps={chartThemes}
id="latency-threshold"
threshold={[alertEvaluationThreshold]}
value={alertEvaluationValue}
valueFormatter={(d: number) => String(formatAlertEvaluationValue(alertRuleTypeId, d))}
title={i18n.translate('xpack.apm.alertDetails.thresholdTitle', {
defaultMessage: 'Threshold breached',
})}
comparator={COMPARATORS.GREATER_THAN}
/>
) : undefined;

const { from, to } = timeRange;
if (!from || !to) {
Expand Down Expand Up @@ -138,6 +119,7 @@ export function AlertDetailsAppSection({
latencyAggregationType={latencyAggregationType}
comparisonEnabled={false}
offset={''}
threshold={thresholdComponent}
/>
<EuiSpacer size="s" />
<EuiFlexGroup direction="row" gutterSize="s">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import { Theme } from '@elastic/charts';
import { RecursivePartial } from '@elastic/eui';
import React, { useMemo } from 'react';
import React, { useMemo, ReactElement } from 'react';
import { EuiFlexItem, EuiPanel, EuiFlexGroup, EuiTitle } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { BoolQuery } from '@kbn/es-query';
Expand Down Expand Up @@ -38,7 +38,7 @@ import { LatencyAggregationType } from '../../../../../common/latency_aggregatio
import { isLatencyThresholdRuleType } from './helpers';
import { ApmDocumentType } from '../../../../../common/document_type';
import { usePreferredDataSourceAndBucketSize } from '../../../../hooks/use_preferred_data_source_and_bucket_size';
import { DEFAULT_DATE_FORMAT } from './constants';
import { CHART_SETTINGS, DEFAULT_DATE_FORMAT } from './constants';
import { TransactionTypeSelect } from './transaction_type_select';
import { ViewInAPMButton } from './view_in_apm_button';

Expand All @@ -61,6 +61,7 @@ function LatencyChart({
customAlertEvaluationThreshold,
kuery = '',
filters,
threshold,
}: {
alert: TopAlert;
transactionType: string;
Expand All @@ -78,6 +79,7 @@ function LatencyChart({
offset: string;
timeZone: string;
customAlertEvaluationThreshold?: number;
threshold?: ReactElement;
kuery?: string;
filters?: BoolQuery;
}) {
Expand Down Expand Up @@ -245,18 +247,28 @@ function LatencyChart({
</EuiFlexGroup>
</EuiFlexItem>
</EuiFlexGroup>
<TimeseriesChart
id="latencyChart"
annotations={getLatencyChartAdditionalData()}
height={200}
comparisonEnabled={comparisonEnabled}
offset={offset}
fetchStatus={status}
customTheme={comparisonChartTheme}
timeseries={timeseriesLatency}
yLabelFormat={getResponseTimeTickFormatter(latencyFormatter)}
timeZone={timeZone}
/>
<EuiFlexGroup direction="row" gutterSize="m">
{!!threshold && (
<EuiFlexItem style={{ minWidth: 180 }} grow={1}>
{threshold}
</EuiFlexItem>
)}
<EuiFlexItem grow={!!threshold ? 5 : undefined}>
<TimeseriesChart
id="latencyChart"
annotations={getLatencyChartAdditionalData()}
height={200}
comparisonEnabled={comparisonEnabled}
offset={offset}
fetchStatus={status}
customTheme={comparisonChartTheme}
timeseries={timeseriesLatency}
yLabelFormat={getResponseTimeTickFormatter(latencyFormatter)}
timeZone={timeZone}
settings={CHART_SETTINGS}
/>
</EuiFlexItem>
</EuiFlexGroup>
</EuiPanel>
</EuiFlexItem>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
EuiIconTip,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { CHART_SETTINGS } from './constants';

import { ChartType, getTimeSeriesColor } from '../../../shared/charts/helper/get_timeseries_color';
import { useFetcher } from '../../../../hooks/use_fetcher';
Expand Down Expand Up @@ -190,6 +191,7 @@ function ThroughputChart({
timeseries={timeseriesThroughput}
yLabelFormat={asExactTransactionRate}
timeZone={timeZone}
settings={CHART_SETTINGS}
/>
</EuiPanel>
</EuiFlexItem>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
*/

import type { Rule } from '@kbn/alerting-plugin/common';
import type { TopAlert, AlertSummaryField } from '@kbn/observability-plugin/public';
import type { TopAlert } from '@kbn/observability-plugin/public';
import type { TIME_UNITS } from '@kbn/triggers-actions-ui-plugin/public';
import type {
SERVICE_NAME,
Expand All @@ -28,5 +28,4 @@ export interface AlertDetailsAppSectionProps {
[SERVICE_ENVIRONMENT]: string;
}>;
timeZone: string;
setAlertSummaryFields: React.Dispatch<React.SetStateAction<AlertSummaryField[] | undefined>>;
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
XYBrushEvent,
XYChartSeriesIdentifier,
Tooltip,
SettingsSpec,
} from '@elastic/charts';
import { EuiFlexGroup, EuiFlexItem, EuiIcon, EuiSpacer } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
Expand All @@ -46,11 +47,13 @@ const END_ZONE_LABEL = i18n.translate('xpack.apm.timeseries.endzone', {
defaultMessage:
'The selected time range does not include this entire bucket. It might contain partial data.',
});

interface TimeseriesChartProps extends TimeseriesChartWithContextProps {
comparisonEnabled: boolean;
offset?: string;
timeZone: string;
annotations?: Array<ReactElement<typeof RectAnnotation | typeof LineAnnotation>>;
settings?: Partial<SettingsSpec>;
}
export function TimeseriesChart({
id,
Expand All @@ -68,6 +71,7 @@ export function TimeseriesChart({
offset,
timeZone,
annotations,
settings,
}: TimeseriesChartProps) {
const history = useHistory();
const { chartRef, updatePointerEvent } = useChartPointerEventContext();
Expand Down Expand Up @@ -186,6 +190,7 @@ export function TimeseriesChart({
}
}}
locale={i18n.getLocale()}
{...settings}
/>
<Axis
id="x-axis"
Expand Down
1 change: 1 addition & 0 deletions x-pack/plugins/observability_solution/apm/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@
"@kbn/aiops-log-rate-analysis",
"@kbn/router-utils",
"@kbn/react-hooks",
"@kbn/alerting-comparators",
],
"exclude": ["target/**/*"]
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,10 @@
*/

import { Rule } from '@kbn/alerting-plugin/common';
import { AlertSummaryField, TopAlert } from '@kbn/observability-plugin/public';
import { TopAlert } from '@kbn/observability-plugin/public';
import { PartialRuleParams } from '../../../../../common/alerting/logs/log_threshold';

export interface AlertDetailsAppSectionProps {
rule: Rule<PartialRuleParams>;
alert: TopAlert<Record<string, any>>;
setAlertSummaryFields: React.Dispatch<React.SetStateAction<AlertSummaryField[] | undefined>>;
}
Original file line number Diff line number Diff line change
Expand Up @@ -69,15 +69,13 @@ jest.mock('../../../hooks/use_kibana', () => ({

describe('AlertDetailsAppSection', () => {
const queryClient = new QueryClient();
const mockedSetAlertSummaryFields = jest.fn();
const renderComponent = () => {
return render(
<IntlProvider locale="en">
<QueryClientProvider client={queryClient}>
<AlertDetailsAppSection
alert={buildMetricThresholdAlert()}
rule={buildMetricThresholdRule()}
setAlertSummaryFields={mockedSetAlertSummaryFields}
/>
</QueryClientProvider>
</IntlProvider>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import {
} from '@elastic/eui';
import chroma from 'chroma-js';

import { AlertSummaryField, RuleConditionChart, TopAlert } from '@kbn/observability-plugin/public';
import { RuleConditionChart, TopAlert } from '@kbn/observability-plugin/public';
import { ALERT_END, ALERT_START, ALERT_EVALUATION_VALUES, ALERT_GROUP } from '@kbn/rule-data-utils';
import { Rule, RuleTypeParams } from '@kbn/alerting-plugin/common';
import { getPaddedAlertTimeRange } from '@kbn/observability-get-padded-alert-time-range-util';
Expand Down Expand Up @@ -57,10 +57,9 @@ export type MetricThresholdAlert = TopAlert<MetricThresholdAlertField>;
interface AppSectionProps {
alert: MetricThresholdAlert;
rule: MetricThresholdRule;
setAlertSummaryFields: React.Dispatch<React.SetStateAction<AlertSummaryField[] | undefined>>;
}

export function AlertDetailsAppSection({ alert, rule, setAlertSummaryFields }: AppSectionProps) {
export function AlertDetailsAppSection({ alert, rule }: AppSectionProps) {
const { charts } = useKibanaContextForPlugin().services;
const { euiTheme } = useEuiTheme();
const groups = alert.fields[ALERT_GROUP];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,33 @@
import { ALERT_GROUP_FIELD, ALERT_GROUP_VALUE, ALERT_GROUP } from '@kbn/rule-data-utils';
import { TopAlert } from '../../typings/alerts';
import { apmSources, infraSources } from './get_alert_source_links';
import { Group } from '../../../common/typings';

interface AlertFields {
[key: string]: any;
}

export const getSources = (alert: TopAlert) => {
const isGroup = (item: Group | undefined): item is Group => {
return !!item;
};

export const getSources = (alert: TopAlert): Group[] => {
// when `kibana.alert.group` is not flattened (for alert detail pages)
if (alert.fields[ALERT_GROUP]) return alert.fields[ALERT_GROUP];
if (alert.fields[ALERT_GROUP]) return alert.fields[ALERT_GROUP] as Group[];

// when `kibana.alert.group` is flattened (for alert flyout)
const groupsFromGroupFields = alert.fields[ALERT_GROUP_FIELD]?.map((field, index) => {
const values = alert.fields[ALERT_GROUP_VALUE];
if (values?.length && values[index]) {
return { field, value: values[index] };
const group: Group = { field, value: values[index] };
return group;
}
});
}).filter(isGroup);

if (groupsFromGroupFields?.length) return groupsFromGroupFields;

// Not all rules has group.fields, in that case we search in the alert fields.
const matchedSources: Array<{ field: string; value: any }> = [];
const matchedSources: Group[] = [];
const ALL_SOURCES = [...infraSources, ...apmSources];
const alertFields = alert.fields as AlertFields;
ALL_SOURCES.forEach((source: string) => {
Expand Down
Loading

0 comments on commit 65df46b

Please sign in to comment.