From e150da7a80a0b932ebffb085a6e3e4f792093be9 Mon Sep 17 00:00:00 2001 From: Maryam Saeidi Date: Tue, 24 Sep 2024 22:02:14 +0200 Subject: [PATCH] [Alert details page] Update alertDetailsUrl context variable URL (#193674) Closes #180889 ## Summary Update the alertDetailsUrl context variable for the following rules: - Inventory rule - Metric threshold rule - Error count threshold rule - Failed transaction rate threshold rule - APM Anomaly rule - Synthetics TLS rule - Synthetics monitor status rule (cherry picked from commit 09082f2d3e751776c8546e31cdad95db11cab8d5) --- .../register_anomaly_rule_type.test.ts | 2 +- .../anomaly/register_anomaly_rule_type.ts | 19 ++++----- .../register_error_count_rule_type.test.ts | 38 +++++++++--------- .../register_error_count_rule_type.ts | 15 ++----- ...r_transaction_error_rate_rule_type.test.ts | 10 ++--- ...gister_transaction_error_rate_rule_type.ts | 15 ++----- .../server/routes/alerts/test_utils/index.ts | 7 ---- .../inventory_metric_threshold_executor.ts | 26 ++---------- .../metric_threshold_executor.test.ts | 2 +- .../metric_threshold_executor.ts | 20 ++-------- .../lib/rules/slo_burn_rate/executor.test.ts | 40 ++----------------- .../lib/rules/slo_burn_rate/executor.ts | 22 ++-------- .../synthetics/server/alert_rules/common.ts | 8 +--- .../status_rule/monitor_status_rule.ts | 3 +- .../tls_rule/message_utils.test.ts | 12 +----- .../alert_rules/tls_rule/message_utils.ts | 16 +------- .../server/alert_rules/tls_rule/tls_rule.ts | 27 +++---------- .../observability/metric_threshold_rule.ts | 6 +-- 18 files changed, 70 insertions(+), 218 deletions(-) diff --git a/x-pack/plugins/observability_solution/apm/server/routes/alerts/rule_types/anomaly/register_anomaly_rule_type.test.ts b/x-pack/plugins/observability_solution/apm/server/routes/alerts/rule_types/anomaly/register_anomaly_rule_type.test.ts index 5649af59ce4e0..e5fc1a41abdfd 100644 --- a/x-pack/plugins/observability_solution/apm/server/routes/alerts/rule_types/anomaly/register_anomaly_rule_type.test.ts +++ b/x-pack/plugins/observability_solution/apm/server/routes/alerts/rule_types/anomaly/register_anomaly_rule_type.test.ts @@ -217,7 +217,7 @@ describe('Transaction duration anomaly alert', () => { expect(services.alertsClient.setAlertData).toHaveBeenCalledWith({ context: { - alertDetailsUrl: 'mockedAlertsLocator > getLocation', + alertDetailsUrl: 'http://localhost:5601/eyr/app/observability/alerts/test-uuid', environment: 'development', reason: 'critical latency anomaly with a score of 80, was detected in the last 5 mins for foo.', diff --git a/x-pack/plugins/observability_solution/apm/server/routes/alerts/rule_types/anomaly/register_anomaly_rule_type.ts b/x-pack/plugins/observability_solution/apm/server/routes/alerts/rule_types/anomaly/register_anomaly_rule_type.ts index d9a58d23a5888..531b5c9558a56 100644 --- a/x-pack/plugins/observability_solution/apm/server/routes/alerts/rule_types/anomaly/register_anomaly_rule_type.ts +++ b/x-pack/plugins/observability_solution/apm/server/routes/alerts/rule_types/anomaly/register_anomaly_rule_type.ts @@ -18,7 +18,11 @@ import { import { KibanaRequest, DEFAULT_APP_CATEGORIES } from '@kbn/core/server'; import datemath from '@kbn/datemath'; import type { ESSearchResponse } from '@kbn/es-types'; -import { getAlertUrl, observabilityPaths, ProcessorEvent } from '@kbn/observability-plugin/common'; +import { + getAlertDetailsUrl, + observabilityPaths, + ProcessorEvent, +} from '@kbn/observability-plugin/common'; import { termQuery, termsQuery } from '@kbn/observability-plugin/server'; import { ALERT_EVALUATION_THRESHOLD, @@ -128,7 +132,7 @@ export function registerAnomalyRuleType({ return { state: {} }; } - const { params, services, spaceId, startedAt, getTimeRange } = options; + const { params, services, spaceId, getTimeRange } = options; const { alertsClient, savedObjectsClient, scopedClusterClient, uiSettingsClient } = services; if (!alertsClient) { throw new AlertsClientError(); @@ -303,11 +307,10 @@ export function registerAnomalyRuleType({ const alertId = bucketKey.join('_'); - const { uuid, start } = alertsClient.report({ + const { uuid } = alertsClient.report({ id: alertId, actionGroup: ruleTypeConfig.defaultActionGroupId, }); - const indexedStartedAt = start ?? startedAt.toISOString(); const relativeViewInAppUrl = getAlertUrlTransaction( serviceName, @@ -319,13 +322,7 @@ export function registerAnomalyRuleType({ spaceId, relativeViewInAppUrl ); - const alertDetailsUrl = await getAlertUrl( - uuid, - spaceId, - indexedStartedAt, - alertsLocator, - basePath.publicBaseUrl - ); + const alertDetailsUrl = await getAlertDetailsUrl(basePath, spaceId, uuid); const payload = { [SERVICE_NAME]: serviceName, diff --git a/x-pack/plugins/observability_solution/apm/server/routes/alerts/rule_types/error_count/register_error_count_rule_type.test.ts b/x-pack/plugins/observability_solution/apm/server/routes/alerts/rule_types/error_count/register_error_count_rule_type.test.ts index 2115a517beedf..a27b0ca78e510 100644 --- a/x-pack/plugins/observability_solution/apm/server/routes/alerts/rule_types/error_count/register_error_count_rule_type.test.ts +++ b/x-pack/plugins/observability_solution/apm/server/routes/alerts/rule_types/error_count/register_error_count_rule_type.test.ts @@ -142,7 +142,7 @@ describe('Error count alert', () => { expect(services.alertsClient.setAlertData).toHaveBeenCalledWith({ context: { - alertDetailsUrl: 'mockedAlertsLocator > getLocation', + alertDetailsUrl: 'http://localhost:5601/eyr/app/observability/alerts/test-uuid', environment: 'env-foo', errorGroupingKey: undefined, interval: '5 mins', @@ -167,7 +167,7 @@ describe('Error count alert', () => { }); expect(services.alertsClient.setAlertData).toHaveBeenCalledWith({ context: { - alertDetailsUrl: 'mockedAlertsLocator > getLocation', + alertDetailsUrl: 'http://localhost:5601/eyr/app/observability/alerts/test-uuid', environment: 'env-foo-2', errorGroupingKey: undefined, interval: '5 mins', @@ -192,7 +192,7 @@ describe('Error count alert', () => { }); expect(services.alertsClient.setAlertData).toHaveBeenCalledWith({ context: { - alertDetailsUrl: 'mockedAlertsLocator > getLocation', + alertDetailsUrl: 'http://localhost:5601/eyr/app/observability/alerts/test-uuid', environment: 'env-bar', errorGroupingKey: undefined, interval: '5 mins', @@ -283,7 +283,7 @@ describe('Error count alert', () => { expect(services.alertsClient.setAlertData).toHaveBeenCalledWith({ context: { - alertDetailsUrl: 'mockedAlertsLocator > getLocation', + alertDetailsUrl: 'http://localhost:5601/eyr/app/observability/alerts/test-uuid', environment: 'env-foo', errorGroupingKey: undefined, interval: '5 mins', @@ -310,7 +310,7 @@ describe('Error count alert', () => { }); expect(services.alertsClient.setAlertData).toHaveBeenCalledWith({ context: { - alertDetailsUrl: 'mockedAlertsLocator > getLocation', + alertDetailsUrl: 'http://localhost:5601/eyr/app/observability/alerts/test-uuid', environment: 'env-foo-2', errorGroupingKey: undefined, interval: '5 mins', @@ -337,7 +337,7 @@ describe('Error count alert', () => { }); expect(services.alertsClient.setAlertData).toHaveBeenCalledWith({ context: { - alertDetailsUrl: 'mockedAlertsLocator > getLocation', + alertDetailsUrl: 'http://localhost:5601/eyr/app/observability/alerts/test-uuid', environment: 'env-bar', errorGroupingKey: undefined, interval: '5 mins', @@ -433,7 +433,7 @@ describe('Error count alert', () => { expect(services.alertsClient.setAlertData).toHaveBeenCalledWith({ context: { - alertDetailsUrl: 'mockedAlertsLocator > getLocation', + alertDetailsUrl: 'http://localhost:5601/eyr/app/observability/alerts/test-uuid', environment: 'env-foo', errorGroupingKey: 'error-key-foo', interval: '5 mins', @@ -458,7 +458,7 @@ describe('Error count alert', () => { }); expect(services.alertsClient.setAlertData).toHaveBeenCalledWith({ context: { - alertDetailsUrl: 'mockedAlertsLocator > getLocation', + alertDetailsUrl: 'http://localhost:5601/eyr/app/observability/alerts/test-uuid', environment: 'env-foo-2', errorGroupingKey: 'error-key-foo-2', interval: '5 mins', @@ -483,7 +483,7 @@ describe('Error count alert', () => { }); expect(services.alertsClient.setAlertData).toHaveBeenCalledWith({ context: { - alertDetailsUrl: 'mockedAlertsLocator > getLocation', + alertDetailsUrl: 'http://localhost:5601/eyr/app/observability/alerts/test-uuid', environment: 'env-bar', errorGroupingKey: 'error-key-bar', interval: '5 mins', @@ -573,7 +573,7 @@ describe('Error count alert', () => { expect(services.alertsClient.setAlertData).toHaveBeenCalledWith({ context: { - alertDetailsUrl: 'mockedAlertsLocator > getLocation', + alertDetailsUrl: 'http://localhost:5601/eyr/app/observability/alerts/test-uuid', environment: 'env-foo', errorGroupingKey: undefined, interval: '5 mins', @@ -598,7 +598,7 @@ describe('Error count alert', () => { }); expect(services.alertsClient.setAlertData).toHaveBeenCalledWith({ context: { - alertDetailsUrl: 'mockedAlertsLocator > getLocation', + alertDetailsUrl: 'http://localhost:5601/eyr/app/observability/alerts/test-uuid', environment: 'env-foo-2', errorGroupingKey: undefined, interval: '5 mins', @@ -623,7 +623,7 @@ describe('Error count alert', () => { }); expect(services.alertsClient.setAlertData).toHaveBeenCalledWith({ context: { - alertDetailsUrl: 'mockedAlertsLocator > getLocation', + alertDetailsUrl: 'http://localhost:5601/eyr/app/observability/alerts/test-uuid', environment: 'env-bar', errorGroupingKey: undefined, interval: '5 mins', @@ -714,7 +714,7 @@ describe('Error count alert', () => { expect(services.alertsClient.setAlertData).toHaveBeenCalledWith({ context: { - alertDetailsUrl: 'mockedAlertsLocator > getLocation', + alertDetailsUrl: 'http://localhost:5601/eyr/app/observability/alerts/test-uuid', environment: 'Not defined', errorGroupingKey: undefined, interval: '5 mins', @@ -740,7 +740,7 @@ describe('Error count alert', () => { }); expect(services.alertsClient.setAlertData).toHaveBeenCalledWith({ context: { - alertDetailsUrl: 'mockedAlertsLocator > getLocation', + alertDetailsUrl: 'http://localhost:5601/eyr/app/observability/alerts/test-uuid', environment: 'Not defined', errorGroupingKey: undefined, interval: '5 mins', @@ -766,7 +766,7 @@ describe('Error count alert', () => { }); expect(services.alertsClient.setAlertData).toHaveBeenCalledWith({ context: { - alertDetailsUrl: 'mockedAlertsLocator > getLocation', + alertDetailsUrl: 'http://localhost:5601/eyr/app/observability/alerts/test-uuid', environment: 'env-bar', errorGroupingKey: undefined, interval: '5 mins', @@ -860,7 +860,7 @@ describe('Error count alert', () => { expect(services.alertsClient.setAlertData).toHaveBeenCalledWith({ context: { - alertDetailsUrl: 'mockedAlertsLocator > getLocation', + alertDetailsUrl: 'http://localhost:5601/eyr/app/observability/alerts/test-uuid', environment: 'env-foo', errorGroupingKey: 'error-key-foo', errorGroupingName: 'error-name-foo', @@ -887,7 +887,7 @@ describe('Error count alert', () => { }); expect(services.alertsClient.setAlertData).toHaveBeenCalledWith({ context: { - alertDetailsUrl: 'mockedAlertsLocator > getLocation', + alertDetailsUrl: 'http://localhost:5601/eyr/app/observability/alerts/test-uuid', environment: 'env-foo-2', errorGroupingKey: 'error-key-foo-2', errorGroupingName: 'error-name-foo2', @@ -914,7 +914,7 @@ describe('Error count alert', () => { }); expect(services.alertsClient.setAlertData).toHaveBeenCalledWith({ context: { - alertDetailsUrl: 'mockedAlertsLocator > getLocation', + alertDetailsUrl: 'http://localhost:5601/eyr/app/observability/alerts/test-uuid', environment: 'env-bar', errorGroupingKey: 'error-key-bar', errorGroupingName: 'error-name-bar', @@ -1001,7 +1001,7 @@ describe('Error count alert', () => { expect(services.alertsClient.setAlertData).toHaveBeenCalledWith({ context: { - alertDetailsUrl: 'mockedAlertsLocator > getLocation', + alertDetailsUrl: 'http://localhost:5601/eyr/app/observability/alerts/test-uuid', environment: 'env-foo', errorGroupingKey: undefined, interval: '5 mins', diff --git a/x-pack/plugins/observability_solution/apm/server/routes/alerts/rule_types/error_count/register_error_count_rule_type.ts b/x-pack/plugins/observability_solution/apm/server/routes/alerts/rule_types/error_count/register_error_count_rule_type.ts index 2539a63ea8575..8fb4000645a2e 100644 --- a/x-pack/plugins/observability_solution/apm/server/routes/alerts/rule_types/error_count/register_error_count_rule_type.ts +++ b/x-pack/plugins/observability_solution/apm/server/routes/alerts/rule_types/error_count/register_error_count_rule_type.ts @@ -17,7 +17,7 @@ import { } from '@kbn/alerting-plugin/server'; import { formatDurationFromTimeUnitChar, - getAlertUrl, + getAlertDetailsUrl, observabilityPaths, ProcessorEvent, TimeUnitChar, @@ -127,7 +127,7 @@ export function registerErrorCountRuleType({ ErrorCountAlert > ) => { - const { params: ruleParams, services, spaceId, startedAt, getTimeRange } = options; + const { params: ruleParams, services, spaceId, getTimeRange } = options; const { alertsClient, savedObjectsClient, scopedClusterClient, uiSettingsClient } = services; if (!alertsClient) { throw new AlertsClientError(); @@ -221,11 +221,10 @@ export function registerErrorCountRuleType({ groupByFields, }); - const { uuid, start } = alertsClient.report({ + const { uuid } = alertsClient.report({ id: alertId, actionGroup: ruleTypeConfig.defaultActionGroupId, }); - const indexedStartedAt = start ?? startedAt.toISOString(); const relativeViewInAppUrl = getAlertUrlErrorCount( groupByFields[SERVICE_NAME], @@ -236,13 +235,7 @@ export function registerErrorCountRuleType({ spaceId, relativeViewInAppUrl ); - const alertDetailsUrl = await getAlertUrl( - uuid, - spaceId, - indexedStartedAt, - alertsLocator, - basePath.publicBaseUrl - ); + const alertDetailsUrl = await getAlertDetailsUrl(basePath, spaceId, uuid); const groupByActionVariables = getGroupByActionVariables(groupByFields); const payload = { diff --git a/x-pack/plugins/observability_solution/apm/server/routes/alerts/rule_types/transaction_error_rate/register_transaction_error_rate_rule_type.test.ts b/x-pack/plugins/observability_solution/apm/server/routes/alerts/rule_types/transaction_error_rate/register_transaction_error_rate_rule_type.test.ts index 382cc9f53767e..98eda3ef9e904 100644 --- a/x-pack/plugins/observability_solution/apm/server/routes/alerts/rule_types/transaction_error_rate/register_transaction_error_rate_rule_type.test.ts +++ b/x-pack/plugins/observability_solution/apm/server/routes/alerts/rule_types/transaction_error_rate/register_transaction_error_rate_rule_type.test.ts @@ -129,7 +129,7 @@ describe('Transaction error rate alert', () => { expect(services.alertsClient.setAlertData).toHaveBeenCalledWith({ context: { - alertDetailsUrl: 'mockedAlertsLocator > getLocation', + alertDetailsUrl: 'http://localhost:5601/eyr/app/observability/alerts/test-uuid', environment: 'env-foo', interval: '5 mins', reason: @@ -242,7 +242,7 @@ describe('Transaction error rate alert', () => { expect(services.alertsClient.setAlertData).toHaveBeenCalledWith({ context: { - alertDetailsUrl: 'mockedAlertsLocator > getLocation', + alertDetailsUrl: 'http://localhost:5601/eyr/app/observability/alerts/test-uuid', environment: 'env-foo', interval: '5 mins', reason: @@ -355,7 +355,7 @@ describe('Transaction error rate alert', () => { expect(services.alertsClient.setAlertData).toHaveBeenCalledWith({ context: { - alertDetailsUrl: 'mockedAlertsLocator > getLocation', + alertDetailsUrl: 'http://localhost:5601/eyr/app/observability/alerts/test-uuid', environment: 'env-foo', interval: '5 mins', reason: @@ -468,7 +468,7 @@ describe('Transaction error rate alert', () => { expect(services.alertsClient.setAlertData).toHaveBeenCalledWith({ context: { - alertDetailsUrl: 'mockedAlertsLocator > getLocation', + alertDetailsUrl: 'http://localhost:5601/eyr/app/observability/alerts/test-uuid', environment: 'Not defined', interval: '5 mins', reason: @@ -569,7 +569,7 @@ describe('Transaction error rate alert', () => { expect(services.alertsClient.setAlertData).toHaveBeenCalledWith({ context: { - alertDetailsUrl: 'mockedAlertsLocator > getLocation', + alertDetailsUrl: 'http://localhost:5601/eyr/app/observability/alerts/test-uuid', environment: 'env-bar', interval: '5 mins', reason: diff --git a/x-pack/plugins/observability_solution/apm/server/routes/alerts/rule_types/transaction_error_rate/register_transaction_error_rate_rule_type.ts b/x-pack/plugins/observability_solution/apm/server/routes/alerts/rule_types/transaction_error_rate/register_transaction_error_rate_rule_type.ts index cff5a481f9200..1090a1c91d54b 100644 --- a/x-pack/plugins/observability_solution/apm/server/routes/alerts/rule_types/transaction_error_rate/register_transaction_error_rate_rule_type.ts +++ b/x-pack/plugins/observability_solution/apm/server/routes/alerts/rule_types/transaction_error_rate/register_transaction_error_rate_rule_type.ts @@ -17,7 +17,7 @@ import { } from '@kbn/alerting-plugin/server'; import { formatDurationFromTimeUnitChar, - getAlertUrl, + getAlertDetailsUrl, observabilityPaths, ProcessorEvent, TimeUnitChar, @@ -137,7 +137,7 @@ export function registerTransactionErrorRateRuleType({ TransactionErrorRateAlert > ) => { - const { services, spaceId, params: ruleParams, startedAt, getTimeRange } = options; + const { services, spaceId, params: ruleParams, getTimeRange } = options; const { alertsClient, savedObjectsClient, scopedClusterClient, uiSettingsClient } = services; if (!alertsClient) { throw new AlertsClientError(); @@ -273,11 +273,10 @@ export function registerTransactionErrorRateRuleType({ groupByFields, }); - const { uuid, start } = alertsClient.report({ + const { uuid } = alertsClient.report({ id: alertId, actionGroup: ruleTypeConfig.defaultActionGroupId, }); - const indexedStartedAt = start ?? startedAt.toISOString(); const relativeViewInAppUrl = getAlertUrlTransaction( groupByFields[SERVICE_NAME], @@ -289,13 +288,7 @@ export function registerTransactionErrorRateRuleType({ spaceId, relativeViewInAppUrl ); - const alertDetailsUrl = await getAlertUrl( - uuid, - spaceId, - indexedStartedAt, - alertsLocator, - basePath.publicBaseUrl - ); + const alertDetailsUrl = await getAlertDetailsUrl(basePath, spaceId, uuid); const groupByActionVariables = getGroupByActionVariables(groupByFields); const payload = { diff --git a/x-pack/plugins/observability_solution/apm/server/routes/alerts/test_utils/index.ts b/x-pack/plugins/observability_solution/apm/server/routes/alerts/test_utils/index.ts index 8db29408d4752..ce3e67baea1d6 100644 --- a/x-pack/plugins/observability_solution/apm/server/routes/alerts/test_utils/index.ts +++ b/x-pack/plugins/observability_solution/apm/server/routes/alerts/test_utils/index.ts @@ -7,8 +7,6 @@ import { IBasePath, Logger } from '@kbn/core/server'; import { elasticsearchServiceMock } from '@kbn/core/server/mocks'; -import type { AlertsLocatorParams } from '@kbn/observability-plugin/common'; -import { LocatorPublic } from '@kbn/share-plugin/common'; import { IRuleDataClient } from '@kbn/rule-registry-plugin/server'; import { ruleRegistryMocks } from '@kbn/rule-registry-plugin/server/mocks'; import { PluginSetupContract as AlertingPluginSetupContract } from '@kbn/alerting-plugin/server'; @@ -80,11 +78,6 @@ export const createRuleTypeMocks = () => { ruleDataClient: ruleRegistryMocks.createRuleDataClient( '.alerts-observability.apm.alerts' ) as IRuleDataClient, - alertsLocator: { - getLocation: jest.fn().mockImplementation(() => ({ - path: 'mockedAlertsLocator > getLocation', - })), - } as any as LocatorPublic, } as unknown as RegisterRuleDependencies; return { diff --git a/x-pack/plugins/observability_solution/infra/server/lib/alerting/inventory_metric_threshold/inventory_metric_threshold_executor.ts b/x-pack/plugins/observability_solution/infra/server/lib/alerting/inventory_metric_threshold/inventory_metric_threshold_executor.ts index d4c5a3b25c902..38bbe40e69855 100644 --- a/x-pack/plugins/observability_solution/infra/server/lib/alerting/inventory_metric_threshold/inventory_metric_threshold_executor.ts +++ b/x-pack/plugins/observability_solution/infra/server/lib/alerting/inventory_metric_threshold/inventory_metric_threshold_executor.ts @@ -21,7 +21,7 @@ import { AlertInstanceState as AlertState, } from '@kbn/alerting-plugin/common'; import { AlertsClientError, RuleExecutorOptions, RuleTypeState } from '@kbn/alerting-plugin/server'; -import { convertToBuiltInComparators, getAlertUrl } from '@kbn/observability-plugin/common'; +import { convertToBuiltInComparators, getAlertDetailsUrl } from '@kbn/observability-plugin/common'; import type { InventoryItemType, SnapshotMetricType } from '@kbn/metrics-data-access-plugin/common'; import { ObservabilityMetricsAlert } from '@kbn/alerts-as-data-utils'; import { getOriginalActionGroup } from '../../../utils/get_original_action_group'; @@ -140,13 +140,7 @@ export const createInventoryMetricThresholdExecutor = [ALERT_REASON]: reason, }, context: { - alertDetailsUrl: await getAlertUrl( - uuid, - spaceId, - indexedStartedAt, - alertsLocator, - libs.basePath.publicBaseUrl - ), + alertDetailsUrl: await getAlertDetailsUrl(libs.basePath, spaceId, uuid), alertState: stateToAlertMessage[AlertStates.ERROR], group: UNGROUPED_FACTORY_KEY, metric: mapToConditionsLookup(criteria, (c) => c.metric), @@ -292,13 +286,7 @@ export const createInventoryMetricThresholdExecutor = scheduledActionsCount++; const context = { - alertDetailsUrl: await getAlertUrl( - uuid, - spaceId, - indexedStartedAt, - alertsLocator, - libs.basePath.publicBaseUrl - ), + alertDetailsUrl: await getAlertDetailsUrl(libs.basePath, spaceId, uuid), alertState: stateToAlertMessage[nextState], group, reason, @@ -346,13 +334,7 @@ export const createInventoryMetricThresholdExecutor = const originalActionGroup = getOriginalActionGroup(alertHits); const recoveredContext = { - alertDetailsUrl: await getAlertUrl( - alertUuid, - spaceId, - indexedStartedAt, - alertsLocator, - libs.basePath.publicBaseUrl - ), + alertDetailsUrl: await getAlertDetailsUrl(libs.basePath, spaceId, alertUuid), alertState: stateToAlertMessage[AlertStates.OK], group: recoveredAlertId, metric: mapToConditionsLookup(criteria, (c) => c.metric), diff --git a/x-pack/plugins/observability_solution/infra/server/lib/alerting/metric_threshold/metric_threshold_executor.test.ts b/x-pack/plugins/observability_solution/infra/server/lib/alerting/metric_threshold/metric_threshold_executor.test.ts index 47266cee5ec06..9777f7ceda476 100644 --- a/x-pack/plugins/observability_solution/infra/server/lib/alerting/metric_threshold/metric_threshold_executor.test.ts +++ b/x-pack/plugins/observability_solution/infra/server/lib/alerting/metric_threshold/metric_threshold_executor.test.ts @@ -2384,7 +2384,7 @@ describe('The metric threshold rule type', () => { }); expect(services.alertsClient.setAlertData).toHaveBeenNthCalledWith(index, { context: { - alertDetailsUrl: '', + alertDetailsUrl: `http://localhost:5601/app/observability/alerts/uuid-${id}`, alertState, group: id, reason, diff --git a/x-pack/plugins/observability_solution/infra/server/lib/alerting/metric_threshold/metric_threshold_executor.ts b/x-pack/plugins/observability_solution/infra/server/lib/alerting/metric_threshold/metric_threshold_executor.ts index a98253553e4f2..ff75a4b84c466 100644 --- a/x-pack/plugins/observability_solution/infra/server/lib/alerting/metric_threshold/metric_threshold_executor.ts +++ b/x-pack/plugins/observability_solution/infra/server/lib/alerting/metric_threshold/metric_threshold_executor.ts @@ -20,7 +20,7 @@ import { RecoveredActionGroup, } from '@kbn/alerting-plugin/common'; import { AlertsClientError, RuleExecutorOptions, RuleTypeState } from '@kbn/alerting-plugin/server'; -import { TimeUnitChar, getAlertUrl } from '@kbn/observability-plugin/common'; +import { TimeUnitChar, getAlertDetailsUrl } from '@kbn/observability-plugin/common'; import { ObservabilityMetricsAlert } from '@kbn/alerts-as-data-utils'; import { COMPARATORS } from '@kbn/alerting-comparators'; import { getEcsGroups, type Group } from '@kbn/observability-alerting-rule-utils'; @@ -153,7 +153,7 @@ export const createMetricThresholdExecutor = groups, thresholds, }) => { - const { uuid, start } = alertsClient.report({ + const { uuid } = alertsClient.report({ id, actionGroup, }); @@ -170,13 +170,7 @@ export const createMetricThresholdExecutor = }, context: { ...contextWithoutAlertDetailsUrl, - alertDetailsUrl: await getAlertUrl( - uuid, - spaceId, - start ?? startedAt.toISOString(), - alertsLocator, - libs.basePath.publicBaseUrl - ), + alertDetailsUrl: await getAlertDetailsUrl(libs.basePath, spaceId, uuid), }, }); }; @@ -456,13 +450,7 @@ export const createMetricThresholdExecutor = const originalActionGroup = getOriginalActionGroup(alertHits); recoveredAlert.alert.setContext({ - alertDetailsUrl: await getAlertUrl( - alertUuid, - spaceId, - indexedStartedAt, - alertsLocator, - libs.basePath.publicBaseUrl - ), + alertDetailsUrl: await getAlertDetailsUrl(libs.basePath, spaceId, alertUuid), alertState: stateToAlertMessage[AlertStates.OK], group: recoveredAlertId, groupByKeys: groupByKeysObjectForRecovered[recoveredAlertId], diff --git a/x-pack/plugins/observability_solution/slo/server/lib/rules/slo_burn_rate/executor.test.ts b/x-pack/plugins/observability_solution/slo/server/lib/rules/slo_burn_rate/executor.test.ts index 28fdae0c12f38..32090cf88390c 100644 --- a/x-pack/plugins/observability_solution/slo/server/lib/rules/slo_burn_rate/executor.test.ts +++ b/x-pack/plugins/observability_solution/slo/server/lib/rules/slo_burn_rate/executor.test.ts @@ -25,9 +25,7 @@ import { import { ISearchStartSearchSource } from '@kbn/data-plugin/public'; import { dataViewPluginMocks } from '@kbn/data-views-plugin/public/mocks'; import { MockedLogger } from '@kbn/logging-mocks'; -import { AlertsLocatorParams } from '@kbn/observability-plugin/common'; import { Rule } from '@kbn/alerting-plugin/common'; -import { LocatorPublic } from '@kbn/share-plugin/common'; import { SharePluginStart } from '@kbn/share-plugin/server'; import { sloDefinitionSchema } from '@kbn/slo-schema'; import { get } from 'lodash'; @@ -148,13 +146,6 @@ describe('BurnRateRuleExecutor', () => { let soClientMock: jest.Mocked; let loggerMock: jest.Mocked; const basePathMock = { publicBaseUrl: 'https://kibana.dev' } as IBasePath; - const alertsLocatorMock = { - getLocation: jest.fn().mockImplementation(() => ({ - path: 'mockedAlertsLocator > getLocation', - })), - } as any as LocatorPublic; - const ISO_DATE_REGEX = - /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)((-(\d{2}):(\d{2})|Z)?)$/; let searchSourceClientMock: jest.Mocked; let uiSettingsClientMock: jest.Mocked; @@ -375,7 +366,6 @@ describe('BurnRateRuleExecutor', () => { const executor = getRuleExecutor({ basePath: basePathMock, - alertsLocator: alertsLocatorMock, }); await executor({ @@ -456,7 +446,7 @@ describe('BurnRateRuleExecutor', () => { burnRateThreshold: 2, reason: 'CRITICAL: The burn rate for the past 1h is 2.3 and for the past 5m is 2.1 for foo,asia. Alert when above 2 for both windows', - alertDetailsUrl: 'mockedAlertsLocator > getLocation', + alertDetailsUrl: 'https://kibana.dev/s/irrelevant/app/observability/alerts/uuid-foo,asia', }), }); expect(servicesMock.alertsClient?.setAlertData).toHaveBeenNthCalledWith(2, { @@ -467,23 +457,9 @@ describe('BurnRateRuleExecutor', () => { burnRateThreshold: 2, reason: 'CRITICAL: The burn rate for the past 1h is 2.5 and for the past 5m is 2.2 for bar,asia. Alert when above 2 for both windows', - alertDetailsUrl: 'mockedAlertsLocator > getLocation', + alertDetailsUrl: 'https://kibana.dev/s/irrelevant/app/observability/alerts/uuid-bar,asia', }), }); - - expect(alertsLocatorMock.getLocation).toHaveBeenCalledTimes(2); - expect(alertsLocatorMock.getLocation).toHaveBeenNthCalledWith(1, { - baseUrl: 'https://kibana.dev', - kuery: 'kibana.alert.uuid: "uuid-foo,asia"', - rangeFrom: expect.stringMatching(ISO_DATE_REGEX), - spaceId: 'irrelevant', - }); - expect(alertsLocatorMock.getLocation).toHaveBeenNthCalledWith(2, { - baseUrl: 'https://kibana.dev', - kuery: 'kibana.alert.uuid: "uuid-bar,asia"', - rangeFrom: expect.stringMatching(ISO_DATE_REGEX), - spaceId: 'irrelevant', - }); }); it('schedules a suppressed alert when both windows of first window definition burn rate have reached the threshold but the dependency matches', async () => { @@ -539,7 +515,6 @@ describe('BurnRateRuleExecutor', () => { const executor = getRuleExecutor({ basePath: basePathMock, - alertsLocator: alertsLocatorMock, }); await executor({ @@ -609,7 +584,7 @@ describe('BurnRateRuleExecutor', () => { burnRateThreshold: 2, reason: 'SUPPRESSED - CRITICAL: The burn rate for the past 1h is 2.3 and for the past 5m is 2.1 for foo. Alert when above 2 for both windows', - alertDetailsUrl: 'mockedAlertsLocator > getLocation', + alertDetailsUrl: 'https://kibana.dev/s/irrelevant/app/observability/alerts/uuid-foo', }), }); expect(servicesMock.alertsClient?.setAlertData).toHaveBeenNthCalledWith(2, { @@ -620,16 +595,9 @@ describe('BurnRateRuleExecutor', () => { burnRateThreshold: 2, reason: 'SUPPRESSED - CRITICAL: The burn rate for the past 1h is 2.5 and for the past 5m is 2.2 for bar. Alert when above 2 for both windows', - alertDetailsUrl: 'mockedAlertsLocator > getLocation', + alertDetailsUrl: 'https://kibana.dev/s/irrelevant/app/observability/alerts/uuid-bar', }), }); - - expect(alertsLocatorMock.getLocation).toBeCalledWith({ - baseUrl: 'https://kibana.dev', - kuery: 'kibana.alert.uuid: "uuid-foo"', - rangeFrom: expect.stringMatching(ISO_DATE_REGEX), - spaceId: 'irrelevant', - }); }); it('schedules an alert when both windows of second window definition burn rate have reached the threshold', async () => { diff --git a/x-pack/plugins/observability_solution/slo/server/lib/rules/slo_burn_rate/executor.ts b/x-pack/plugins/observability_solution/slo/server/lib/rules/slo_burn_rate/executor.ts index 6fbf8bcc0e891..7671ed7ebbaa3 100644 --- a/x-pack/plugins/observability_solution/slo/server/lib/rules/slo_burn_rate/executor.ts +++ b/x-pack/plugins/observability_solution/slo/server/lib/rules/slo_burn_rate/executor.ts @@ -21,7 +21,7 @@ import { LocatorPublic } from '@kbn/share-plugin/common'; import { upperCase } from 'lodash'; import { addSpaceIdToPath } from '@kbn/spaces-plugin/server'; import { ALL_VALUE } from '@kbn/slo-schema'; -import { AlertsLocatorParams, getAlertUrl } from '@kbn/observability-plugin/common'; +import { AlertsLocatorParams, getAlertDetailsUrl } from '@kbn/observability-plugin/common'; import { ObservabilitySloAlert } from '@kbn/alerts-as-data-utils'; import { ExecutorType } from '@kbn/alerting-plugin/server'; import { @@ -171,7 +171,7 @@ export const getRuleExecutor = ({ ? SUPPRESSED_PRIORITY_ACTION.id : windowDef.actionGroup; - const { uuid, start } = alertsClient.report({ + const { uuid } = alertsClient.report({ id: alertId, actionGroup, state: { @@ -189,14 +189,7 @@ export const getRuleExecutor = ({ }, }); - const indexedStartedAt = start ?? startedAt.toISOString(); - const alertDetailsUrl = await getAlertUrl( - uuid, - spaceId, - indexedStartedAt, - alertsLocator, - basePath.publicBaseUrl - ); + const alertDetailsUrl = await getAlertDetailsUrl(basePath, spaceId, uuid); const context = { alertDetailsUrl, @@ -228,15 +221,8 @@ export const getRuleExecutor = ({ const recoveredAlerts = alertsClient.getRecoveredAlerts() ?? []; for (const recoveredAlert of recoveredAlerts) { const alertId = recoveredAlert.alert.getId(); - const indexedStartedAt = recoveredAlert.alert.getStart() ?? startedAt.toISOString(); const alertUuid = recoveredAlert.alert.getUuid(); - const alertDetailsUrl = await getAlertUrl( - alertUuid, - spaceId, - indexedStartedAt, - alertsLocator, - basePath.publicBaseUrl - ); + const alertDetailsUrl = await getAlertDetailsUrl(basePath, spaceId, alertUuid); const urlQuery = alertId === ALL_VALUE ? '' : `?instanceId=${alertId}`; const viewInAppUrl = addSpaceIdToPath( diff --git a/x-pack/plugins/observability_solution/synthetics/server/alert_rules/common.ts b/x-pack/plugins/observability_solution/synthetics/server/alert_rules/common.ts index 27f051ff2e9c9..18ade57662ed3 100644 --- a/x-pack/plugins/observability_solution/synthetics/server/alert_rules/common.ts +++ b/x-pack/plugins/observability_solution/synthetics/server/alert_rules/common.ts @@ -4,6 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ + import moment, { Moment } from 'moment'; import { isRight } from 'fp-ts/lib/Either'; import Mustache from 'mustache'; @@ -14,6 +15,7 @@ import { AlertInstanceContext as AlertContext, AlertInstanceState as AlertState, } from '@kbn/alerting-plugin/server'; +import { getAlertDetailsUrl } from '@kbn/observability-plugin/common'; import { addSpaceIdToPath } from '@kbn/spaces-plugin/common'; import { i18n } from '@kbn/i18n'; import { fromKueryExpression, toElasticsearchQuery } from '@kbn/es-query'; @@ -113,12 +115,6 @@ export const getViewInAppUrl = ( relativeViewInAppUrl: string ) => addSpaceIdToPath(basePath.publicBaseUrl, spaceId, relativeViewInAppUrl); -export const getAlertDetailsUrl = ( - basePath: IBasePath, - spaceId: string, - alertUuid: string | null -) => addSpaceIdToPath(basePath.publicBaseUrl, spaceId, `/app/observability/alerts/${alertUuid}`); - export const getRelativeViewInAppUrl = ({ configId, stateId, diff --git a/x-pack/plugins/observability_solution/synthetics/server/alert_rules/status_rule/monitor_status_rule.ts b/x-pack/plugins/observability_solution/synthetics/server/alert_rules/status_rule/monitor_status_rule.ts index 3ca5aeb94af58..a5d530f2ec53b 100644 --- a/x-pack/plugins/observability_solution/synthetics/server/alert_rules/status_rule/monitor_status_rule.ts +++ b/x-pack/plugins/observability_solution/synthetics/server/alert_rules/status_rule/monitor_status_rule.ts @@ -14,7 +14,7 @@ import { RuleExecutorOptions, AlertsClientError, } from '@kbn/alerting-plugin/server'; -import { observabilityPaths } from '@kbn/observability-plugin/common'; +import { getAlertDetailsUrl, observabilityPaths } from '@kbn/observability-plugin/common'; import { ObservabilityUptimeAlert } from '@kbn/alerts-as-data-utils'; import { syntheticsRuleFieldMap } from '../../../common/rules/synthetics_rule_field_map'; import { SyntheticsPluginsSetupDependencies, SyntheticsServerSetup } from '../../types'; @@ -33,7 +33,6 @@ import { import { setRecoveredAlertsContext, updateState, - getAlertDetailsUrl, getViewInAppUrl, getRelativeViewInAppUrl, getFullViewInAppMessage, diff --git a/x-pack/plugins/observability_solution/synthetics/server/alert_rules/tls_rule/message_utils.test.ts b/x-pack/plugins/observability_solution/synthetics/server/alert_rules/tls_rule/message_utils.test.ts index e07ba00c1de6c..39fa7b185fb8d 100644 --- a/x-pack/plugins/observability_solution/synthetics/server/alert_rules/tls_rule/message_utils.test.ts +++ b/x-pack/plugins/observability_solution/synthetics/server/alert_rules/tls_rule/message_utils.test.ts @@ -4,9 +4,8 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ + import { IBasePath } from '@kbn/core/server'; -import { AlertsLocatorParams } from '@kbn/observability-plugin/common'; -import { LocatorPublic } from '@kbn/share-plugin/common'; import { setTLSRecoveredAlertsContext } from './message_utils'; import { TLSLatestPing } from './tls_rule_executor'; @@ -17,11 +16,6 @@ describe('setTLSRecoveredAlertsContext', () => { const basePath = { publicBaseUrl: 'https://localhost:5601', } as IBasePath; - const alertsLocatorMock = { - getLocation: jest.fn().mockImplementation(() => ({ - path: 'https://localhost:5601/app/observability/alerts/alert-id', - })), - } as any as LocatorPublic; const alertState = { summary: 'test-summary', status: 'has expired', @@ -57,9 +51,7 @@ describe('setTLSRecoveredAlertsContext', () => { await setTLSRecoveredAlertsContext({ alertsClient: alertsClientMock, basePath, - defaultStartedAt: timestamp, spaceId: 'default', - alertsLocator: alertsLocatorMock, latestPings: [ { config_id: configId, @@ -122,9 +114,7 @@ describe('setTLSRecoveredAlertsContext', () => { await setTLSRecoveredAlertsContext({ alertsClient: alertsClientMock, basePath, - defaultStartedAt: timestamp, spaceId: 'default', - alertsLocator: alertsLocatorMock, latestPings: [ { config_id: configId, diff --git a/x-pack/plugins/observability_solution/synthetics/server/alert_rules/tls_rule/message_utils.ts b/x-pack/plugins/observability_solution/synthetics/server/alert_rules/tls_rule/message_utils.ts index 5fc23a370caea..3f0650f12ee8b 100644 --- a/x-pack/plugins/observability_solution/synthetics/server/alert_rules/tls_rule/message_utils.ts +++ b/x-pack/plugins/observability_solution/synthetics/server/alert_rules/tls_rule/message_utils.ts @@ -7,8 +7,7 @@ import moment from 'moment/moment'; import { IBasePath } from '@kbn/core-http-server'; -import { LocatorPublic } from '@kbn/share-plugin/common'; -import { AlertsLocatorParams, getAlertUrl } from '@kbn/observability-plugin/common'; +import { getAlertDetailsUrl } from '@kbn/observability-plugin/common'; import { AlertInstanceContext as AlertContext, AlertInstanceState as AlertState, @@ -85,9 +84,7 @@ export const getCertSummary = (cert: Cert, expirationThreshold: number, ageThres export const setTLSRecoveredAlertsContext = async ({ alertsClient, basePath, - defaultStartedAt, spaceId, - alertsLocator, latestPings, }: { alertsClient: PublicAlertsClient< @@ -96,10 +93,8 @@ export const setTLSRecoveredAlertsContext = async ({ AlertContext, ActionGroupIdsOf >; - defaultStartedAt: string; basePath: IBasePath; spaceId: string; - alertsLocator?: LocatorPublic; latestPings: TLSLatestPing[]; }) => { const recoveredAlerts = alertsClient.getRecoveredAlerts() ?? []; @@ -107,16 +102,9 @@ export const setTLSRecoveredAlertsContext = async ({ for (const recoveredAlert of recoveredAlerts) { const recoveredAlertId = recoveredAlert.alert.getId(); const alertUuid = recoveredAlert.alert.getUuid(); - const indexedStartedAt = recoveredAlert.alert.getStart() ?? defaultStartedAt; const state = recoveredAlert.alert.getState(); - const alertUrl = await getAlertUrl( - alertUuid, - spaceId, - indexedStartedAt, - alertsLocator, - basePath.publicBaseUrl - ); + const alertUrl = await getAlertDetailsUrl(basePath, spaceId, alertUuid); const configId = state.configId; const latestPing = latestPings.find((ping) => ping.config_id === configId); diff --git a/x-pack/plugins/observability_solution/synthetics/server/alert_rules/tls_rule/tls_rule.ts b/x-pack/plugins/observability_solution/synthetics/server/alert_rules/tls_rule/tls_rule.ts index 3aaafcaf17468..1339aeac89ad3 100644 --- a/x-pack/plugins/observability_solution/synthetics/server/alert_rules/tls_rule/tls_rule.ts +++ b/x-pack/plugins/observability_solution/synthetics/server/alert_rules/tls_rule/tls_rule.ts @@ -15,13 +15,7 @@ import { } from '@kbn/alerting-plugin/server'; import { asyncForEach } from '@kbn/std'; import { ALERT_REASON, ALERT_UUID } from '@kbn/rule-data-utils'; -import { - alertsLocatorID, - AlertsLocatorParams, - getAlertUrl, - observabilityPaths, -} from '@kbn/observability-plugin/common'; -import { LocatorPublic } from '@kbn/share-plugin/common'; +import { getAlertDetailsUrl, observabilityPaths } from '@kbn/observability-plugin/common'; import { schema } from '@kbn/config-schema'; import { ObservabilityUptimeAlert } from '@kbn/alerts-as-data-utils'; import { syntheticsRuleFieldMap } from '../../../common/rules/synthetics_rule_field_map'; @@ -92,14 +86,12 @@ export const registerSyntheticsTLSCheckRule = ( TLSAlert > ) => { - const { state: ruleState, params, services, spaceId, previousStartedAt, startedAt } = options; + const { state: ruleState, params, services, spaceId, previousStartedAt } = options; const { alertsClient, savedObjectsClient, scopedClusterClient } = services; if (!alertsClient) { throw new AlertsClientError(); } - const { basePath, share } = server; - const alertsLocator: LocatorPublic | undefined = - share.url.locators.get(alertsLocatorID); + const { basePath } = server; const tlsRule = new TLSRuleExecutor( previousStartedAt, @@ -121,12 +113,11 @@ export const registerSyntheticsTLSCheckRule = ( } const alertId = cert.sha256; - const { uuid, start } = alertsClient.report({ + const { uuid } = alertsClient.report({ id: alertId, actionGroup: TLS_CERTIFICATE.id, state: { ...updateState(ruleState, foundCerts), ...summary }, }); - const indexedStartedAt = start ?? startedAt.toISOString(); const payload = { [CERT_COMMON_NAME]: cert.common_name, @@ -139,13 +130,7 @@ export const registerSyntheticsTLSCheckRule = ( }; const context = { - [ALERT_DETAILS_URL]: await getAlertUrl( - uuid, - spaceId, - indexedStartedAt, - alertsLocator, - basePath.publicBaseUrl - ), + [ALERT_DETAILS_URL]: await getAlertDetailsUrl(basePath, spaceId, uuid), ...summary, }; @@ -159,9 +144,7 @@ export const registerSyntheticsTLSCheckRule = ( await setTLSRecoveredAlertsContext({ alertsClient, basePath, - defaultStartedAt: startedAt.toISOString(), spaceId, - alertsLocator, latestPings, }); diff --git a/x-pack/test/alerting_api_integration/observability/metric_threshold_rule.ts b/x-pack/test/alerting_api_integration/observability/metric_threshold_rule.ts index bc36566f91f52..4a1459d350ea6 100644 --- a/x-pack/test/alerting_api_integration/observability/metric_threshold_rule.ts +++ b/x-pack/test/alerting_api_integration/observability/metric_threshold_rule.ts @@ -5,7 +5,6 @@ * 2.0. */ -import moment from 'moment'; import expect from '@kbn/expect'; import { cleanup, generate, Dataset, PartialConfig } from '@kbn/data-forge'; import { @@ -33,7 +32,6 @@ export default function ({ getService }: FtrProviderContext) { describe('Metric threshold rule >', () => { let ruleId: string; let alertId: string; - let startedAt: string; let actionId: string; let dataForgeConfig: PartialConfig; let dataForgeIndices: string[]; @@ -159,7 +157,6 @@ export default function ({ getService }: FtrProviderContext) { logger, }); alertId = (resp.hits.hits[0]._source as any)['kibana.alert.uuid']; - startedAt = (resp.hits.hits[0]._source as any)['kibana.alert.start']; expect(resp.hits.hits[0]._source).property( 'kibana.alert.rule.category', 'Metric threshold' @@ -210,7 +207,6 @@ export default function ({ getService }: FtrProviderContext) { }); it('should set correct action parameter: ruleType', async () => { - const rangeFrom = moment(startedAt).subtract('5', 'minute').toISOString(); const resp = await waitForDocumentInIndex<{ ruleType: string; alertDetailsUrl: string; @@ -224,7 +220,7 @@ export default function ({ getService }: FtrProviderContext) { expect(resp.hits.hits[0]._source?.ruleType).eql('metrics.alert.threshold'); expect(resp.hits.hits[0]._source?.alertDetailsUrl).eql( - `https://localhost:5601/app/observability/alerts?_a=(kuery:%27kibana.alert.uuid:%20%22${alertId}%22%27%2CrangeFrom:%27${rangeFrom}%27%2CrangeTo:now%2Cstatus:all)` + `https://localhost:5601/app/observability/alerts/${alertId}` ); expect(resp.hits.hits[0]._source?.reason).eql( `system.cpu.user.pct is 90% in the last 5 mins. Alert when above 50%.`