From f20444a9bfe9d28c0def11e60c9d2fed33502a4b Mon Sep 17 00:00:00 2001 From: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Date: Tue, 1 Oct 2024 08:03:06 +1000 Subject: [PATCH] [8.x] [Alert details page] Add view logs to each condition for the custom threshold rule (#193839) (#194487) # Backport This will backport the following commits from `main` to `8.x`: - [[Alert details page] Add view logs to each condition for the custom threshold rule (#193839)](https://github.com/elastic/kibana/pull/193839) ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sqren/backport) Co-authored-by: Maryam Saeidi --- .../alert_details_app_section.test.tsx.snap | 1 + .../alert_details_app_section.test.tsx | 39 ++-- .../alert_details_app_section.tsx | 178 ++++++++---------- .../mocks/custom_threshold_rule.ts | 1 + .../translations/translations/fr-FR.json | 2 - .../translations/translations/ja-JP.json | 2 - .../translations/translations/zh-CN.json | 2 - 7 files changed, 97 insertions(+), 128 deletions(-) diff --git a/x-pack/plugins/observability_solution/observability/public/components/custom_threshold/components/alert_details_app_section/__snapshots__/alert_details_app_section.test.tsx.snap b/x-pack/plugins/observability_solution/observability/public/components/custom_threshold/components/alert_details_app_section/__snapshots__/alert_details_app_section.test.tsx.snap index efa0222912f4f..79c58c84a1f30 100644 --- a/x-pack/plugins/observability_solution/observability/public/components/custom_threshold/components/alert_details_app_section/__snapshots__/alert_details_app_section.test.tsx.snap +++ b/x-pack/plugins/observability_solution/observability/public/components/custom_threshold/components/alert_details_app_section/__snapshots__/alert_details_app_section.test.tsx.snap @@ -49,6 +49,7 @@ Array [ "metrics": Array [ Object { "aggType": "count", + "filter": "host.name: host-1", "name": "A", }, ], diff --git a/x-pack/plugins/observability_solution/observability/public/components/custom_threshold/components/alert_details_app_section/alert_details_app_section.test.tsx b/x-pack/plugins/observability_solution/observability/public/components/custom_threshold/components/alert_details_app_section/alert_details_app_section.test.tsx index 553ca19787d4f..d16df6b6120df 100644 --- a/x-pack/plugins/observability_solution/observability/public/components/custom_threshold/components/alert_details_app_section/alert_details_app_section.test.tsx +++ b/x-pack/plugins/observability_solution/observability/public/components/custom_threshold/components/alert_details_app_section/alert_details_app_section.test.tsx @@ -6,7 +6,6 @@ */ import React from 'react'; -import { EuiLink } from '@elastic/eui'; import { chartPluginMock } from '@kbn/charts-plugin/public/mocks'; import { coreMock as mockCoreMock } from '@kbn/core/public/mocks'; import { __IntlProvider as IntlProvider } from '@kbn/i18n-react'; @@ -77,7 +76,6 @@ jest.mock('../../../../utils/kibana_react', () => ({ describe('AlertDetailsAppSection', () => { const queryClient = new QueryClient(); - const mockedSetAlertSummaryFields = jest.fn(); const mockedSetRelatedAlertsKuery = jest.fn(); const renderComponent = ( @@ -90,7 +88,6 @@ describe('AlertDetailsAppSection', () => { @@ -109,27 +106,6 @@ describe('AlertDetailsAppSection', () => { expect(result.getByTestId('thresholdRule-2000-2500')).toBeTruthy(); }); - it('should render additional alert summary fields', async () => { - renderComponent(); - - expect(mockedSetAlertSummaryFields).toBeCalledTimes(2); - expect(mockedSetAlertSummaryFields).toBeCalledWith([ - { - label: 'Related logs', - value: ( - - - View related logs - - - ), - }, - ]); - }); - it('should render annotations', async () => { const mockedRuleConditionChart = jest.fn(() =>
); (RuleConditionChart as jest.Mock).mockImplementation(mockedRuleConditionChart); @@ -145,7 +121,7 @@ describe('AlertDetailsAppSection', () => { it('should set relatedAlertsKuery', async () => { renderComponent(); - expect(mockedSetAlertSummaryFields).toBeCalledTimes(2); + expect(mockedSetRelatedAlertsKuery).toBeCalledTimes(1); expect(mockedSetRelatedAlertsKuery).toHaveBeenLastCalledWith( '(tags: "tag 1" or tags: "tag 2") or (host.name: "host-1" or kibana.alert.group.value: "host-1")' ); @@ -155,22 +131,33 @@ describe('AlertDetailsAppSection', () => { const result = renderComponent(); expect(result.getByTestId('chartTitle-0').textContent).toBe( - 'Equation result for count (all documents)' + 'Equation result for count (host.name: host-1)' ); + expect((result.getByTestId('viewLogs-0') as any).href).toBe('http://localhost/view-in-app-url'); + expect(result.getByTestId('chartTitle-1').textContent).toBe( 'Equation result for max (system.cpu.user.pct)' ); + expect((result.getByTestId('viewLogs-1') as any).href).toBe('http://localhost/view-in-app-url'); + expect(result.getByTestId('chartTitle-2').textContent).toBe( 'Equation result for min (system.memory.used.pct)' ); + expect((result.getByTestId('viewLogs-2') as any).href).toBe('http://localhost/view-in-app-url'); + expect(result.getByTestId('chartTitle-3').textContent).toBe( 'Equation result for min (system.memory.used.pct) + min (system.memory.used.pct) + min (system.memory.used.pct) + min (system.memory.used.pct...' ); + expect((result.getByTestId('viewLogs-3') as any).href).toBe('http://localhost/view-in-app-url'); + expect(result.getByTestId('chartTitle-4').textContent).toBe( 'Equation result for min (system.memory.used.pct) + min (system.memory.used.pct)' ); + expect((result.getByTestId('viewLogs-4') as any).href).toBe('http://localhost/view-in-app-url'); + expect(result.getByTestId('chartTitle-5').textContent).toBe( 'Equation result for min (system.memory.used.pct) + min (system.memory.used.pct) + min (system.memory.used.pct)' ); + expect((result.getByTestId('viewLogs-5') as any).href).toBe('http://localhost/view-in-app-url'); }); }); diff --git a/x-pack/plugins/observability_solution/observability/public/components/custom_threshold/components/alert_details_app_section/alert_details_app_section.tsx b/x-pack/plugins/observability_solution/observability/public/components/custom_threshold/components/alert_details_app_section/alert_details_app_section.tsx index cb7cbd6fca914..a7ec41f4ab660 100644 --- a/x-pack/plugins/observability_solution/observability/public/components/custom_threshold/components/alert_details_app_section/alert_details_app_section.tsx +++ b/x-pack/plugins/observability_solution/observability/public/components/custom_threshold/components/alert_details_app_section/alert_details_app_section.tsx @@ -11,6 +11,7 @@ import React, { useEffect, useState } from 'react'; import { EuiFlexGroup, EuiFlexItem, + EuiIcon, EuiLink, EuiPanel, EuiSpacer, @@ -36,7 +37,6 @@ import { getRelatedAlertKuery } from '../../../../../common/utils/alerting/get_r import { useLicense } from '../../../../hooks/use_license'; import { useKibana } from '../../../../utils/kibana_react'; import { metricValueFormatter } from '../../../../../common/custom_threshold_rule/metric_value_formatter'; -import { AlertSummaryField } from '../../../..'; import { AlertParams } from '../../types'; import { Threshold } from '../custom_threshold'; import { CustomThresholdRule, CustomThresholdAlert } from '../types'; @@ -49,7 +49,6 @@ import { generateChartTitleAndTooltip } from './helpers/generate_chart_title_and interface AppSectionProps { alert: CustomThresholdAlert; rule: CustomThresholdRule; - setAlertSummaryFields: React.Dispatch>; setRelatedAlertsKuery: React.Dispatch>; } @@ -57,7 +56,6 @@ interface AppSectionProps { export default function AlertDetailsAppSection({ alert, rule, - setAlertSummaryFields, setRelatedAlertsKuery, }: AppSectionProps) { const services = useKibana().services; @@ -73,7 +71,6 @@ export default function AlertDetailsAppSection({ const hasLogRateAnalysisLicense = hasAtLeast('platinum'); const [dataView, setDataView] = useState(); const [, setDataViewError] = useState(); - const [viewInAppUrl, setViewInAppUrl] = useState(); const [timeRange, setTimeRange] = useState({ from: 'now-15m', to: 'now' }); const ruleParams = rule.params as RuleTypeParams & AlertParams; const chartProps = { @@ -123,48 +120,6 @@ export default function AlertDetailsAppSection({ setTimeRange(getPaddedAlertTimeRange(alertStart!, alertEnd)); }, [alertStart, alertEnd]); - useEffect(() => { - const appUrl = getViewInAppUrl({ - dataViewId: dataView?.id, - groups, - logsExplorerLocator: locators.get(LOGS_EXPLORER_LOCATOR_ID), - metrics: ruleParams.criteria[0]?.metrics, - searchConfiguration: - ruleParams.searchConfiguration as SearchConfigurationWithExtractedReferenceType, - startedAt: alertStart, - endedAt: alertEnd, - }); - - setViewInAppUrl(appUrl); - }, [dataView, alertStart, alertEnd, groups, ruleParams, locators]); - - useEffect(() => { - const alertSummaryFields = []; - - alertSummaryFields.push({ - label: i18n.translate( - 'xpack.observability.customThreshold.rule.alertDetailsAppSection.summaryField.relatedLogs', - { - defaultMessage: 'Related logs', - } - ), - value: ( - - - {i18n.translate('xpack.observability.alertDetailsAppSection.a.viewRelatedLogsLabel', { - defaultMessage: 'View related logs', - })} - - - ), - }); - - setAlertSummaryFields(alertSummaryFields); - }, [viewInAppUrl, setAlertSummaryFields]); - useEffect(() => { const initDataView = async () => { const ruleSearchConfiguration = ruleParams.searchConfiguration; @@ -186,57 +141,88 @@ export default function AlertDetailsAppSection({ return ( - {ruleParams.criteria.map((criterion, index) => ( - - - - -

{chartTitleAndTooltip[index].title}

-
-
- - - - - metricValueFormatter( - d, - criterion.metrics[0] ? criterion.metrics[0].name : undefined - ) - } - title={i18n.translate( - 'xpack.observability.customThreshold.rule.alertDetailsAppSection.thresholdTitle', - { - defaultMessage: 'Threshold breached', + {ruleParams.criteria.map((criterion, index) => { + const appUrl = getViewInAppUrl({ + dataViewId: dataView?.id, + groups, + logsExplorerLocator: locators.get(LOGS_EXPLORER_LOCATOR_ID), + metrics: criterion?.metrics, + searchConfiguration: + ruleParams.searchConfiguration as SearchConfigurationWithExtractedReferenceType, + startedAt: alertStart, + endedAt: alertEnd, + }); + + return ( + + + + + + +

+ {chartTitleAndTooltip[index].title} +

+
+
+
+ + + +   + {i18n.translate( + 'xpack.observability.customThreshold.rule.alertDetailsAppSection.openInDiscoverLabel', + { + defaultMessage: 'Open in Discover', + } + )} + + +
+ + + + + metricValueFormatter( + d, + criterion.metrics[0] ? criterion.metrics[0].name : undefined + ) } - )} - comparator={criterion.comparator} - /> - - - - - -
-
- ))} + title={i18n.translate( + 'xpack.observability.customThreshold.rule.alertDetailsAppSection.thresholdTitle', + { + defaultMessage: 'Threshold breached', + } + )} + comparator={criterion.comparator} + /> +
+ + + +
+
+
+ ); + })} {hasLogRateAnalysisLicense && ( )} diff --git a/x-pack/plugins/observability_solution/observability/public/components/custom_threshold/mocks/custom_threshold_rule.ts b/x-pack/plugins/observability_solution/observability/public/components/custom_threshold/mocks/custom_threshold_rule.ts index efa32473e0b44..c1db31d991c28 100644 --- a/x-pack/plugins/observability_solution/observability/public/components/custom_threshold/mocks/custom_threshold_rule.ts +++ b/x-pack/plugins/observability_solution/observability/public/components/custom_threshold/mocks/custom_threshold_rule.ts @@ -66,6 +66,7 @@ export const buildCustomThresholdRule = ( { name: 'A', aggType: Aggregators.COUNT, + filter: 'host.name: host-1', }, ], threshold: [2000], diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index 5b8a9f823b8c6..0dd19cd14cf5e 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -32087,7 +32087,6 @@ "xpack.observability.alertDetails.tab.overviewLabel": "Aperçu", "xpack.observability.alertDetails.untrackAlert": "Marquer comme non suivi", "xpack.observability.alertDetails.viewRuleDetails": "Accéder aux détails de la règle", - "xpack.observability.alertDetailsAppSection.a.viewRelatedLogsLabel": "Afficher les logs associés", "xpack.observability.alertDetailsPage.alertHistory.alertsTriggered": "Alertes déclenchées", "xpack.observability.alertDetailsPage.alertHistory.avgTimeToRecover": "Temps moyen de récupération", "xpack.observability.alertDetailsPage.alertHistory.chartTitle": "Historique des alertes", @@ -32200,7 +32199,6 @@ "xpack.observability.customThreshold.rule.aggregators.p99": "99e centile de {metric}", "xpack.observability.customThreshold.rule.aggregators.rate": "Taux de {metric}", "xpack.observability.customThreshold.rule.aggregators.sum": "Somme de {metric}", - "xpack.observability.customThreshold.rule.alertDetailsAppSection.summaryField.relatedLogs": "Logs associés", "xpack.observability.customThreshold.rule.alertDetailsAppSection.thresholdTitle": "Seuil dépassé", "xpack.observability.customThreshold.rule.alertDetailUrlActionVariableDescription": "Lien vers l’affichage de résolution des problèmes d’alerte pour voir plus de contextes et de détails. La chaîne sera vide si server.publicBaseUrl n'est pas configuré.", "xpack.observability.customThreshold.rule.alertFlyout.addCondition": "Ajouter une condition", diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 5018850808810..efad84a1470d0 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -31831,7 +31831,6 @@ "xpack.observability.alertDetails.tab.overviewLabel": "概要", "xpack.observability.alertDetails.untrackAlert": "未追跡に設定", "xpack.observability.alertDetails.viewRuleDetails": "ルール詳細に移動", - "xpack.observability.alertDetailsAppSection.a.viewRelatedLogsLabel": "関連ログを表示", "xpack.observability.alertDetailsPage.alertHistory.alertsTriggered": "アラートがトリガーされました", "xpack.observability.alertDetailsPage.alertHistory.avgTimeToRecover": "回復までの平均時間", "xpack.observability.alertDetailsPage.alertHistory.chartTitle": "アラート履歴", @@ -31944,7 +31943,6 @@ "xpack.observability.customThreshold.rule.aggregators.p99": "{metric}の99パーセンタイル", "xpack.observability.customThreshold.rule.aggregators.rate": "{metric}の比率", "xpack.observability.customThreshold.rule.aggregators.sum": "{metric}の合計", - "xpack.observability.customThreshold.rule.alertDetailsAppSection.summaryField.relatedLogs": "関連ログ", "xpack.observability.customThreshold.rule.alertDetailsAppSection.thresholdTitle": "しきい値を超えました", "xpack.observability.customThreshold.rule.alertDetailUrlActionVariableDescription": "アラートトラブルシューティングビューにリンクして、さらに詳しい状況や詳細を確認できます。server.publicBaseUrlが構成されていない場合は、空の文字列になります。", "xpack.observability.customThreshold.rule.alertFlyout.addCondition": "条件を追加", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index cf5a1dabb4459..4024b7a182132 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -31874,7 +31874,6 @@ "xpack.observability.alertDetails.tab.overviewLabel": "概览", "xpack.observability.alertDetails.untrackAlert": "标记为已取消跟踪", "xpack.observability.alertDetails.viewRuleDetails": "前往规则详情", - "xpack.observability.alertDetailsAppSection.a.viewRelatedLogsLabel": "查看相关日志", "xpack.observability.alertDetailsPage.alertHistory.alertsTriggered": "已触发告警", "xpack.observability.alertDetailsPage.alertHistory.avgTimeToRecover": "恢复的平均时间", "xpack.observability.alertDetailsPage.alertHistory.chartTitle": "告警历史记录", @@ -31987,7 +31986,6 @@ "xpack.observability.customThreshold.rule.aggregators.p99": "{metric} 的第 99 个百分位", "xpack.observability.customThreshold.rule.aggregators.rate": "{metric} 的比率", "xpack.observability.customThreshold.rule.aggregators.sum": "{metric} 的总和", - "xpack.observability.customThreshold.rule.alertDetailsAppSection.summaryField.relatedLogs": "相关日志", "xpack.observability.customThreshold.rule.alertDetailsAppSection.thresholdTitle": "超出阈值", "xpack.observability.customThreshold.rule.alertDetailUrlActionVariableDescription": "链接到告警故障排除视图获取进一步的上下文和详情。如果未配置 server.publicBaseUrl,这将为空字符串。", "xpack.observability.customThreshold.rule.alertFlyout.addCondition": "添加条件",