Remove feature flag for APM Alert Details page (#150475)

## Summary

This PR removes the
`xpack.observability.unsafe.alertDetails.apm.enabled` feature flag to
enable the Alert Detail page for the APM Latency Threshold Rule. I've
also removed the`alertDetailsAppSection` options along with the
`alertDetailsUrl` action context variable for the remaining APM rules
since the APM Alert Detail page should only be available for the APM
Latency Threshold rule.

I also changed`isAlertDetailsEnabledPerApp()` method to allow the
`apm.transaction_duration` rule type to work but not `apm.error_rate`,
`apm.transaction_error_rate`, or `apm.anomaly` rule types. This change
was necessary because the granularity of the feature flag was set to the
solution level and didn't allow to set the flag per rule type.

### Testing

To test this PR you will need to have some APM data in your cluster.
1. Create an APM Latency Threshold Rule with a low threshold so it will
trigger
2. Create an APM Error Count Rule with a low threshold so it will
trigger
3. Click on the "Action Menu" (the ellipses) in the alert (in the Alert
Table) for the latency threshold alert
4. Click on the "View alert details" menu item for the latency threshold
alert
5. Verify it takes you to the new "alert details" page for APM
6. Repeat steps 3 & 4 for the error count alert BUT it should open the
"alert flyout" instead.

---------

Co-authored-by: Faisal Kanout <faisal.kanout@elastic.co>
Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Chris Cowan 2023-03-20 17:32:55 -06:00 committed by GitHub
parent c1deeeb8d5
commit 2bd3e8dd20
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
22 changed files with 36 additions and 113 deletions

View file

@ -300,7 +300,6 @@ kibana_vars=(
xpack.ingestManager.fleet.tlsCheckDisabled xpack.ingestManager.fleet.tlsCheckDisabled
xpack.ingestManager.registryUrl xpack.ingestManager.registryUrl
xpack.observability.annotations.index xpack.observability.annotations.index
xpack.observability.unsafe.alertDetails.apm.enabled
xpack.observability.unsafe.alertDetails.metrics.enabled xpack.observability.unsafe.alertDetails.metrics.enabled
xpack.observability.unsafe.alertDetails.logs.enabled xpack.observability.unsafe.alertDetails.logs.enabled
xpack.observability.unsafe.alertDetails.uptime.enabled xpack.observability.unsafe.alertDetails.uptime.enabled

View file

@ -229,7 +229,6 @@ export default function ({ getService }: PluginFunctionalProviderContext) {
'xpack.upgrade_assistant.featureSet.mlSnapshots (boolean)', 'xpack.upgrade_assistant.featureSet.mlSnapshots (boolean)',
'xpack.upgrade_assistant.featureSet.reindexCorrectiveActions (boolean)', 'xpack.upgrade_assistant.featureSet.reindexCorrectiveActions (boolean)',
'xpack.upgrade_assistant.ui.enabled (boolean)', 'xpack.upgrade_assistant.ui.enabled (boolean)',
'xpack.observability.unsafe.alertDetails.apm.enabled (boolean)',
'xpack.observability.unsafe.alertDetails.metrics.enabled (boolean)', 'xpack.observability.unsafe.alertDetails.metrics.enabled (boolean)',
'xpack.observability.unsafe.alertDetails.logs.enabled (boolean)', 'xpack.observability.unsafe.alertDetails.logs.enabled (boolean)',
'xpack.observability.unsafe.alertDetails.uptime.enabled (boolean)', 'xpack.observability.unsafe.alertDetails.uptime.enabled (boolean)',

View file

@ -8,12 +8,6 @@ from files dual-licensed under the Server Side Public License and the Elastic Li
If you have: If you have:
```yaml
xpack.observability.unsafe.alertDetails.apm.enabled: true
```
**[For APM rule types]** In Kibana configuration, will allow the user to navigate to the new Alert Details page, instead of the Alert Flyout when clicking on `View alert details` in the Alert table
```yaml ```yaml
xpack.observability.unsafe.alertDetails.metrics.enabled: true xpack.observability.unsafe.alertDetails.metrics.enabled: true
``` ```

View file

@ -53,9 +53,6 @@ export function registerApmRuleTypes(
validate: () => ({ validate: () => ({
errors: [], errors: [],
}), }),
alertDetailsAppSection: lazy(
() => import('../ui_components/alert_details_app_section')
),
requiresAppContext: false, requiresAppContext: false,
defaultActionMessage: errorCountMessage, defaultActionMessage: errorCountMessage,
}); });
@ -69,7 +66,7 @@ export function registerApmRuleTypes(
'Alert when the latency of a specific transaction type in a service exceeds a defined threshold.', 'Alert when the latency of a specific transaction type in a service exceeds a defined threshold.',
} }
), ),
format: ({ fields, formatters: { asDuration } }) => { format: ({ fields }) => {
return { return {
reason: fields[ALERT_REASON]!, reason: fields[ALERT_REASON]!,
link: getAlertUrlTransaction( link: getAlertUrlTransaction(
@ -106,7 +103,7 @@ export function registerApmRuleTypes(
'Alert when the rate of transaction errors in a service exceeds a defined threshold.', 'Alert when the rate of transaction errors in a service exceeds a defined threshold.',
} }
), ),
format: ({ fields, formatters: { asPercent } }) => ({ format: ({ fields }) => ({
reason: fields[ALERT_REASON]!, reason: fields[ALERT_REASON]!,
link: getAlertUrlTransaction( link: getAlertUrlTransaction(
// TODO:fix SERVICE_NAME when we move it to initializeIndex // TODO:fix SERVICE_NAME when we move it to initializeIndex
@ -125,9 +122,6 @@ export function registerApmRuleTypes(
validate: () => ({ validate: () => ({
errors: [], errors: [],
}), }),
alertDetailsAppSection: lazy(
() => import('../ui_components/alert_details_app_section')
),
requiresAppContext: false, requiresAppContext: false,
defaultActionMessage: transactionErrorRateMessage, defaultActionMessage: transactionErrorRateMessage,
}); });
@ -157,9 +151,6 @@ export function registerApmRuleTypes(
validate: () => ({ validate: () => ({
errors: [], errors: [],
}), }),
alertDetailsAppSection: lazy(
() => import('../ui_components/alert_details_app_section')
),
requiresAppContext: false, requiresAppContext: false,
defaultActionMessage: anomalyMessage, defaultActionMessage: anomalyMessage,
}); });

View file

@ -194,9 +194,6 @@ describe('Transaction duration anomaly alert', () => {
); );
expect(scheduleActions).toHaveBeenCalledWith('threshold_met', { expect(scheduleActions).toHaveBeenCalledWith('threshold_met', {
alertDetailsUrl: expect.stringContaining(
'http://localhost:5601/eyr/app/observability/alerts/'
),
serviceName: 'foo', serviceName: 'foo',
transactionType: 'type-foo', transactionType: 'type-foo',
environment: 'development', environment: 'development',

View file

@ -8,7 +8,6 @@ import { QueryDslQueryContainer } from '@elastic/elasticsearch/lib/api/typesWith
import { KibanaRequest } from '@kbn/core/server'; import { KibanaRequest } from '@kbn/core/server';
import datemath from '@kbn/datemath'; import datemath from '@kbn/datemath';
import type { ESSearchResponse } from '@kbn/es-types'; import type { ESSearchResponse } from '@kbn/es-types';
import { getAlertDetailsUrl } from '@kbn/infra-plugin/server/lib/alerting/common/utils';
import { ProcessorEvent } from '@kbn/observability-plugin/common'; import { ProcessorEvent } from '@kbn/observability-plugin/common';
import { termQuery } from '@kbn/observability-plugin/server'; import { termQuery } from '@kbn/observability-plugin/server';
import { import {
@ -60,7 +59,6 @@ export function registerAnomalyRuleType({
config$, config$,
logger, logger,
ml, ml,
observability,
ruleDataClient, ruleDataClient,
}: RegisterRuleDependencies) { }: RegisterRuleDependencies) {
const createLifecycleRuleType = createLifecycleRuleTypeFactory({ const createLifecycleRuleType = createLifecycleRuleTypeFactory({
@ -77,9 +75,6 @@ export function registerAnomalyRuleType({
validate: { params: anomalyParamsSchema }, validate: { params: anomalyParamsSchema },
actionVariables: { actionVariables: {
context: [ context: [
...(observability.getAlertDetailsConfig()?.apm.enabled
? [apmActionVariables.alertDetailsUrl]
: []),
apmActionVariables.environment, apmActionVariables.environment,
apmActionVariables.reason, apmActionVariables.reason,
apmActionVariables.serviceName, apmActionVariables.serviceName,
@ -97,8 +92,7 @@ export function registerAnomalyRuleType({
return { state: {} }; return { state: {} };
} }
const { savedObjectsClient, scopedClusterClient, getAlertUuid } = const { savedObjectsClient, scopedClusterClient } = services;
services;
const ruleParams = params; const ruleParams = params;
const request = {} as KibanaRequest; const request = {} as KibanaRequest;
@ -288,14 +282,6 @@ export function registerAnomalyRuleType({
relativeViewInAppUrl relativeViewInAppUrl
); );
const alertUuid = getAlertUuid(id);
const alertDetailsUrl = getAlertDetailsUrl(
basePath,
spaceId,
alertUuid
);
services services
.alertWithLifecycle({ .alertWithLifecycle({
id, id,
@ -312,7 +298,6 @@ export function registerAnomalyRuleType({
}, },
}) })
.scheduleActions(ruleTypeConfig.defaultActionGroupId, { .scheduleActions(ruleTypeConfig.defaultActionGroupId, {
alertDetailsUrl,
environment: getEnvironmentLabel(environment), environment: getEnvironmentLabel(environment),
reason: reasonMessage, reason: reasonMessage,
serviceName, serviceName,

View file

@ -138,9 +138,6 @@ describe('Error count alert', () => {
expect(scheduleActions).toHaveBeenCalledTimes(3); expect(scheduleActions).toHaveBeenCalledTimes(3);
expect(scheduleActions).toHaveBeenCalledWith('threshold_met', { expect(scheduleActions).toHaveBeenCalledWith('threshold_met', {
alertDetailsUrl: expect.stringContaining(
'http://localhost:5601/eyr/app/observability/alerts/'
),
serviceName: 'foo', serviceName: 'foo',
environment: 'env-foo', environment: 'env-foo',
threshold: 2, threshold: 2,
@ -151,9 +148,6 @@ describe('Error count alert', () => {
'http://localhost:5601/eyr/app/apm/services/foo/errors?environment=env-foo', 'http://localhost:5601/eyr/app/apm/services/foo/errors?environment=env-foo',
}); });
expect(scheduleActions).toHaveBeenCalledWith('threshold_met', { expect(scheduleActions).toHaveBeenCalledWith('threshold_met', {
alertDetailsUrl: expect.stringContaining(
'http://localhost:5601/eyr/app/observability/alerts/'
),
serviceName: 'foo', serviceName: 'foo',
environment: 'env-foo-2', environment: 'env-foo-2',
threshold: 2, threshold: 2,
@ -164,9 +158,6 @@ describe('Error count alert', () => {
'http://localhost:5601/eyr/app/apm/services/foo/errors?environment=env-foo-2', 'http://localhost:5601/eyr/app/apm/services/foo/errors?environment=env-foo-2',
}); });
expect(scheduleActions).toHaveBeenCalledWith('threshold_met', { expect(scheduleActions).toHaveBeenCalledWith('threshold_met', {
alertDetailsUrl: expect.stringContaining(
'http://localhost:5601/eyr/app/observability/alerts/'
),
serviceName: 'bar', serviceName: 'bar',
environment: 'env-bar', environment: 'env-bar',
reason: 'Error count is 3 in the last 5 mins for bar. Alert when > 2.', reason: 'Error count is 3 in the last 5 mins for bar. Alert when > 2.',

View file

@ -5,19 +5,18 @@
* 2.0. * 2.0.
*/ */
import { getAlertDetailsUrl } from '@kbn/infra-plugin/server/lib/alerting/common/utils';
import { import {
formatDurationFromTimeUnitChar, formatDurationFromTimeUnitChar,
ProcessorEvent, ProcessorEvent,
TimeUnitChar, TimeUnitChar,
} from '@kbn/observability-plugin/common'; } from '@kbn/observability-plugin/common';
import { termQuery } from '@kbn/observability-plugin/server';
import { import {
ALERT_EVALUATION_THRESHOLD, ALERT_EVALUATION_THRESHOLD,
ALERT_EVALUATION_VALUE, ALERT_EVALUATION_VALUE,
ALERT_REASON, ALERT_REASON,
} from '@kbn/rule-data-utils'; } from '@kbn/rule-data-utils';
import { createLifecycleRuleTypeFactory } from '@kbn/rule-registry-plugin/server'; import { createLifecycleRuleTypeFactory } from '@kbn/rule-registry-plugin/server';
import { termQuery } from '@kbn/observability-plugin/server';
import { addSpaceIdToPath } from '@kbn/spaces-plugin/common'; import { addSpaceIdToPath } from '@kbn/spaces-plugin/common';
import { firstValueFrom } from 'rxjs'; import { firstValueFrom } from 'rxjs';
import { import {
@ -58,7 +57,6 @@ export function registerErrorCountRuleType({
basePath, basePath,
config$, config$,
logger, logger,
observability,
ruleDataClient, ruleDataClient,
}: RegisterRuleDependencies) { }: RegisterRuleDependencies) {
const createLifecycleRuleType = createLifecycleRuleTypeFactory({ const createLifecycleRuleType = createLifecycleRuleTypeFactory({
@ -75,9 +73,6 @@ export function registerErrorCountRuleType({
validate: { params: errorCountParamsSchema }, validate: { params: errorCountParamsSchema },
actionVariables: { actionVariables: {
context: [ context: [
...(observability.getAlertDetailsConfig()?.apm.enabled
? [apmActionVariables.alertDetailsUrl]
: []),
apmActionVariables.environment, apmActionVariables.environment,
apmActionVariables.interval, apmActionVariables.interval,
apmActionVariables.reason, apmActionVariables.reason,
@ -93,8 +88,7 @@ export function registerErrorCountRuleType({
executor: async ({ params: ruleParams, services, spaceId }) => { executor: async ({ params: ruleParams, services, spaceId }) => {
const config = await firstValueFrom(config$); const config = await firstValueFrom(config$);
const { getAlertUuid, savedObjectsClient, scopedClusterClient } = const { savedObjectsClient, scopedClusterClient } = services;
services;
const indices = await getApmIndices({ const indices = await getApmIndices({
config, config,
@ -187,13 +181,6 @@ export function registerErrorCountRuleType({
relativeViewInAppUrl relativeViewInAppUrl
); );
const alertUuid = getAlertUuid(id);
const alertDetailsUrl = getAlertDetailsUrl(
basePath,
spaceId,
alertUuid
);
services services
.alertWithLifecycle({ .alertWithLifecycle({
id, id,
@ -208,7 +195,6 @@ export function registerErrorCountRuleType({
}, },
}) })
.scheduleActions(ruleTypeConfig.defaultActionGroupId, { .scheduleActions(ruleTypeConfig.defaultActionGroupId, {
alertDetailsUrl,
environment: getEnvironmentLabel(environment), environment: getEnvironmentLabel(environment),
interval: formatDurationFromTimeUnitChar( interval: formatDurationFromTimeUnitChar(
ruleParams.windowSize, ruleParams.windowSize,

View file

@ -73,7 +73,6 @@ export function registerTransactionDurationRuleType({
ruleDataClient, ruleDataClient,
config$, config$,
logger, logger,
observability,
basePath, basePath,
}: RegisterRuleDependencies) { }: RegisterRuleDependencies) {
const createLifecycleRuleType = createLifecycleRuleTypeFactory({ const createLifecycleRuleType = createLifecycleRuleTypeFactory({
@ -89,9 +88,7 @@ export function registerTransactionDurationRuleType({
validate: { params: transactionDurationParamsSchema }, validate: { params: transactionDurationParamsSchema },
actionVariables: { actionVariables: {
context: [ context: [
...(observability.getAlertDetailsConfig()?.apm.enabled apmActionVariables.alertDetailsUrl,
? [apmActionVariables.alertDetailsUrl]
: []),
apmActionVariables.environment, apmActionVariables.environment,
apmActionVariables.interval, apmActionVariables.interval,
apmActionVariables.reason, apmActionVariables.reason,

View file

@ -121,9 +121,6 @@ describe('Transaction error rate alert', () => {
); );
expect(scheduleActions).toHaveBeenCalledWith('threshold_met', { expect(scheduleActions).toHaveBeenCalledWith('threshold_met', {
alertDetailsUrl: expect.stringContaining(
'http://localhost:5601/eyr/app/observability/alerts/'
),
serviceName: 'foo', serviceName: 'foo',
transactionType: 'type-foo', transactionType: 'type-foo',
environment: 'env-foo', environment: 'env-foo',

View file

@ -5,7 +5,6 @@
* 2.0. * 2.0.
*/ */
import { getAlertDetailsUrl } from '@kbn/infra-plugin/server/lib/alerting/common/utils';
import { import {
formatDurationFromTimeUnitChar, formatDurationFromTimeUnitChar,
ProcessorEvent, ProcessorEvent,
@ -67,7 +66,6 @@ export function registerTransactionErrorRateRuleType({
basePath, basePath,
config$, config$,
logger, logger,
observability,
ruleDataClient, ruleDataClient,
}: RegisterRuleDependencies) { }: RegisterRuleDependencies) {
const createLifecycleRuleType = createLifecycleRuleTypeFactory({ const createLifecycleRuleType = createLifecycleRuleTypeFactory({
@ -84,9 +82,6 @@ export function registerTransactionErrorRateRuleType({
validate: { params: transactionErrorRateParamsSchema }, validate: { params: transactionErrorRateParamsSchema },
actionVariables: { actionVariables: {
context: [ context: [
...(observability.getAlertDetailsConfig()?.apm.enabled
? [apmActionVariables.alertDetailsUrl]
: []),
apmActionVariables.environment, apmActionVariables.environment,
apmActionVariables.interval, apmActionVariables.interval,
apmActionVariables.reason, apmActionVariables.reason,
@ -103,8 +98,7 @@ export function registerTransactionErrorRateRuleType({
executor: async ({ services, spaceId, params: ruleParams }) => { executor: async ({ services, spaceId, params: ruleParams }) => {
const config = await firstValueFrom(config$); const config = await firstValueFrom(config$);
const { getAlertUuid, savedObjectsClient, scopedClusterClient } = const { savedObjectsClient, scopedClusterClient } = services;
services;
const indices = await getApmIndices({ const indices = await getApmIndices({
config, config,
@ -246,14 +240,6 @@ export function registerTransactionErrorRateRuleType({
.filter((name) => name) .filter((name) => name)
.join('_'); .join('_');
const alertUuid = getAlertUuid(id);
const alertDetailsUrl = getAlertDetailsUrl(
basePath,
spaceId,
alertUuid
);
const relativeViewInAppUrl = getAlertUrlTransaction( const relativeViewInAppUrl = getAlertUrlTransaction(
serviceName, serviceName,
getEnvironmentEsField(environment)?.[SERVICE_ENVIRONMENT], getEnvironmentEsField(environment)?.[SERVICE_ENVIRONMENT],
@ -281,7 +267,6 @@ export function registerTransactionErrorRateRuleType({
}, },
}) })
.scheduleActions(ruleTypeConfig.defaultActionGroupId, { .scheduleActions(ruleTypeConfig.defaultActionGroupId, {
alertDetailsUrl,
environment: getEnvironmentLabel(environment), environment: getEnvironmentLabel(environment),
interval: formatDurationFromTimeUnitChar( interval: formatDurationFromTimeUnitChar(
ruleParams.windowSize, ruleParams.windowSize,

View file

@ -69,7 +69,6 @@ describe('renderApp', () => {
const config = { const config = {
unsafe: { unsafe: {
alertDetails: { alertDetails: {
apm: { enabled: false },
logs: { enabled: false }, logs: { enabled: false },
metrics: { enabled: false }, metrics: { enabled: false },
uptime: { enabled: false }, uptime: { enabled: false },

View file

@ -48,7 +48,6 @@ describe('APMSection', () => {
const config = { const config = {
unsafe: { unsafe: {
alertDetails: { alertDetails: {
apm: { enabled: false },
logs: { enabled: false }, logs: { enabled: false },
metrics: { enabled: false }, metrics: { enabled: false },
uptime: { enabled: false }, uptime: { enabled: false },

View file

@ -98,7 +98,6 @@ const params = {
const config: Subset<ConfigSchema> = { const config: Subset<ConfigSchema> = {
unsafe: { unsafe: {
alertDetails: { alertDetails: {
apm: { enabled: true },
logs: { enabled: true }, logs: { enabled: true },
metrics: { enabled: true }, metrics: { enabled: true },
uptime: { enabled: true }, uptime: { enabled: true },

View file

@ -32,7 +32,6 @@ jest.mock('../../../hooks/use_get_user_cases_permissions', () => ({
const config = { const config = {
unsafe: { unsafe: {
alertDetails: { alertDetails: {
apm: { enabled: false },
logs: { enabled: false }, logs: { enabled: false },
metrics: { enabled: false }, metrics: { enabled: false },
uptime: { enabled: false }, uptime: { enabled: false },

View file

@ -78,7 +78,6 @@ const withCore = makeDecorator({
const config: ConfigSchema = { const config: ConfigSchema = {
unsafe: { unsafe: {
alertDetails: { alertDetails: {
apm: { enabled: false },
logs: { enabled: false }, logs: { enabled: false },
metrics: { enabled: false }, metrics: { enabled: false },
uptime: { enabled: false }, uptime: { enabled: false },

View file

@ -63,9 +63,6 @@ import { registerObservabilityRuleTypes } from './rules/register_observability_r
export interface ConfigSchema { export interface ConfigSchema {
unsafe: { unsafe: {
alertDetails: { alertDetails: {
apm: {
enabled: boolean;
};
metrics: { metrics: {
enabled: boolean; enabled: boolean;
}; };

View file

@ -31,7 +31,6 @@ import type { TopAlert } from '../typings/alerts';
const defaultConfig = { const defaultConfig = {
unsafe: { unsafe: {
alertDetails: { alertDetails: {
apm: { enabled: false },
logs: { enabled: false }, logs: { enabled: false },
metrics: { enabled: false }, metrics: { enabled: false },
uptime: { enabled: false }, uptime: { enabled: false },
@ -72,7 +71,6 @@ describe('isAlertDetailsEnabled', () => {
const updatedConfig = { const updatedConfig = {
unsafe: { unsafe: {
alertDetails: { alertDetails: {
apm: { enabled: false },
logs: { enabled: true }, logs: { enabled: true },
metrics: { enabled: false }, metrics: { enabled: false },
uptime: { enabled: false }, uptime: { enabled: false },
@ -107,22 +105,25 @@ describe('isAlertDetailsEnabled', () => {
start: 1630587249674, start: 1630587249674,
lastUpdated: 1630588131750, lastUpdated: 1630588131750,
} as unknown as TopAlert; } as unknown as TopAlert;
it('returns FALSE when apm: { enabled: false }', () => { it('returns FALSE when the rule type IS NOT apm.transaction_duration', () => {
expect(isAlertDetailsEnabledPerApp(APMAlert, defaultConfig)).toBeFalsy(); expect(isAlertDetailsEnabledPerApp(APMAlert, defaultConfig)).toBeFalsy();
}); });
it('returns TRUE when apm: { enabled: true }', () => { it('returns TRUE when rule type is apm.transaction_duration', () => {
const updatedConfig = { const updatedConfig = {
unsafe: { unsafe: {
alertDetails: { alertDetails: {
apm: { enabled: true },
logs: { enabled: false }, logs: { enabled: false },
metrics: { enabled: false }, metrics: { enabled: false },
uptime: { enabled: false }, uptime: { enabled: false },
}, },
}, },
} as ConfigSchema; } as ConfigSchema;
expect(isAlertDetailsEnabledPerApp(APMAlert, updatedConfig)).toBeTruthy(); const apmTransactionDurationAlert = {
...APMAlert,
fields: { ...APMAlert.fields, [ALERT_RULE_TYPE_ID]: 'apm.transaction_duration' },
};
expect(isAlertDetailsEnabledPerApp(apmTransactionDurationAlert, updatedConfig)).toBeTruthy();
}); });
}); });
describe('Metrics alert', () => { describe('Metrics alert', () => {
@ -158,7 +159,6 @@ describe('isAlertDetailsEnabled', () => {
const updatedConfig = { const updatedConfig = {
unsafe: { unsafe: {
alertDetails: { alertDetails: {
apm: { enabled: false },
logs: { enabled: false }, logs: { enabled: false },
metrics: { enabled: true }, metrics: { enabled: true },
uptime: { enabled: false }, uptime: { enabled: false },
@ -201,7 +201,6 @@ describe('isAlertDetailsEnabled', () => {
const updatedConfig = { const updatedConfig = {
unsafe: { unsafe: {
alertDetails: { alertDetails: {
apm: { enabled: false },
logs: { enabled: false }, logs: { enabled: false },
metrics: { enabled: false }, metrics: { enabled: false },
uptime: { enabled: true }, uptime: { enabled: true },
@ -244,7 +243,6 @@ describe('isAlertDetailsEnabled', () => {
const updatedConfig = { const updatedConfig = {
unsafe: { unsafe: {
alertDetails: { alertDetails: {
apm: { enabled: true },
logs: { enabled: true }, logs: { enabled: true },
metrics: { enabled: true }, metrics: { enabled: true },
uptime: { enabled: true }, uptime: { enabled: true },
@ -257,7 +255,6 @@ describe('isAlertDetailsEnabled', () => {
const updatedConfig = { const updatedConfig = {
unsafe: { unsafe: {
alertDetails: { alertDetails: {
apm: { enabled: true },
logs: { enabled: true }, logs: { enabled: true },
metrics: { enabled: true }, metrics: { enabled: true },
uptime: { enabled: true }, uptime: { enabled: true },

View file

@ -9,21 +9,39 @@ import { ALERT_RULE_TYPE_ID } from '@kbn/rule-data-utils';
import type { ConfigSchema } from '../plugin'; import type { ConfigSchema } from '../plugin';
import type { TopAlert } from '../typings/alerts'; import type { TopAlert } from '../typings/alerts';
const ALLOWED_RULE_TYPES = ['apm.transaction_duration'];
const isUnsafeAlertDetailsFlag = (
subject: string
): subject is keyof ConfigSchema['unsafe']['alertDetails'] =>
['uptime', 'logs', 'metrics'].includes(subject);
// We are mapping the ruleTypeId from the feature flag with the ruleTypeId from the alert // We are mapping the ruleTypeId from the feature flag with the ruleTypeId from the alert
// to know whether the feature flag is enabled or not. // to know whether the feature flag is enabled or not.
export const isAlertDetailsEnabledPerApp = ( export const isAlertDetailsEnabledPerApp = (
alert: TopAlert | null, alert: TopAlert | null,
config: ConfigSchema | null config: ConfigSchema | null
): boolean => { ): boolean => {
if (!alert || !config) return false; if (!alert) return false;
const ruleTypeId = alert.fields[ALERT_RULE_TYPE_ID]; const ruleTypeId = alert.fields[ALERT_RULE_TYPE_ID];
// The feature flags for alertDetails are not specific enough so we need to check
// the specific rule types to see if they should be blocked or not.
if (ALLOWED_RULE_TYPES.includes(ruleTypeId)) {
return true;
}
if (!config) return false;
// Since we are moving away from feature flags, this code will eventually be removed.
const appNameFromAlertRuleType = const appNameFromAlertRuleType =
ruleTypeId === 'xpack.uptime.alerts.monitorStatus' || ruleTypeId === 'xpack.uptime.alerts.monitorStatus' ||
ruleTypeId === 'xpack.uptime.alerts.tlsCertificate' ruleTypeId === 'xpack.uptime.alerts.tlsCertificate'
? 'uptime' ? 'uptime'
: (ruleTypeId.split('.')[0] as keyof ConfigSchema['unsafe']['alertDetails']); : ruleTypeId.split('.')[0];
if (isUnsafeAlertDetailsFlag(appNameFromAlertRuleType)) {
return config.unsafe?.alertDetails[appNameFromAlertRuleType]?.enabled; return config.unsafe?.alertDetails[appNameFromAlertRuleType]?.enabled;
}
return false;
}; };

View file

@ -25,7 +25,6 @@ export function KibanaReactStorybookDecorator(Story: ComponentType) {
const config: ConfigSchema = { const config: ConfigSchema = {
unsafe: { unsafe: {
alertDetails: { alertDetails: {
apm: { enabled: false },
logs: { enabled: false }, logs: { enabled: false },
metrics: { enabled: false }, metrics: { enabled: false },
uptime: { enabled: false }, uptime: { enabled: false },

View file

@ -32,7 +32,6 @@ export const data = dataPluginMock.createStartContract();
const defaultConfig: ConfigSchema = { const defaultConfig: ConfigSchema = {
unsafe: { unsafe: {
alertDetails: { alertDetails: {
apm: { enabled: false },
logs: { enabled: false }, logs: { enabled: false },
metrics: { enabled: false }, metrics: { enabled: false },
uptime: { enabled: false }, uptime: { enabled: false },

View file

@ -30,9 +30,6 @@ const configSchema = schema.object({
}), }),
unsafe: schema.object({ unsafe: schema.object({
alertDetails: schema.object({ alertDetails: schema.object({
apm: schema.object({
enabled: schema.boolean({ defaultValue: false }),
}),
metrics: schema.object({ metrics: schema.object({
enabled: schema.boolean({ defaultValue: false }), enabled: schema.boolean({ defaultValue: false }),
}), }),