[ResponseOps] Adding back recovered alert optimization for the task state (#215344)

## Summary

I refactored the flapping code on ON week in PR
https://github.com/elastic/kibana/pull/213825 , and I removed an
optimization for removing recovered alerts from the task state that we
don't need to track for flapping. This PR adds it back.


### Checklist

- [ ] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios

### To verify
1. Create an rule let it be active for a little and then let it recover.
2. Verify that once the flapping array doesn't have any `true` values
changes
This commit is contained in:
Alexi Doak 2025-03-21 17:21:16 -07:00 committed by GitHub
parent f5424e0c51
commit 1dd1ec5870
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 32 additions and 8 deletions

View file

@ -345,8 +345,8 @@ export class AlertsClient<
return await this.updatePersistedAlertsWithMaintenanceWindowIds();
}
public getRawAlertInstancesForState() {
return this.legacyAlertsClient.getRawAlertInstancesForState();
public getRawAlertInstancesForState(shouldOptimizeTaskState?: boolean) {
return this.legacyAlertsClient.getRawAlertInstancesForState(shouldOptimizeTaskState);
}
public factory() {

View file

@ -211,10 +211,11 @@ export class LegacyAlertsClient<
return {};
}
public getRawAlertInstancesForState() {
public getRawAlertInstancesForState(shouldOptimizeTaskState?: boolean) {
return toRawAlertInstances<State, Context, ActionGroupIds, RecoveryActionGroupId>(
this.processedAlerts.trackedActiveAlerts,
this.processedAlerts.trackedRecoveredAlerts
this.processedAlerts.trackedRecoveredAlerts,
shouldOptimizeTaskState
);
}

View file

@ -85,7 +85,7 @@ export interface IAlertsClient<
persistAlerts(): Promise<{ alertIds: string[]; maintenanceWindowIds: string[] } | null>;
isTrackedAlert(id: string): boolean;
getSummarizedAlerts?(params: GetSummarizedAlertsParams): Promise<SummarizedAlerts>;
getRawAlertInstancesForState(): {
getRawAlertInstancesForState(shouldOptimizeTaskState?: boolean): {
rawActiveAlerts: Record<string, RawAlertInstance>;
rawRecoveredAlerts: Record<string, RawAlertInstance>;
};

View file

@ -31,5 +31,14 @@ describe('toRawAlertInstances', () => {
const { rawRecoveredAlerts } = toRawAlertInstances({}, recoveredAlerts);
expect(keys(rawRecoveredAlerts)).toEqual(['1', '2']);
});
test('should return all flapping recovered alerts', () => {
const recoveredAlerts = {
'1': new Alert('1', { meta: { flappingHistory: flapping } }),
'2': new Alert('2', { meta: { flappingHistory: notFlapping } }),
};
const { rawRecoveredAlerts } = toRawAlertInstances({}, recoveredAlerts, true);
expect(keys(rawRecoveredAlerts)).toEqual(['1']);
});
});
});

View file

@ -16,7 +16,8 @@ export function toRawAlertInstances<
RecoveryActionGroupId extends string
>(
activeAlerts: Record<string, Alert<State, Context, ActionGroupIds>> = {},
recoveredAlerts: Record<string, Alert<State, Context, RecoveryActionGroupId>> = {}
recoveredAlerts: Record<string, Alert<State, Context, RecoveryActionGroupId>> = {},
shouldOptimizeTaskState: boolean = false
): {
rawActiveAlerts: Record<string, RawAlertInstance>;
rawRecoveredAlerts: Record<string, RawAlertInstance>;
@ -30,7 +31,20 @@ export function toRawAlertInstances<
for (const id of keys(recoveredAlerts)) {
const alert = recoveredAlerts[id];
rawRecoveredAlerts[id] = alert.toRaw(true);
if (shouldOptimizeTaskState) {
// this is a space saving effort that will only return recovered alerts if they are flapping
// or if the flapping array contains any state changes
const flapping = alert.getFlapping();
const flappingHistory: boolean[] = alert.getFlappingHistory() || [];
const numStateChanges = flappingHistory.filter((f) => f).length;
if (flapping) {
rawRecoveredAlerts[id] = alert.toRaw(true);
} else if (numStateChanges > 0) {
rawRecoveredAlerts[id] = alert.toRaw(true);
}
} else {
rawRecoveredAlerts[id] = alert.toRaw(true);
}
}
return { rawActiveAlerts, rawRecoveredAlerts };
}

View file

@ -432,7 +432,7 @@ export class TaskRunner<
// Only serialize alerts into task state if we're auto-recovering, otherwise
// we don't need to keep this information around.
if (this.ruleType.autoRecoverAlerts) {
const alerts = alertsClient.getRawAlertInstancesForState();
const alerts = alertsClient.getRawAlertInstancesForState(true);
alertsToReturn = alerts.rawActiveAlerts;
recoveredAlertsToReturn = alerts.rawRecoveredAlerts;
}