Skip to content

Commit

Permalink
[8.x] [Alert details page] Use related alerts logic only for the cust…
Browse files Browse the repository at this point in the history
…om threshold rule (#193957) (#193991)

# Backport

This will backport the following commits from `main` to `8.x`:
- [[Alert details page] Use related alerts logic only for the custom
threshold rule (#193957)](#193957)

<!--- 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-09-25T12:43:52Z","message":"[Alert
details page] Use related alerts logic only for the custom threshold
rule (#193957)\n\nCloses #193943\r\n\r\n### Summary\r\n\r\nThis PR only
loads related alerts for the custom threshold rule and only\r\nwhen the
related rule has tags or group by fields.\r\n\r\nFor now, we don't show
this tab if there is no tag or group and there is\r\na follow-up ticket
for discussing the empty state for the related\r\nalerts.\r\n\r\n####
Follow-up work\r\n- https://github.com/elastic/kibana/issues/193952\r\n-
https://github.com/elastic/kibana/issues/193942","sha":"387afb782e44a0bf7de5549751e52fc7619c328a","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","ci:project-deploy-observability","Team:obs-ux-management"],"title":"[Alert
details page] Use related alerts logic only for the custom threshold
rule","number":193957,"url":"https://github.com/elastic/kibana/pull/193957","mergeCommit":{"message":"[Alert
details page] Use related alerts logic only for the custom threshold
rule (#193957)\n\nCloses #193943\r\n\r\n### Summary\r\n\r\nThis PR only
loads related alerts for the custom threshold rule and only\r\nwhen the
related rule has tags or group by fields.\r\n\r\nFor now, we don't show
this tab if there is no tag or group and there is\r\na follow-up ticket
for discussing the empty state for the related\r\nalerts.\r\n\r\n####
Follow-up work\r\n- https://github.com/elastic/kibana/issues/193952\r\n-
https://github.com/elastic/kibana/issues/193942","sha":"387afb782e44a0bf7de5549751e52fc7619c328a"}},"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/193957","number":193957,"mergeCommit":{"message":"[Alert
details page] Use related alerts logic only for the custom threshold
rule (#193957)\n\nCloses #193943\r\n\r\n### Summary\r\n\r\nThis PR only
loads related alerts for the custom threshold rule and only\r\nwhen the
related rule has tags or group by fields.\r\n\r\nFor now, we don't show
this tab if there is no tag or group and there is\r\na follow-up ticket
for discussing the empty state for the related\r\nalerts.\r\n\r\n####
Follow-up work\r\n- https://github.com/elastic/kibana/issues/193952\r\n-
https://github.com/elastic/kibana/issues/193942","sha":"387afb782e44a0bf7de5549751e52fc7619c328a"}}]}]
BACKPORT-->

Co-authored-by: Maryam Saeidi <[email protected]>
  • Loading branch information
kibanamachine and maryam-saeidi authored Sep 25, 2024
1 parent c7b153c commit 24bec01
Show file tree
Hide file tree
Showing 6 changed files with 36 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* 2.0.
*/

import type { Group } from '../../../../common/typings';
import type { Group } from '../../typings';

export interface Query {
query: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ jest.mock('../../../../utils/kibana_react', () => ({
describe('AlertDetailsAppSection', () => {
const queryClient = new QueryClient();
const mockedSetAlertSummaryFields = jest.fn();
const mockedSetRelatedAlertsKuery = jest.fn();

const renderComponent = (
alert: Partial<CustomThresholdAlert> = {},
Expand All @@ -90,6 +91,7 @@ describe('AlertDetailsAppSection', () => {
alert={buildCustomThresholdAlert(alert, alertFields)}
rule={buildCustomThresholdRule()}
setAlertSummaryFields={mockedSetAlertSummaryFields}
setRelatedAlertsKuery={mockedSetRelatedAlertsKuery}
/>
</QueryClientProvider>
</IntlProvider>
Expand Down Expand Up @@ -140,6 +142,15 @@ describe('AlertDetailsAppSection', () => {
expect(mockedRuleConditionChart.mock.calls[0]).toMatchSnapshot();
});

it('should set relatedAlertsKuery', async () => {
renderComponent();

expect(mockedSetAlertSummaryFields).toBeCalledTimes(2);
expect(mockedSetRelatedAlertsKuery).toHaveBeenLastCalledWith(
'(tags: "tag 1" or tags: "tag 2") or (host.name: "host-1" or kibana.alert.group.value: "host-1")'
);
});

it('should render title on condition charts', async () => {
const result = renderComponent();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import moment from 'moment';
import { LOGS_EXPLORER_LOCATOR_ID, LogsExplorerLocatorParams } from '@kbn/deeplinks-observability';
import { TimeRange } from '@kbn/es-query';
import { getGroupFilters } from '../../../../../common/custom_threshold_rule/helpers/get_group';
import { getRelatedAlertKuery } from '../../../../../common/utils/alerting/get_related_alerts_query';
import { useLicense } from '../../../../hooks/use_license';
import { useKibana } from '../../../../utils/kibana_react';
import { metricValueFormatter } from '../../../../../common/custom_threshold_rule/metric_value_formatter';
Expand All @@ -49,13 +50,15 @@ interface AppSectionProps {
alert: CustomThresholdAlert;
rule: CustomThresholdRule;
setAlertSummaryFields: React.Dispatch<React.SetStateAction<AlertSummaryField[] | undefined>>;
setRelatedAlertsKuery: React.Dispatch<React.SetStateAction<string | undefined>>;
}

// eslint-disable-next-line import/no-default-export
export default function AlertDetailsAppSection({
alert,
rule,
setAlertSummaryFields,
setRelatedAlertsKuery,
}: AppSectionProps) {
const services = useKibana().services;
const {
Expand All @@ -79,6 +82,7 @@ export default function AlertDetailsAppSection({
const alertStart = alert.fields[ALERT_START];
const alertEnd = alert.fields[ALERT_END];
const groups = alert.fields[ALERT_GROUP];
const tags = alert.fields.tags;

const chartTitleAndTooltip: Array<{ title: string; tooltip: string }> = [];

Expand All @@ -97,7 +101,6 @@ export default function AlertDetailsAppSection({
icon: 'alert',
id: 'custom_threshold_alert_start_annotation',
};

const alertRangeAnnotation: RangeEventAnnotationConfig = {
label: `${alertEnd ? 'Alert duration' : 'Active alert'}`,
type: 'manual',
Expand All @@ -109,10 +112,13 @@ export default function AlertDetailsAppSection({
color: chroma(transparentize('#F04E981A', 0.2)).hex().toUpperCase(),
id: `custom_threshold_${alertEnd ? 'recovered' : 'active'}_alert_range_annotation`,
};

const annotations: EventAnnotationConfig[] = [];
annotations.push(alertStartAnnotation, alertRangeAnnotation);

useEffect(() => {
setRelatedAlertsKuery(getRelatedAlertKuery(tags, groups));
}, [groups, setRelatedAlertsKuery, tags]);

useEffect(() => {
setTimeRange(getPaddedAlertTimeRange(alertStart!, alertEnd));
}, [alertStart, alertEnd]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,13 @@ import {
ALERT_RULE_UUID,
ALERT_STATUS,
ALERT_STATUS_UNTRACKED,
ALERT_GROUP,
} from '@kbn/rule-data-utils';
import { RuleTypeModel } from '@kbn/triggers-actions-ui-plugin/public';
import { useBreadcrumbs } from '@kbn/observability-shared-plugin/public';
import dedent from 'dedent';
import { AlertFieldsTable } from '@kbn/alerts-ui-shared';
import { css } from '@emotion/react';
import { omit } from 'lodash';
import type { Group } from '../../../common/typings';
import { observabilityFeatureId } from '../../../common';
import { RelatedAlerts } from './components/related_alerts';
import { useKibana } from '../../utils/kibana_react';
Expand Down Expand Up @@ -98,6 +96,7 @@ export function AlertDetails() {
const [alertStatus, setAlertStatus] = useState<AlertStatus>();
const { euiTheme } = useEuiTheme();

const [relatedAlertsKuery, setRelatedAlertsKuery] = useState<string>();
const [activeTabId, setActiveTabId] = useState<TabId>(() => {
const searchParams = new URLSearchParams(search);
const urlTabId = searchParams.get(ALERT_DETAILS_TAB_URL_STORAGE_KEY);
Expand Down Expand Up @@ -213,6 +212,7 @@ export function AlertDetails() {
rule={rule}
timeZone={timeZone}
setAlertSummaryFields={setSummaryFields}
setRelatedAlertsKuery={setRelatedAlertsKuery}
/>
<EuiSpacer size="l" />
<AlertHistoryChart
Expand Down Expand Up @@ -258,21 +258,18 @@ export function AlertDetails() {
'data-test-subj': 'metadataTab',
content: metadataTab,
},
{
];

if (relatedAlertsKuery && alertDetail?.formatted) {
tabs.push({
id: RELATED_ALERTS_TAB_ID,
name: i18n.translate('xpack.observability.alertDetails.tab.relatedAlertsLabel', {
defaultMessage: 'Related Alerts',
}),
'data-test-subj': 'relatedAlertsTab',
content: (
<RelatedAlerts
alert={alertDetail?.formatted}
tags={alertDetail?.formatted.fields.tags}
groups={alertDetail?.formatted.fields[ALERT_GROUP] as Group[]}
/>
),
},
];
content: <RelatedAlerts alert={alertDetail.formatted} kuery={relatedAlertsKuery} />,
});
}

return (
<ObservabilityPageTemplate
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import {
AlertSearchBarContainerState,
DEFAULT_STATE,
} from '../../../components/alert_search_bar/containers/state_container';
import type { Group } from '../../../../common/typings';
import { ObservabilityAlertSearchbarWithUrlSync } from '../../../components/alert_search_bar/alert_search_bar_with_url_sync';
import { renderGroupPanel } from '../../../components/alerts_table/grouping/render_group_panel';
import { getGroupStats } from '../../../components/alerts_table/grouping/get_group_stats';
Expand All @@ -36,22 +35,20 @@ import { usePluginContext } from '../../../hooks/use_plugin_context';
import { useKibana } from '../../../utils/kibana_react';
import { buildEsQuery } from '../../../utils/build_es_query';
import { mergeBoolQueries } from '../../alerts/helpers/merge_bool_queries';
import { getRelatedAlertKuery } from '../helpers/get_related_alerts_query';

const ALERTS_PER_PAGE = 50;
const RELATED_ALERTS_SEARCH_BAR_ID = 'related-alerts-search-bar-o11y';
const ALERTS_TABLE_ID = 'xpack.observability.related.alerts.table';

interface Props {
alert?: TopAlert;
groups?: Group[];
tags?: string[];
alert: TopAlert;
kuery: string;
}

const defaultState: AlertSearchBarContainerState = { ...DEFAULT_STATE, status: 'active' };
const DEFAULT_FILTERS: Filter[] = [];

export function InternalRelatedAlerts({ alert, groups, tags }: Props) {
export function InternalRelatedAlerts({ alert, kuery }: Props) {
const kibanaServices = useKibana().services;
const {
http,
Expand All @@ -65,9 +62,9 @@ export function InternalRelatedAlerts({ alert, groups, tags }: Props) {
});

const [esQuery, setEsQuery] = useState<{ bool: BoolQuery }>();
const alertStart = alert?.fields[ALERT_START];
const alertEnd = alert?.fields[ALERT_END];
const alertId = alert?.fields[ALERT_UUID];
const alertStart = alert.fields[ALERT_START];
const alertEnd = alert.fields[ALERT_END];
const alertId = alert.fields[ALERT_UUID];

const defaultQuery = useRef<Query[]>([
{ query: `not kibana.alert.uuid: ${alertId}`, language: 'kuery' },
Expand All @@ -93,7 +90,7 @@ export function InternalRelatedAlerts({ alert, groups, tags }: Props) {
defaultSearchQueries={defaultQuery.current}
defaultState={{
...defaultState,
kuery: getRelatedAlertKuery(tags, groups) ?? '',
kuery,
}}
/>
</EuiFlexItem>
Expand Down

0 comments on commit 24bec01

Please sign in to comment.