Skip to content
Merged
75 changes: 8 additions & 67 deletions x-pack/platform/plugins/shared/alerting_v2/server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,81 +5,22 @@
* 2.0.
*/

import { Logger, OnSetup, PluginSetup } from '@kbn/core-di';
import { CoreSetup, PluginInitializer, Route } from '@kbn/core-di-server';
import type { CoreStart, PluginConfigDescriptor, PluginInitializerContext } from '@kbn/core/server';
import type { TaskManagerSetupContract } from '@kbn/task-manager-plugin/server';
import { ContainerModule } from 'inversify';
import { RulesClient } from './lib/rules_client';
import type { PluginConfigDescriptor } from '@kbn/core/server';
import type { PluginConfig } from './config';
import { configSchema } from './config';
import { AlertingRetryService } from './lib/services/retry_service';
import { registerFeaturePrivileges } from './lib/security/privileges';
import { CreateRuleRoute } from './routes/create_rule_route';
import { DeleteRuleRoute } from './routes/delete_rule_route';
import { GetRuleRoute } from './routes/get_rule_route';
import { GetRulesRoute } from './routes/get_rules_route';
import { UpdateRuleRoute } from './routes/update_rule_route';
import { initializeRuleExecutorTaskDefinition } from './lib/rule_executor';
import { AlertingResourcesService } from './lib/services/alerting_resources_service';
import { registerSavedObjects } from './saved_objects';
import type { AlertingServerStartDependencies } from './types';
import { bindOnSetup } from './setup/bind_on_setup';
import { bindRoutes } from './setup/bind_routes';
import { bindServices } from './setup/bind_services';

export const config: PluginConfigDescriptor<PluginConfig> = {
schema: configSchema,
};

export const module = new ContainerModule(({ bind }) => {
// Register HTTP routes via DI
bind(Route).toConstantValue(CreateRuleRoute);
bind(Route).toConstantValue(DeleteRuleRoute);
bind(Route).toConstantValue(GetRuleRoute);
bind(Route).toConstantValue(GetRulesRoute);
bind(Route).toConstantValue(UpdateRuleRoute);

// Request-scoped rules client
bind(RulesClient).toSelf().inRequestScope();

// Singleton services
bind(AlertingRetryService).toSelf().inSingletonScope();
bind(AlertingResourcesService).toSelf().inSingletonScope();

bind(OnSetup).toConstantValue((container) => {
const logger = container.get(Logger);
const pluginConfig = container.get(
PluginInitializer('config')
) as PluginInitializerContext['config'];
const alertingConfig = pluginConfig.get<PluginConfig>();

// Register feature privileges
registerFeaturePrivileges(container.get(PluginSetup('features')));

// Saved Objects + Encrypted Saved Objects registration
registerSavedObjects({
savedObjects: container.get(CoreSetup('savedObjects')),
logger,
});

// Task type registration
const taskManagerSetup = container.get(PluginSetup<TaskManagerSetupContract>('taskManager'));
const getStartServices = container.get(CoreSetup('getStartServices')) as () => Promise<
[CoreStart, AlertingServerStartDependencies, unknown]
>;
const startServices = getStartServices();

const resourcesService = container.get(AlertingResourcesService);
resourcesService.startInitialization({
enabled: alertingConfig.enabled,
});

initializeRuleExecutorTaskDefinition(
logger,
taskManagerSetup,
startServices,
alertingConfig,
resourcesService
);
});
export const module = new ContainerModule((options) => {
bindRoutes(options);
bindServices(options);
bindOnSetup(options);
});

export type { PluginConfig as AlertingV2Config } from './config';
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import type { Logger } from '@kbn/core/server';
import { loggerMock } from '@kbn/logging-mocks';
import { LoggerService } from './logger_service';

describe('LoggerService', () => {
let mockLogger: jest.Mocked<Logger>;
let loggerService: LoggerService;

beforeEach(() => {
mockLogger = loggerMock.create();
loggerService = new LoggerService(mockLogger);
});

afterEach(() => {
jest.clearAllMocks();
});

describe('debug', () => {
it('should call logger.debug with the message', () => {
const message = 'Test debug message';

loggerService.debug({ message });

expect(mockLogger.debug).toHaveBeenCalledTimes(1);
expect(mockLogger.debug).toHaveBeenCalledWith(message);
});
});

describe('error', () => {
it('should call logger.error with error message and EcsError when only error is provided', () => {
const error = new Error('Test error');

loggerService.error({ error });

expect(mockLogger.error).toHaveBeenCalledTimes(1);
expect(mockLogger.error).toHaveBeenCalledWith(error.message, {
error: {
code: 'UNKNOWN_ERROR',
message: error.message,
stack_trace: error.stack,
type: 'Error',
},
});
});

it('should use the code and the type if provided', () => {
const error = new Error('Test error');
const code = 'CUSTOM_ERROR_CODE';
const type = 'CustomErrorType';

loggerService.error({ error, code, type });

expect(mockLogger.error).toHaveBeenCalledWith(error.message, {
error: {
code,
message: error.message,
stack_trace: error.stack,
type,
},
});
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import { inject, injectable } from 'inversify';
import type { Logger, LogMessageSource } from '@kbn/logging';
import { Logger as BaseLogger } from '@kbn/core-di';
import type { EcsError } from '@elastic/ecs';

interface DebugParams {
message: LogMessageSource;
}

interface InfoParams {
message: LogMessageSource;
}

interface WarnParams {
message: LogMessageSource;
}

interface ErrorParams {
error: Error;
code?: string;
type?: string;
}

@injectable()
export class LoggerService {
constructor(@inject(BaseLogger) private readonly logger: Logger) {}

public debug({ message }: DebugParams): void {
Comment thread
cnasikas marked this conversation as resolved.
this.logger.debug(message);
}

public error({ error, code, type }: ErrorParams): void {
const ecsError = this.buildError({ error, code, type });
this.logger.error(error.message, {
error: ecsError,
});
}

public info({ message }: InfoParams): void {
this.logger.info(message);
}

public warn({ message }: WarnParams): void {
this.logger.warn(message);
}

private buildError({ error, code, type }: ErrorParams): EcsError {
return {
code: code ?? 'UNKNOWN_ERROR',
message: error.message,
stack_trace: error.stack,
type: type ?? 'Error',
};
}
}
Loading