Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .buildkite/ftr_platform_stateful_configs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ enabled:
- x-pack/platform/test/alerting_api_integration/spaces_only/tests/alerting/group2/config.ts
- x-pack/platform/test/alerting_api_integration/spaces_only/tests/alerting/group3/config.ts
- x-pack/platform/test/alerting_api_integration/spaces_only/tests/alerting/group4/config.ts
- x-pack/platform/test/alerting_api_integration/spaces_only/tests/alerting/group4/config_with_schedule_circuit_breaker.ts
- x-pack/platform/test/alerting_api_integration/spaces_only/tests/actions/config.ts
- x-pack/platform/test/alerting_api_integration/spaces_only/tests/action_task_params/config.ts
- x-pack/test/api_integration_basic/config.ts
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -460,7 +460,6 @@ describe('Legacy Alerts Client', () => {
alertsClient.determineFlappingAlerts();

expect(determineFlappingAlerts).toHaveBeenCalledWith({
logger,
newAlerts: {},
activeAlerts: {},
recoveredAlerts: {},
Expand All @@ -471,7 +470,6 @@ describe('Legacy Alerts Client', () => {
},
previouslyRecoveredAlerts: {},
actionGroupId: 'default',
maxAlerts: 1000,
});

expect(alertsClient.getProcessedAlerts('active')).toEqual({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,8 @@ export class LegacyAlertsClient<

public getRawAlertInstancesForState(shouldOptimizeTaskState?: boolean) {
return toRawAlertInstances<State, Context, ActionGroupIds, RecoveryActionGroupId>(
this.options.logger,
this.maxAlerts,
this.processedAlerts.trackedActiveAlerts,
this.processedAlerts.trackedRecoveredAlerts,
shouldOptimizeTaskState
Expand All @@ -225,14 +227,12 @@ export class LegacyAlertsClient<
public determineFlappingAlerts() {
if (this.flappingSettings.enabled) {
const alerts = determineFlappingAlerts({
logger: this.options.logger,
newAlerts: this.processedAlerts.new,
activeAlerts: this.processedAlerts.active,
recoveredAlerts: this.processedAlerts.recovered,
flappingSettings: this.flappingSettings,
previouslyRecoveredAlerts: this.trackedAlerts.recovered,
actionGroupId: this.options.ruleType.defaultActionGroupId,
maxAlerts: this.maxAlerts,
});

this.processedAlerts.new = alerts.newAlerts;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,21 @@
* 2.0.
*/

import { loggingSystemMock } from '@kbn/core-logging-server-mocks';
import { DEFAULT_FLAPPING_SETTINGS } from '../../../common/rules_settings';
import { Alert } from '../../alert';
import { alertsWithAnyUUID } from '../../test_utils';
import {
delayRecoveredFlappingAlerts,
getEarlyRecoveredAlertIds,
} from './delay_recovered_flapping_alerts';
import { delayRecoveredFlappingAlerts } from './delay_recovered_flapping_alerts';

describe('delayRecoveredFlappingAlerts', () => {
const logger = loggingSystemMock.createLogger();

test('should set pendingRecoveredCount to zero for all active alerts', () => {
const alert1 = new Alert('1', {
meta: { flapping: true, pendingRecoveredCount: 3, uuid: 'uuid-1' },
});
const alert2 = new Alert('2', { meta: { flapping: false, uuid: 'uuid-2' } });

const { newAlerts, activeAlerts, trackedActiveAlerts } = delayRecoveredFlappingAlerts(
logger,
DEFAULT_FLAPPING_SETTINGS,
'default',
1000,
{
// new alerts
'1': alert1,
Expand Down Expand Up @@ -121,10 +113,8 @@ describe('delayRecoveredFlappingAlerts', () => {
recoveredAlerts,
trackedRecoveredAlerts,
} = delayRecoveredFlappingAlerts(
logger,
DEFAULT_FLAPPING_SETTINGS,
'default',
1000,
{}, // new alerts
{}, // active alerts
{}, // tracked active alerts
Expand Down Expand Up @@ -238,95 +228,4 @@ describe('delayRecoveredFlappingAlerts', () => {
}
`);
});

describe('getEarlyRecoveredAlertIds', () => {
const alert1 = new Alert('1', { meta: { flappingHistory: [true, true, true, true] } });
const alert2 = new Alert('2', { meta: { flappingHistory: new Array(20).fill(false) } });
const alert3 = new Alert('3', { meta: { flappingHistory: [true, true] } });

test('should remove longest recovered alerts', () => {
const { recoveredAlerts, trackedRecoveredAlerts } = delayRecoveredFlappingAlerts(
logger,
DEFAULT_FLAPPING_SETTINGS,
'default',
2,
{}, // new alerts
{}, // active alerts
{}, // tracked active alerts
{
// recovered alerts
'1': alert1,
'2': alert2,
'3': alert3,
},
{
// tracked recovered alerts
'1': alert1,
'2': alert2,
'3': alert3,
}
);
expect(Object.keys(recoveredAlerts).length).toBe(3);
expect(recoveredAlerts['2'].getFlapping()).toBe(false);
expect(Object.keys(trackedRecoveredAlerts).length).toBe(2);
});

test('should not remove alerts if the num of recovered alerts is not at the limit', () => {
const { recoveredAlerts, trackedRecoveredAlerts } = delayRecoveredFlappingAlerts(
logger,
DEFAULT_FLAPPING_SETTINGS,
'default',
3,
{}, // new alerts
{}, // active alerts
{}, // tracked active alerts
{
// recovered alerts
'1': alert1,
'2': alert2,
'3': alert3,
},
{
// tracked recovered alerts
'1': alert1,
'2': alert2,
'3': alert3,
}
);
expect(Object.keys(recoveredAlerts).length).toBe(3);
expect(recoveredAlerts['2'].getFlapping()).toBe(false);
expect(Object.keys(trackedRecoveredAlerts).length).toBe(3);
});

test('getEarlyRecoveredAlertIds should return longest recovered alerts', () => {
const alertIds = getEarlyRecoveredAlertIds(
logger,
{
// tracked recovered alerts
'1': alert1,
'2': alert2,
'3': alert3,
},
2
);
expect(alertIds).toEqual(['2']);

expect(logger.warn).toBeCalledWith(
'Recovered alerts have exceeded the max alert limit of 2 : dropping 1 alert.'
);
});

test('getEarlyRecoveredAlertIds should not return alerts if the num of recovered alerts is not at the limit', () => {
const trimmedAlerts = getEarlyRecoveredAlertIds(
logger,
{
// tracked recovered alerts
'1': alert1,
'2': alert2,
},
2
);
expect(trimmedAlerts).toEqual([]);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@
* 2.0.
*/

import { keys, map } from 'lodash';
import type { Logger } from '@kbn/logging';
import { keys } from 'lodash';
import type { RulesSettingsFlappingProperties } from '../../../common/rules_settings';
import { Alert } from '../../alert';
import type { AlertInstanceState, AlertInstanceContext } from '../../types';
Expand All @@ -17,10 +16,8 @@ export function delayRecoveredFlappingAlerts<
ActionGroupIds extends string,
RecoveryActionGroupId extends string
>(
logger: Logger,
flappingSettings: RulesSettingsFlappingProperties,
actionGroupId: string,
maxAlerts: number,
newAlerts: Record<string, Alert<State, Context, ActionGroupIds>> = {},
activeAlerts: Record<string, Alert<State, Context, ActionGroupIds>> = {},
trackedActiveAlerts: Record<string, Alert<State, Context, ActionGroupIds>> = {},
Expand Down Expand Up @@ -66,19 +63,6 @@ export function delayRecoveredFlappingAlerts<
}
}

const earlyRecoveredAlertIds = getEarlyRecoveredAlertIds(
logger,
trackedRecoveredAlerts,
maxAlerts
);
for (const id of earlyRecoveredAlertIds) {
const alert = trackedRecoveredAlerts[id];
alert.setFlapping(false);
recoveredAlerts[id] = alert;

delete trackedRecoveredAlerts[id];
}

return {
newAlerts,
activeAlerts,
Expand All @@ -87,35 +71,3 @@ export function delayRecoveredFlappingAlerts<
trackedRecoveredAlerts,
};
}

export function getEarlyRecoveredAlertIds<
State extends AlertInstanceState,
Context extends AlertInstanceContext,
RecoveryActionGroupId extends string
>(
logger: Logger,
trackedRecoveredAlerts: Record<string, Alert<State, Context, RecoveryActionGroupId>>,
maxAlerts: number
) {
const alerts = map(trackedRecoveredAlerts, (alert, id) => {
return {
id,
flappingHistory: alert.getFlappingHistory() || [],
};
});

let earlyRecoveredAlertIds: string[] = [];
if (alerts.length > maxAlerts) {
alerts.sort((a, b) => {
return a.flappingHistory.length - b.flappingHistory.length;
});

earlyRecoveredAlertIds = alerts.slice(maxAlerts).map((alert) => alert.id);
logger.warn(
`Recovered alerts have exceeded the max alert limit of ${maxAlerts} : dropping ${
earlyRecoveredAlertIds.length
} ${earlyRecoveredAlertIds.length > 1 ? 'alerts' : 'alert'}.`
);
}
return earlyRecoveredAlertIds;
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
* 2.0.
*/

import type { Logger } from '@kbn/logging';
import type { Alert } from '../../alert';
import type { AlertInstanceState, AlertInstanceContext } from '../../types';
import type { RulesSettingsFlappingProperties } from '../../../common/rules_settings';
Expand All @@ -19,14 +18,12 @@ interface DetermineFlappingAlertsOpts<
ActionGroupIds extends string,
RecoveryActionGroupId extends string
> {
logger: Logger;
newAlerts: Record<string, Alert<State, Context, ActionGroupIds>>;
activeAlerts: Record<string, Alert<State, Context, ActionGroupIds>>;
recoveredAlerts: Record<string, Alert<State, Context, RecoveryActionGroupId>>;
flappingSettings: RulesSettingsFlappingProperties;
previouslyRecoveredAlerts: Record<string, Alert<State, Context>>;
actionGroupId: string;
maxAlerts: number;
}

export function determineFlappingAlerts<
Expand All @@ -35,14 +32,12 @@ export function determineFlappingAlerts<
ActionGroupIds extends string,
RecoveryActionGroupId extends string
>({
logger,
newAlerts,
activeAlerts,
recoveredAlerts,
flappingSettings,
previouslyRecoveredAlerts,
actionGroupId,
maxAlerts,
}: DetermineFlappingAlertsOpts<State, Context, ActionGroupIds, RecoveryActionGroupId>) {
setFlapping<State, Context, ActionGroupIds, RecoveryActionGroupId>(
flappingSettings,
Expand All @@ -58,10 +53,8 @@ export function determineFlappingAlerts<
>(flappingSettings, newAlerts, activeAlerts, recoveredAlerts, previouslyRecoveredAlerts);

alerts = delayRecoveredFlappingAlerts<State, Context, ActionGroupIds, RecoveryActionGroupId>(
logger,
flappingSettings,
actionGroupId,
maxAlerts,
alerts.newAlerts,
alerts.activeAlerts,
alerts.trackedActiveAlerts,
Expand Down
Loading