[Metric threshold] Deprecate unsafe.alertDetails.metrics.enabled feature flag (#186623)

Fixes #183489

It also removes the technical preview badge from the metric threshold
alert details page.

Having this feature flag now gives you the following warning and even
changing it to false will not have any impact:
```
[2024-06-21T17:09:01.688+02:00][WARN ][config.deprecation] You no longer need to configure "xpack.observability.unsafe.alertDetails.metrics.enabled".
```
This commit is contained in:
Maryam Saeidi 2024-06-24 13:56:43 +02:00 committed by GitHub
parent ecda2a8fc1
commit 626f2b171c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 26 additions and 67 deletions

View file

@ -8,12 +8,6 @@ from files dual-licensed under the Server Side Public License and the Elastic Li
If you have:
```yaml
xpack.observability.unsafe.alertDetails.metrics.enabled: true
```
**[For Infrastructure 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
xpack.observability.unsafe.alertDetails.uptime.enabled: true
```

View file

@ -74,14 +74,13 @@ describe('renderApp', () => {
theme$: themeServiceMock.createTheme$(),
} as unknown as AppMountParameters;
const config = {
const config: ConfigSchema = {
unsafe: {
alertDetails: {
metrics: { enabled: false },
uptime: { enabled: false },
},
},
} as ConfigSchema;
};
it('renders', async () => {
expect(() => {

View file

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

View file

@ -23,16 +23,11 @@ import {
ALERT_DURATION,
ALERT_FLAPPING,
ALERT_RULE_CATEGORY,
ALERT_RULE_TYPE_ID,
TIMESTAMP,
} from '@kbn/rule-data-utils';
import { css } from '@emotion/react';
import { asDuration } from '../../../../common/utils/formatters';
import { TopAlert } from '../../../typings/alerts';
import { ExperimentalBadge } from '../../../components/experimental_badge';
import { METRIC_THRESHOLD_ALERT_TYPE_ID } from '../alert_details';
import { isAlertDetailsEnabledPerApp } from '../../../utils/is_alert_details_enabled';
import { usePluginContext } from '../../../hooks/use_plugin_context';
export interface PageTitleProps {
alert: TopAlert | null;
@ -52,19 +47,13 @@ export function pageTitleContent(ruleCategory: string) {
export function PageTitle({ alert, alertStatus, dataTestSubj }: PageTitleProps) {
const { euiTheme } = useEuiTheme();
const { config } = usePluginContext();
if (!alert) return <EuiLoadingSpinner />;
const showExperimentalBadge = alert.fields[ALERT_RULE_TYPE_ID] === METRIC_THRESHOLD_ALERT_TYPE_ID;
return (
<div data-test-subj={dataTestSubj}>
<EuiFlexGroup direction="row" alignItems="center" gutterSize="s">
{pageTitleContent(alert.fields[ALERT_RULE_CATEGORY])}
{isAlertDetailsEnabledPerApp(alert, config) && showExperimentalBadge && (
<ExperimentalBadge />
)}
</EuiFlexGroup>
<EuiSpacer size="l" />
<EuiFlexGroup direction="row" alignItems="center" gutterSize="xl">

View file

@ -68,7 +68,6 @@ jest.spyOn(pluginContext, 'usePluginContext').mockImplementation(() => ({
unsafe: {
alertDetails: {
apm: { enabled: false },
metrics: { enabled: false },
uptime: { enabled: false },
},
},

View file

@ -63,14 +63,13 @@ jest.mock('@kbn/triggers-actions-ui-plugin/public/common/lib/kibana/kibana_react
})),
}));
const config = {
const config: ConfigSchema = {
unsafe: {
alertDetails: {
metrics: { enabled: false },
uptime: { enabled: false },
},
},
} as ConfigSchema;
};
const getFormatterMock = jest.fn();
const createRuleTypeRegistryMock = () => ({

View file

@ -49,14 +49,13 @@ describe('APMSection', () => {
from: '2020-10-08T06:00:00.000Z',
to: '2020-10-08T07:00:00.000Z',
});
const config = {
const config: ConfigSchema = {
unsafe: {
alertDetails: {
metrics: { enabled: false },
uptime: { enabled: false },
},
},
} as ConfigSchema;
};
jest.spyOn(pluginContext, 'usePluginContext').mockImplementation(() => ({
appMountParameters: {} as AppMountParameters,

View file

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

View file

@ -58,7 +58,6 @@ jest.spyOn(pluginContext, 'usePluginContext').mockImplementation(() => ({
unsafe: {
alertDetails: {
apm: { enabled: false },
metrics: { enabled: false },
uptime: { enabled: false },
observability: { enabled: false },
},

View file

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

View file

@ -28,14 +28,13 @@ import { ConfigSchema } from '../plugin';
import { isAlertDetailsEnabledPerApp } from './is_alert_details_enabled';
import type { TopAlert } from '../typings/alerts';
const defaultConfig = {
const defaultConfig: ConfigSchema = {
unsafe: {
alertDetails: {
metrics: { enabled: false },
uptime: { enabled: false },
},
},
} as ConfigSchema;
};
describe('isAlertDetailsEnabled', () => {
describe('Logs alert', () => {
const logsAlert = {
@ -63,14 +62,13 @@ describe('isAlertDetailsEnabled', () => {
lastUpdated: 1630588131750,
} as unknown as TopAlert;
it('returns TRUE when rule type is logs.alert.document.count', () => {
const updatedConfig = {
const updatedConfig: ConfigSchema = {
unsafe: {
alertDetails: {
metrics: { enabled: false },
uptime: { enabled: false },
},
},
} as ConfigSchema;
};
expect(isAlertDetailsEnabledPerApp(logsAlert, updatedConfig)).toBeTruthy();
});
});
@ -104,14 +102,13 @@ describe('isAlertDetailsEnabled', () => {
});
it('returns TRUE when rule type is apm.transaction_duration', () => {
const updatedConfig = {
const updatedConfig: ConfigSchema = {
unsafe: {
alertDetails: {
metrics: { enabled: false },
uptime: { enabled: false },
},
},
} as ConfigSchema;
};
const apmTransactionDurationAlert = {
...APMAlert,
fields: { ...APMAlert.fields, [ALERT_RULE_TYPE_ID]: 'apm.transaction_duration' },
@ -129,7 +126,7 @@ describe('isAlertDetailsEnabled', () => {
[ALERT_WORKFLOW_STATUS]: 'open',
[ALERT_RULE_UUID]: 'db2ab7c0-0bec-11ec-9ae2-5b10ca924404',
[ALERT_START]: '2021-09-02T12:54:09.674Z',
[ALERT_RULE_TYPE_ID]: 'metrics.alert.inventory.threshold',
[ALERT_RULE_TYPE_ID]: 'metrics.alert.threshold',
[EVENT_ACTION]: 'active',
[ALERT_EVALUATION_VALUE]: 1957,
[ALERT_INSTANCE_ID]: '*',
@ -144,20 +141,8 @@ describe('isAlertDetailsEnabled', () => {
start: 1630587249674,
lastUpdated: 1630588131750,
} as unknown as TopAlert;
it('returns FALSE when metrics: { enabled: false }', () => {
expect(isAlertDetailsEnabledPerApp(metricsAlert, defaultConfig)).toBeFalsy();
});
it('returns TRUE when metrics: { enabled: true }', () => {
const updatedConfig = {
unsafe: {
alertDetails: {
metrics: { enabled: true },
uptime: { enabled: false },
},
},
} as ConfigSchema;
expect(isAlertDetailsEnabledPerApp(metricsAlert, updatedConfig)).toBeTruthy();
it('returns TRUE when rule type is metrics.alert.threshold', () => {
expect(isAlertDetailsEnabledPerApp(metricsAlert, defaultConfig)).toBeTruthy();
});
});
describe('Uptime alert', () => {
@ -231,25 +216,23 @@ describe('isAlertDetailsEnabled', () => {
});
it('returns FALSE when no alert provided', () => {
const updatedConfig = {
const updatedConfig: ConfigSchema = {
unsafe: {
alertDetails: {
metrics: { enabled: true },
uptime: { enabled: true },
},
},
} as ConfigSchema;
};
expect(isAlertDetailsEnabledPerApp(null, updatedConfig)).toBeFalsy();
});
it('returns FALSE when a none-listed rule type is checked', () => {
const updatedConfig = {
const updatedConfig: ConfigSchema = {
unsafe: {
alertDetails: {
metrics: { enabled: true },
uptime: { enabled: true },
},
},
} as ConfigSchema;
};
const noneListedRuleType = {
reason: 'reason message',
fields: {

View file

@ -9,6 +9,7 @@ import { ALERT_RULE_TYPE_ID } from '@kbn/rule-data-utils';
import {
ApmRuleType,
LOG_THRESHOLD_ALERT_TYPE_ID,
METRIC_THRESHOLD_ALERT_TYPE_ID,
OBSERVABILITY_THRESHOLD_RULE_TYPE_ID,
SLO_BURN_RATE_RULE_TYPE_ID,
} from '@kbn/rule-data-utils';
@ -18,14 +19,17 @@ import type { TopAlert } from '../typings/alerts';
const ALLOWED_RULE_TYPES = [
ApmRuleType.TransactionDuration,
LOG_THRESHOLD_ALERT_TYPE_ID,
METRIC_THRESHOLD_ALERT_TYPE_ID,
OBSERVABILITY_THRESHOLD_RULE_TYPE_ID,
SLO_BURN_RATE_RULE_TYPE_ID,
];
const isUnsafeAlertDetailsFlag = (
subject: string
): subject is keyof Omit<ConfigSchema['unsafe']['alertDetails'], 'logs' | 'observability'> =>
['uptime', 'metrics'].includes(subject);
): subject is keyof Omit<
ConfigSchema['unsafe']['alertDetails'],
'logs' | 'observability' | 'metrics'
> => ['uptime'].includes(subject);
// 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.

View file

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

View file

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

View file

@ -84,6 +84,7 @@ export const config: PluginConfigDescriptor = {
deprecations: ({ unused }) => [
unused('unsafe.thresholdRule.enabled', { level: 'warning' }),
unused('unsafe.alertDetails.logs.enabled', { level: 'warning' }),
unused('unsafe.alertDetails.metrics.enabled', { level: 'warning' }),
unused('unsafe.alertDetails.observability.enabled', { level: 'warning' }),
],
};