mirror of
https://github.com/elastic/kibana.git
synced 2025-04-25 02:09:32 -04:00
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

This commit is contained in:
parent
ee6ca657ee
commit
f758ba4750
4 changed files with 41 additions and 15 deletions
|
@ -9,6 +9,7 @@ import { isEmpty, isError } from 'lodash';
|
||||||
import { schema } from '@kbn/config-schema';
|
import { schema } from '@kbn/config-schema';
|
||||||
import { Logger, LogMeta } from '@kbn/logging';
|
import { Logger, LogMeta } from '@kbn/logging';
|
||||||
import type { ElasticsearchClient, IBasePath } from '@kbn/core/server';
|
import type { ElasticsearchClient, IBasePath } from '@kbn/core/server';
|
||||||
|
import { ObservabilityConfig } from '@kbn/observability-plugin/server';
|
||||||
import { addSpaceIdToPath } from '@kbn/spaces-plugin/common';
|
import { addSpaceIdToPath } from '@kbn/spaces-plugin/common';
|
||||||
import { ALERT_RULE_PARAMETERS, TIMESTAMP } from '@kbn/rule-data-utils';
|
import { ALERT_RULE_PARAMETERS, TIMESTAMP } from '@kbn/rule-data-utils';
|
||||||
import {
|
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 = ({
|
export const getViewInInventoryAppUrl = ({
|
||||||
basePath,
|
basePath,
|
||||||
criteria,
|
criteria,
|
||||||
|
|
|
@ -7,7 +7,11 @@
|
||||||
|
|
||||||
import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
|
import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
|
||||||
import { i18n } from '@kbn/i18n';
|
import { i18n } from '@kbn/i18n';
|
||||||
import { getAlertUrl, AlertsLocatorParams } from '@kbn/observability-plugin/common';
|
import {
|
||||||
|
AlertsLocatorParams,
|
||||||
|
getAlertDetailsUrl,
|
||||||
|
getAlertUrl,
|
||||||
|
} from '@kbn/observability-plugin/common';
|
||||||
import {
|
import {
|
||||||
ALERT_CONTEXT,
|
ALERT_CONTEXT,
|
||||||
ALERT_EVALUATION_THRESHOLD,
|
ALERT_EVALUATION_THRESHOLD,
|
||||||
|
@ -59,6 +63,7 @@ import { InfraBackendLibs } from '../../infra_types';
|
||||||
import {
|
import {
|
||||||
AdditionalContext,
|
AdditionalContext,
|
||||||
flattenAdditionalContext,
|
flattenAdditionalContext,
|
||||||
|
getAlertDetailsPageEnabledForApp,
|
||||||
getContextForRecoveredAlerts,
|
getContextForRecoveredAlerts,
|
||||||
getGroupByObject,
|
getGroupByObject,
|
||||||
unflattenObject,
|
unflattenObject,
|
||||||
|
@ -133,6 +138,7 @@ export const createLogThresholdExecutor = (libs: InfraBackendLibs) =>
|
||||||
getAlertByAlertUuid,
|
getAlertByAlertUuid,
|
||||||
} = services;
|
} = services;
|
||||||
const { basePath, alertsLocator } = libs;
|
const { basePath, alertsLocator } = libs;
|
||||||
|
const config = libs.getAlertDetailsConfig();
|
||||||
|
|
||||||
const alertFactory: LogThresholdAlertFactory = (
|
const alertFactory: LogThresholdAlertFactory = (
|
||||||
id,
|
id,
|
||||||
|
@ -183,7 +189,9 @@ export const createLogThresholdExecutor = (libs: InfraBackendLibs) =>
|
||||||
alert.scheduleActions(actionGroup, {
|
alert.scheduleActions(actionGroup, {
|
||||||
...sharedContext,
|
...sharedContext,
|
||||||
...context,
|
...context,
|
||||||
alertDetailsUrl: await getAlertUrl(
|
alertDetailsUrl: getAlertDetailsPageEnabledForApp(config, 'logs')
|
||||||
|
? getAlertDetailsUrl(libs.basePath, spaceId, alertUuid)
|
||||||
|
: await getAlertUrl(
|
||||||
alertUuid,
|
alertUuid,
|
||||||
spaceId,
|
spaceId,
|
||||||
indexedStartedAt,
|
indexedStartedAt,
|
||||||
|
@ -246,6 +254,7 @@ export const createLogThresholdExecutor = (libs: InfraBackendLibs) =>
|
||||||
validatedParams,
|
validatedParams,
|
||||||
getAlertByAlertUuid,
|
getAlertByAlertUuid,
|
||||||
alertsLocator,
|
alertsLocator,
|
||||||
|
isAlertDetailsPageEnabled: getAlertDetailsPageEnabledForApp(config, 'logs'),
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw new Error(e);
|
throw new Error(e);
|
||||||
|
@ -859,6 +868,7 @@ const processRecoveredAlerts = async ({
|
||||||
validatedParams,
|
validatedParams,
|
||||||
getAlertByAlertUuid,
|
getAlertByAlertUuid,
|
||||||
alertsLocator,
|
alertsLocator,
|
||||||
|
isAlertDetailsPageEnabled = false,
|
||||||
}: {
|
}: {
|
||||||
basePath: IBasePath;
|
basePath: IBasePath;
|
||||||
getAlertStartedDate: (alertId: string) => string | null;
|
getAlertStartedDate: (alertId: string) => string | null;
|
||||||
|
@ -871,6 +881,7 @@ const processRecoveredAlerts = async ({
|
||||||
alertUuid: string
|
alertUuid: string
|
||||||
) => Promise<Partial<ParsedTechnicalFields & ParsedExperimentalFields> | null> | null;
|
) => Promise<Partial<ParsedTechnicalFields & ParsedExperimentalFields> | null> | null;
|
||||||
alertsLocator?: LocatorPublic<AlertsLocatorParams>;
|
alertsLocator?: LocatorPublic<AlertsLocatorParams>;
|
||||||
|
isAlertDetailsPageEnabled?: boolean;
|
||||||
}) => {
|
}) => {
|
||||||
const groupByKeysObjectForRecovered = getGroupByObject(
|
const groupByKeysObjectForRecovered = getGroupByObject(
|
||||||
validatedParams.groupBy,
|
validatedParams.groupBy,
|
||||||
|
@ -887,7 +898,9 @@ const processRecoveredAlerts = async ({
|
||||||
const viewInAppUrl = addSpaceIdToPath(basePath.publicBaseUrl, spaceId, relativeViewInAppUrl);
|
const viewInAppUrl = addSpaceIdToPath(basePath.publicBaseUrl, spaceId, relativeViewInAppUrl);
|
||||||
|
|
||||||
const baseContext = {
|
const baseContext = {
|
||||||
alertDetailsUrl: await getAlertUrl(
|
alertDetailsUrl: isAlertDetailsPageEnabled
|
||||||
|
? getAlertDetailsUrl(basePath, spaceId, alertUuid)
|
||||||
|
: await getAlertUrl(
|
||||||
alertUuid,
|
alertUuid,
|
||||||
spaceId,
|
spaceId,
|
||||||
indexedStartedAt,
|
indexedStartedAt,
|
||||||
|
|
|
@ -9,6 +9,7 @@ import type { Logger } from '@kbn/logging';
|
||||||
import type { IBasePath } from '@kbn/core/server';
|
import type { IBasePath } from '@kbn/core/server';
|
||||||
import type { handleEsError } from '@kbn/es-ui-shared-plugin/server';
|
import type { handleEsError } from '@kbn/es-ui-shared-plugin/server';
|
||||||
import type { AlertsLocatorParams } from '@kbn/observability-plugin/common';
|
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 { LocatorPublic } from '@kbn/share-plugin/common';
|
||||||
import type { ILogsSharedLogEntriesDomain } from '@kbn/logs-shared-plugin/server';
|
import type { ILogsSharedLogEntriesDomain } from '@kbn/logs-shared-plugin/server';
|
||||||
import { RulesServiceSetup } from '../services/rules';
|
import { RulesServiceSetup } from '../services/rules';
|
||||||
|
@ -33,6 +34,7 @@ export interface InfraBackendLibs extends InfraDomainLibs {
|
||||||
metricsRules: RulesServiceSetup;
|
metricsRules: RulesServiceSetup;
|
||||||
sources: InfraSources;
|
sources: InfraSources;
|
||||||
sourceStatus: InfraSourceStatus;
|
sourceStatus: InfraSourceStatus;
|
||||||
|
getAlertDetailsConfig: () => ObservabilityConfig['unsafe']['alertDetails'];
|
||||||
getStartServices: InfraPluginStartServicesAccessor;
|
getStartServices: InfraPluginStartServicesAccessor;
|
||||||
handleEsError: typeof handleEsError;
|
handleEsError: typeof handleEsError;
|
||||||
logger: Logger;
|
logger: Logger;
|
||||||
|
|
|
@ -193,6 +193,7 @@ export class InfraServerPlugin
|
||||||
logsRules: this.logsRules.setup(core, plugins),
|
logsRules: this.logsRules.setup(core, plugins),
|
||||||
metricsRules: this.metricsRules.setup(core, plugins),
|
metricsRules: this.metricsRules.setup(core, plugins),
|
||||||
getStartServices: () => core.getStartServices(),
|
getStartServices: () => core.getStartServices(),
|
||||||
|
getAlertDetailsConfig: () => plugins.observability.getAlertDetailsConfig(),
|
||||||
logger: this.logger,
|
logger: this.logger,
|
||||||
basePath: core.http.basePath,
|
basePath: core.http.basePath,
|
||||||
alertsLocator: plugins.share.url.locators.get(alertsLocatorID),
|
alertsLocator: plugins.share.url.locators.get(alertsLocatorID),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue