Skip to content

Commit

Permalink
Creating maintenance windows service
Browse files Browse the repository at this point in the history
  • Loading branch information
ymao1 committed Sep 11, 2024
1 parent fd46119 commit 3c4683b
Show file tree
Hide file tree
Showing 12 changed files with 317 additions and 137 deletions.
49 changes: 27 additions & 22 deletions x-pack/plugins/alerting/server/alerts_client/alerts_client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ import type { AlertRule, LogAlertsOpts, ProcessAlertsOpts, SearchResult } from '
import {
IAlertsClient,
InitializeExecutionOpts,
ProcessAndLogAlertsOpts,
TrackedAlerts,
ReportedAlert,
ReportedAlertData,
Expand Down Expand Up @@ -66,7 +65,7 @@ import { MaintenanceWindow } from '../application/maintenance_window/types';
import {
filterMaintenanceWindows,
filterMaintenanceWindowsIds,
} from '../task_runner/get_maintenance_windows';
} from '../task_runner/maintenance_windows';

// Term queries can take up to 10,000 terms
const CHUNK_SIZE = 10000;
Expand Down Expand Up @@ -121,7 +120,11 @@ export class AlertsClient<
LegacyContext,
ActionGroupIds,
RecoveryActionGroupId
>({ logger: this.options.logger, ruleType: this.options.ruleType });
>({
logger: this.options.logger,
maintenanceWindowsService: this.options.maintenanceWindowsService,
ruleType: this.options.ruleType,
});
this.indexTemplateAndPattern = getIndexTemplateAndPattern({
context: this.options.ruleType.alerts?.context!,
namespace: this.options.ruleType.alerts?.isSpaceAware
Expand Down Expand Up @@ -301,42 +304,42 @@ export class AlertsClient<
return this.legacyAlertsClient.checkLimitUsage();
}

public processAlerts(opts: ProcessAlertsOpts) {
this.legacyAlertsClient.processAlerts(opts);
public async processAlerts(opts: ProcessAlertsOpts) {
await this.legacyAlertsClient.processAlerts(opts);
}

public logAlerts(opts: LogAlertsOpts) {
this.legacyAlertsClient.logAlerts(opts);
}

public processAndLogAlerts(opts: ProcessAndLogAlertsOpts) {
this.legacyAlertsClient.processAndLogAlerts(opts);
}

public getProcessedAlerts(
type: 'new' | 'active' | 'activeCurrent' | 'recovered' | 'recoveredCurrent'
) {
return this.legacyAlertsClient.getProcessedAlerts(type);
}

public async persistAlerts(maintenanceWindows?: MaintenanceWindow[]): Promise<{
public async persistAlerts(): Promise<{
alertIds: string[];
maintenanceWindowIds: string[];
} | null> {
// Persist alerts first
await this.persistAlertsHelper();
const didWriteAlerts = await this.persistAlertsHelper();

// Try to update the persisted alerts with maintenance windows with a scoped query
let updateAlertsMaintenanceWindowResult = null;
try {
updateAlertsMaintenanceWindowResult = await this.updateAlertsMaintenanceWindowIdByScopedQuery(
maintenanceWindows ?? []
);
} catch (e) {
this.options.logger.debug(
`Failed to update alert matched by maintenance window scoped query ${this.ruleInfoMessage}`,
this.logTags
);
if (didWriteAlerts) {
// Try to update the persisted alerts with maintenance windows with a scoped query
const { maintenanceWindows } =
await this.options.maintenanceWindowsService.loadMaintenanceWindows();

try {
updateAlertsMaintenanceWindowResult =
await this.updateAlertsMaintenanceWindowIdByScopedQuery(maintenanceWindows ?? []);
} catch (e) {
this.options.logger.debug(
`Failed to update alert matched by maintenance window scoped query ${this.ruleInfoMessage}`,
this.logTags
);
}
}

return updateAlertsMaintenanceWindowResult;
Expand Down Expand Up @@ -418,7 +421,7 @@ export class AlertsClient<
`Resources registered and installed for ${this.ruleType.alerts?.context} context but "shouldWrite" is set to false ${this.ruleInfoMessage}.`,
this.logTags
);
return;
return false;
}
const currentTime = this.startedAtString ?? new Date().toISOString();
const esClient = await this.options.elasticsearchClientPromise;
Expand Down Expand Up @@ -623,6 +626,8 @@ export class AlertsClient<
},
};
}

return alertsToIndex.length > 0;
}

private async getMaintenanceWindowScopedQueryAlerts({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,24 +21,24 @@ import {
import { trimRecoveredAlerts } from '../lib/trim_recovered_alerts';
import { logAlerts } from '../task_runner/log_alerts';
import { AlertInstanceContext, AlertInstanceState, WithoutReservedActionGroups } from '../types';
import { MaintenanceWindow } from '../application/maintenance_window/types';
import {
DEFAULT_FLAPPING_SETTINGS,
RulesSettingsFlappingProperties,
} from '../../common/rules_settings';
import {
IAlertsClient,
InitializeExecutionOpts,
ProcessAndLogAlertsOpts,
ProcessAlertsOpts,
LogAlertsOpts,
TrackedAlerts,
} from './types';
import { DEFAULT_MAX_ALERTS } from '../config';
import { UntypedNormalizedRuleType } from '../rule_type_registry';
import { MaintenanceWindowsService } from '../task_runner/maintenance_windows';

export interface LegacyAlertsClientParams {
logger: Logger;
maintenanceWindowsService: MaintenanceWindowsService;
ruleType: UntypedNormalizedRuleType;
}

Expand Down Expand Up @@ -141,9 +141,8 @@ export class LegacyAlertsClient<
return !!this.trackedAlerts.active[id];
}

public processAlerts({
public async processAlerts({
flappingSettings,
maintenanceWindowIds,
alertDelay,
ruleRunMetricsStore,
}: ProcessAlertsOpts) {
Expand All @@ -164,9 +163,12 @@ export class LegacyAlertsClient<
});

if (keys(processedAlertsNew).length > 0) {
const { maintenanceWindowsWithoutScopedQueryIds } =
await this.options.maintenanceWindowsService.loadMaintenanceWindows();

for (const id in processedAlertsNew) {
if (Object.hasOwn(processedAlertsNew, id)) {
processedAlertsNew[id].setMaintenanceWindowIds(maintenanceWindowIds);
processedAlertsNew[id].setMaintenanceWindowIds(maintenanceWindowsWithoutScopedQueryIds);
}
}
}
Expand Down Expand Up @@ -211,28 +213,6 @@ export class LegacyAlertsClient<
});
}

public processAndLogAlerts({
eventLogger,
ruleRunMetricsStore,
shouldLogAlerts,
flappingSettings,
maintenanceWindowIds,
alertDelay,
}: ProcessAndLogAlertsOpts) {
this.processAlerts({
flappingSettings,
maintenanceWindowIds,
alertDelay,
ruleRunMetricsStore,
});

this.logAlerts({
eventLogger,
ruleRunMetricsStore,
shouldLogAlerts,
});
}

public getProcessedAlerts(
type: 'new' | 'active' | 'activeCurrent' | 'recovered' | 'recoveredCurrent'
) {
Expand Down Expand Up @@ -274,7 +254,7 @@ export class LegacyAlertsClient<
return null;
}

public async persistAlerts(maintenanceWindows?: MaintenanceWindow[]) {
public async persistAlerts() {
return null;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
SanitizedRule,
} from '../../types';
import { RuleTaskInstance, RuleTypeRunnerContext } from '../../task_runner/types';
import { MaintenanceWindowsService } from '../../task_runner/maintenance_windows';

export type RuleData<Params extends RuleTypeParams> = Pick<
SanitizedRule<Params>,
Expand All @@ -32,6 +33,7 @@ interface InitializeAlertsClientOpts<Params extends RuleTypeParams> {
executionId: string;
logger: Logger;
maxAlerts: number;
maintenanceWindowsService: MaintenanceWindowsService;
rule: RuleData<Params>;
ruleType: UntypedNormalizedRuleType;
runTimestamp?: Date;
Expand All @@ -52,6 +54,7 @@ export const initializeAlertsClient = async <
executionId,
logger,
maxAlerts,
maintenanceWindowsService,
rule,
ruleType,
runTimestamp,
Expand All @@ -65,7 +68,7 @@ export const initializeAlertsClient = async <
},
} = taskInstance;

const alertsClientParams = { logger, ruleType };
const alertsClientParams = { logger, maintenanceWindowsService, ruleType };

// Create AlertsClient if rule type has registered an alerts context
// with the framework. The AlertsClient will handle reading and
Expand Down
7 changes: 1 addition & 6 deletions x-pack/plugins/alerting/server/alerts_client/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,16 +74,12 @@ export interface IAlertsClient<
initializeExecution(opts: InitializeExecutionOpts): Promise<void>;
hasReachedAlertLimit(): boolean;
checkLimitUsage(): void;
processAndLogAlerts(opts: ProcessAndLogAlertsOpts): void;
processAlerts(opts: ProcessAlertsOpts): void;
logAlerts(opts: LogAlertsOpts): void;
getProcessedAlerts(
type: 'new' | 'active' | 'activeCurrent' | 'recovered' | 'recoveredCurrent'
): Record<string, LegacyAlert<State, Context, ActionGroupIds | RecoveryActionGroupId>>;
persistAlerts(maintenanceWindows?: MaintenanceWindow[]): Promise<{
alertIds: string[];
maintenanceWindowIds: string[];
} | null>;
persistAlerts(): Promise<{ alertIds: string[]; maintenanceWindowIds: string[] } | null>;
isTrackedAlert(id: string): boolean;
getSummarizedAlerts?(params: GetSummarizedAlertsParams): Promise<SummarizedAlerts>;
getAlertsToSerialize(): {
Expand Down Expand Up @@ -114,7 +110,6 @@ export interface ProcessAndLogAlertsOpts {

export interface ProcessAlertsOpts {
flappingSettings: RulesSettingsFlappingProperties;
maintenanceWindowIds: string[];
alertDelay: number;
ruleRunMetricsStore: RuleRunMetricsStore;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,7 @@ export class AlertsService implements IAlertsService {
logger: this.options.logger,
elasticsearchClientPromise: this.options.elasticsearchClientPromise,
ruleType: opts.ruleType,
maintenanceWindowsService: opts.maintenanceWindowsService,
namespace: opts.namespace,
rule: opts.rule,
kibanaVersion: this.options.kibanaVersion,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,19 @@

import { CoreKibanaRequest } from '@kbn/core-http-router-server-internal';
import { loggingSystemMock } from '@kbn/core-logging-server-mocks';
import { maintenanceWindowCategoryIdTypes } from '../application/maintenance_window/constants';
import { getMockMaintenanceWindow } from '../data/maintenance_window/test_helpers';
import { maintenanceWindowClientMock } from '../maintenance_window_client.mock';
import { MaintenanceWindowStatus } from '../types';
import { MaintenanceWindow } from '../application/maintenance_window/types';
import { mockedRawRuleSO, mockedRule } from './fixtures';
import { maintenanceWindowCategoryIdTypes } from '../../application/maintenance_window/constants';
import { getMockMaintenanceWindow } from '../../data/maintenance_window/test_helpers';
import { maintenanceWindowClientMock } from '../../maintenance_window_client.mock';
import { MaintenanceWindowStatus } from '../../types';
import { MaintenanceWindow } from '../../application/maintenance_window/types';
import { mockedRawRuleSO, mockedRule } from '../fixtures';
import {
filterMaintenanceWindows,
filterMaintenanceWindowsIds,
getMaintenanceWindows,
} from './get_maintenance_windows';
import { getFakeKibanaRequest } from './rule_loader';
import { TaskRunnerContext } from './types';
import { getFakeKibanaRequest } from '../rule_loader';
import { TaskRunnerContext } from '../types';
import { FilterStateStore } from '@kbn/es-query';

const logger = loggingSystemMock.create().get();
Expand Down Expand Up @@ -64,8 +64,8 @@ describe('getMaintenanceWindows', () => {
);
expect(
await getMaintenanceWindows({
context,
fakeRequest,
getMaintenanceWindowClientWithRequest: jest.fn().mockReturnValue(maintenanceWindowClient),
logger,
ruleTypeId,
ruleTypeCategory: 'observability',
Expand Down Expand Up @@ -98,8 +98,8 @@ describe('getMaintenanceWindows', () => {
);
expect(
await getMaintenanceWindows({
context,
fakeRequest,
getMaintenanceWindowClientWithRequest: jest.fn().mockReturnValue(maintenanceWindowClient),
logger,
ruleTypeId,
ruleTypeCategory: 'observability',
Expand Down Expand Up @@ -139,8 +139,8 @@ describe('getMaintenanceWindows', () => {
);
expect(
await getMaintenanceWindows({
context,
fakeRequest,
getMaintenanceWindowClientWithRequest: jest.fn().mockReturnValue(maintenanceWindowClient),
logger,
ruleTypeId,
ruleTypeCategory: 'observability',
Expand All @@ -153,8 +153,8 @@ describe('getMaintenanceWindows', () => {
maintenanceWindowClient.getActiveMaintenanceWindows.mockResolvedValueOnce([]);
expect(
await getMaintenanceWindows({
context,
fakeRequest,
getMaintenanceWindowClientWithRequest: jest.fn().mockReturnValue(maintenanceWindowClient),
logger,
ruleTypeId,
ruleTypeCategory: 'observability',
Expand All @@ -169,8 +169,8 @@ describe('getMaintenanceWindows', () => {
});
expect(
await getMaintenanceWindows({
context,
fakeRequest,
getMaintenanceWindowClientWithRequest: jest.fn().mockReturnValue(maintenanceWindowClient),
logger,
ruleTypeId,
ruleTypeCategory: 'observability',
Expand Down
Loading

0 comments on commit 3c4683b

Please sign in to comment.