Use alert details page URL for the log threshold rule if the config is enabled (#161175)

Fixes #161117

## Summary

If `xpack.observability.unsafe.alertDetails.logs.enabled` is enabled, we
will use the new alert details page URL in `context.alertDetailsUrl`
otherwise, we send the user to the alerts page filtered for that alert.
(Partially brings back [the logic for alert details
URL](https://github.com/elastic/kibana/pull/157987/files#diff-a71ca536380c1fde8805744b23566ce795707f92b94a03af73347cac46ccac63L1027)
and
[getAlertDetailsConfig](https://github.com/elastic/kibana/pull/157987/files#diff-a71ca536380c1fde8805744b23566ce795707f92b94a03af73347cac46ccac63L1027))

## 🧪 How to test

1. Set `xpack.observability.unsafe.alertDetails.logs.enabled` as false
in Kibana yml config or remove the config
2. Create a log threshold rule with an action for both active state and
recovered state
3. When the alert is triggered, check the default message, it should
include the alertDetailsURL, by clicking on that, you should land on the
alerts page filtered for that alert
4. Make the alert recovered and check and similar URL should be
generated

New alert details page:

1. Set `xpack.observability.unsafe.alertDetails.logs.enabled` as true in
Kibana yml config
2. Repeat the steps 2,3,4 as mentioned before
3. This time, you should land on the new alert details page


![image](a2f99bd7-cfaa-4146-bedf-72458973b463)
This commit is contained in:
Maryam Saeidi 2023-07-05 12:39:58 +02:00 committed by GitHub
parent ee6ca657ee
commit f758ba4750
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 41 additions and 15 deletions

View file

@ -9,6 +9,7 @@ import { isEmpty, isError } from 'lodash';
import { schema } from '@kbn/config-schema';
import { Logger, LogMeta } from '@kbn/logging';
import type { ElasticsearchClient, IBasePath } from '@kbn/core/server';
import { ObservabilityConfig } from '@kbn/observability-plugin/server';
import { addSpaceIdToPath } from '@kbn/spaces-plugin/common';
import { ALERT_RULE_PARAMETERS, TIMESTAMP } from '@kbn/rule-data-utils';
import {
@ -109,6 +110,15 @@ export const createScopedLogger = (
};
};
export const getAlertDetailsPageEnabledForApp = (
config: ObservabilityConfig['unsafe']['alertDetails'] | null,
appName: keyof ObservabilityConfig['unsafe']['alertDetails']
): boolean => {
if (!config) return false;
return config[appName].enabled;
};
export const getViewInInventoryAppUrl = ({
basePath,
criteria,

View file

@ -7,7 +7,11 @@
import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
import { i18n } from '@kbn/i18n';
import { getAlertUrl, AlertsLocatorParams } from '@kbn/observability-plugin/common';
import {
AlertsLocatorParams,
getAlertDetailsUrl,
getAlertUrl,
} from '@kbn/observability-plugin/common';
import {
ALERT_CONTEXT,
ALERT_EVALUATION_THRESHOLD,
@ -59,6 +63,7 @@ import { InfraBackendLibs } from '../../infra_types';
import {
AdditionalContext,
flattenAdditionalContext,
getAlertDetailsPageEnabledForApp,
getContextForRecoveredAlerts,
getGroupByObject,
unflattenObject,
@ -133,6 +138,7 @@ export const createLogThresholdExecutor = (libs: InfraBackendLibs) =>
getAlertByAlertUuid,
} = services;
const { basePath, alertsLocator } = libs;
const config = libs.getAlertDetailsConfig();
const alertFactory: LogThresholdAlertFactory = (
id,
@ -183,13 +189,15 @@ export const createLogThresholdExecutor = (libs: InfraBackendLibs) =>
alert.scheduleActions(actionGroup, {
...sharedContext,
...context,
alertDetailsUrl: await getAlertUrl(
alertUuid,
spaceId,
indexedStartedAt,
libs.alertsLocator,
libs.basePath.publicBaseUrl
),
alertDetailsUrl: getAlertDetailsPageEnabledForApp(config, 'logs')
? getAlertDetailsUrl(libs.basePath, spaceId, alertUuid)
: await getAlertUrl(
alertUuid,
spaceId,
indexedStartedAt,
libs.alertsLocator,
libs.basePath.publicBaseUrl
),
});
});
}
@ -246,6 +254,7 @@ export const createLogThresholdExecutor = (libs: InfraBackendLibs) =>
validatedParams,
getAlertByAlertUuid,
alertsLocator,
isAlertDetailsPageEnabled: getAlertDetailsPageEnabledForApp(config, 'logs'),
});
} catch (e) {
throw new Error(e);
@ -859,6 +868,7 @@ const processRecoveredAlerts = async ({
validatedParams,
getAlertByAlertUuid,
alertsLocator,
isAlertDetailsPageEnabled = false,
}: {
basePath: IBasePath;
getAlertStartedDate: (alertId: string) => string | null;
@ -871,6 +881,7 @@ const processRecoveredAlerts = async ({
alertUuid: string
) => Promise<Partial<ParsedTechnicalFields & ParsedExperimentalFields> | null> | null;
alertsLocator?: LocatorPublic<AlertsLocatorParams>;
isAlertDetailsPageEnabled?: boolean;
}) => {
const groupByKeysObjectForRecovered = getGroupByObject(
validatedParams.groupBy,
@ -887,13 +898,15 @@ const processRecoveredAlerts = async ({
const viewInAppUrl = addSpaceIdToPath(basePath.publicBaseUrl, spaceId, relativeViewInAppUrl);
const baseContext = {
alertDetailsUrl: await getAlertUrl(
alertUuid,
spaceId,
indexedStartedAt,
alertsLocator,
basePath.publicBaseUrl
),
alertDetailsUrl: isAlertDetailsPageEnabled
? getAlertDetailsUrl(basePath, spaceId, alertUuid)
: await getAlertUrl(
alertUuid,
spaceId,
indexedStartedAt,
alertsLocator,
basePath.publicBaseUrl
),
group: hasGroupBy(validatedParams) ? recoveredAlertId : null,
groupByKeys: groupByKeysObjectForRecovered[recoveredAlertId],
timestamp: startedAt.toISOString(),

View file

@ -9,6 +9,7 @@ import type { Logger } from '@kbn/logging';
import type { IBasePath } from '@kbn/core/server';
import type { handleEsError } from '@kbn/es-ui-shared-plugin/server';
import type { AlertsLocatorParams } from '@kbn/observability-plugin/common';
import { ObservabilityConfig } from '@kbn/observability-plugin/server';
import type { LocatorPublic } from '@kbn/share-plugin/common';
import type { ILogsSharedLogEntriesDomain } from '@kbn/logs-shared-plugin/server';
import { RulesServiceSetup } from '../services/rules';
@ -33,6 +34,7 @@ export interface InfraBackendLibs extends InfraDomainLibs {
metricsRules: RulesServiceSetup;
sources: InfraSources;
sourceStatus: InfraSourceStatus;
getAlertDetailsConfig: () => ObservabilityConfig['unsafe']['alertDetails'];
getStartServices: InfraPluginStartServicesAccessor;
handleEsError: typeof handleEsError;
logger: Logger;

View file

@ -193,6 +193,7 @@ export class InfraServerPlugin
logsRules: this.logsRules.setup(core, plugins),
metricsRules: this.metricsRules.setup(core, plugins),
getStartServices: () => core.getStartServices(),
getAlertDetailsConfig: () => plugins.observability.getAlertDetailsConfig(),
logger: this.logger,
basePath: core.http.basePath,
alertsLocator: plugins.share.url.locators.get(alertsLocatorID),