Add Sentry for Backend (#1403)
* - added sentry * - renamed env var * - logger driver * - add breadcrumb and category * - fix driver
This commit is contained in:
67
server/src/integrations/logger/drivers/sentry.driver.ts
Normal file
67
server/src/integrations/logger/drivers/sentry.driver.ts
Normal file
@ -0,0 +1,67 @@
|
||||
import { LoggerService } from '@nestjs/common';
|
||||
|
||||
import * as Sentry from '@sentry/node';
|
||||
|
||||
export interface SentryDriverOptions {
|
||||
sentryDNS: string;
|
||||
}
|
||||
|
||||
export class SentryDriver implements LoggerService {
|
||||
constructor(options: SentryDriverOptions) {
|
||||
Sentry.init({
|
||||
dsn: options.sentryDNS,
|
||||
tracesSampleRate: 1.0,
|
||||
profilesSampleRate: 1.0,
|
||||
});
|
||||
}
|
||||
|
||||
log(message: any, category: string) {
|
||||
Sentry.addBreadcrumb({
|
||||
message,
|
||||
level: 'log',
|
||||
data: {
|
||||
category,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
error(message: any, category: string) {
|
||||
Sentry.addBreadcrumb({
|
||||
message,
|
||||
level: 'error',
|
||||
data: {
|
||||
category,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
warn(message: any, category: string) {
|
||||
Sentry.addBreadcrumb({
|
||||
message,
|
||||
level: 'error',
|
||||
data: {
|
||||
category,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
debug?(message: any, category: string) {
|
||||
Sentry.addBreadcrumb({
|
||||
message,
|
||||
level: 'debug',
|
||||
data: {
|
||||
category,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
verbose?(message: any, category: string) {
|
||||
Sentry.addBreadcrumb({
|
||||
message,
|
||||
level: 'info',
|
||||
data: {
|
||||
category,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
1
server/src/integrations/logger/interfaces/index.ts
Normal file
1
server/src/integrations/logger/interfaces/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from './logger.interface';
|
||||
@ -0,0 +1,17 @@
|
||||
import { LoggerType } from 'src/integrations/environment/interfaces/logger.interface';
|
||||
|
||||
export interface SentryDriverFactoryOptions {
|
||||
type: LoggerType.Sentry;
|
||||
options: {
|
||||
sentryDNS: string;
|
||||
};
|
||||
}
|
||||
|
||||
export interface ConsoleDriverFactoryOptions {
|
||||
type: LoggerType.Console;
|
||||
options: null;
|
||||
}
|
||||
|
||||
export type LoggerModuleOptions =
|
||||
| SentryDriverFactoryOptions
|
||||
| ConsoleDriverFactoryOptions;
|
||||
1
server/src/integrations/logger/logger.constants.ts
Normal file
1
server/src/integrations/logger/logger.constants.ts
Normal file
@ -0,0 +1 @@
|
||||
export const LOGGER_DRIVER = Symbol('LOGGER_DRIVER');
|
||||
25
server/src/integrations/logger/logger.module-definition.ts
Normal file
25
server/src/integrations/logger/logger.module-definition.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import {
|
||||
ConfigurableModuleBuilder,
|
||||
FactoryProvider,
|
||||
ModuleMetadata,
|
||||
} from '@nestjs/common';
|
||||
|
||||
import { LoggerModuleOptions } from './interfaces';
|
||||
|
||||
export const {
|
||||
ConfigurableModuleClass,
|
||||
MODULE_OPTIONS_TOKEN,
|
||||
OPTIONS_TYPE,
|
||||
ASYNC_OPTIONS_TYPE,
|
||||
} = new ConfigurableModuleBuilder<LoggerModuleOptions>({
|
||||
moduleName: 'LoggerService',
|
||||
})
|
||||
.setClassMethodName('forRoot')
|
||||
.build();
|
||||
|
||||
export type LoggerModuleAsyncOptions = {
|
||||
useFactory: (
|
||||
...args: any[]
|
||||
) => LoggerModuleOptions | Promise<LoggerModuleOptions>;
|
||||
} & Pick<ModuleMetadata, 'imports'> &
|
||||
Pick<FactoryProvider, 'inject'>;
|
||||
49
server/src/integrations/logger/logger.module.ts
Normal file
49
server/src/integrations/logger/logger.module.ts
Normal file
@ -0,0 +1,49 @@
|
||||
import { DynamicModule, Global, ConsoleLogger } from '@nestjs/common';
|
||||
|
||||
import { LoggerType } from 'src/integrations/environment/interfaces/logger.interface';
|
||||
|
||||
import { LoggerService } from './logger.service';
|
||||
import { LoggerModuleOptions } from './interfaces';
|
||||
import { LOGGER_DRIVER } from './logger.constants';
|
||||
import { LoggerModuleAsyncOptions } from './logger.module-definition';
|
||||
|
||||
import { SentryDriver } from './drivers/sentry.driver';
|
||||
|
||||
@Global()
|
||||
export class LoggerModule {
|
||||
static forRoot(options: LoggerModuleOptions): DynamicModule {
|
||||
const provider = {
|
||||
provide: LOGGER_DRIVER,
|
||||
useValue:
|
||||
options.type === LoggerType.Console
|
||||
? new ConsoleLogger()
|
||||
: new SentryDriver(options.options),
|
||||
};
|
||||
|
||||
return {
|
||||
module: LoggerModule,
|
||||
providers: [LoggerService, provider],
|
||||
exports: [LoggerService],
|
||||
};
|
||||
}
|
||||
|
||||
static forRootAsync(options: LoggerModuleAsyncOptions): DynamicModule {
|
||||
const provider = {
|
||||
provide: LOGGER_DRIVER,
|
||||
useFactory: async (...args: any[]) => {
|
||||
const config = await options.useFactory(...args);
|
||||
return config?.type === LoggerType.Console
|
||||
? new ConsoleLogger()
|
||||
: new SentryDriver(config.options);
|
||||
},
|
||||
inject: options.inject || [],
|
||||
};
|
||||
|
||||
return {
|
||||
module: LoggerModule,
|
||||
imports: options.imports || [],
|
||||
providers: [LoggerService, provider],
|
||||
exports: [LoggerService],
|
||||
};
|
||||
}
|
||||
}
|
||||
26
server/src/integrations/logger/logger.service.spec.ts
Normal file
26
server/src/integrations/logger/logger.service.spec.ts
Normal file
@ -0,0 +1,26 @@
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
|
||||
import { LoggerService } from './logger.service';
|
||||
import { LOGGER_DRIVER } from './logger.constants';
|
||||
|
||||
describe('LoggerService', () => {
|
||||
let service: LoggerService;
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
providers: [
|
||||
LoggerService,
|
||||
{
|
||||
provide: LOGGER_DRIVER,
|
||||
useValue: {},
|
||||
},
|
||||
],
|
||||
}).compile();
|
||||
|
||||
service = module.get<LoggerService>(LoggerService);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(service).toBeDefined();
|
||||
});
|
||||
});
|
||||
44
server/src/integrations/logger/logger.service.ts
Normal file
44
server/src/integrations/logger/logger.service.ts
Normal file
@ -0,0 +1,44 @@
|
||||
import {
|
||||
Inject,
|
||||
Injectable,
|
||||
LoggerService as ConsoleLoggerService,
|
||||
} from '@nestjs/common';
|
||||
|
||||
import { LOGGER_DRIVER } from './logger.constants';
|
||||
|
||||
@Injectable()
|
||||
export class LoggerService implements ConsoleLoggerService {
|
||||
constructor(@Inject(LOGGER_DRIVER) private driver: ConsoleLoggerService) {}
|
||||
|
||||
log(message: any, category: string, ...optionalParams: any[]) {
|
||||
this.driver.log.apply(this.driver, [message, category, ...optionalParams]);
|
||||
}
|
||||
|
||||
error(message: any, category: string, ...optionalParams: any[]) {
|
||||
this.driver.error.apply(this.driver, [
|
||||
message,
|
||||
category,
|
||||
...optionalParams,
|
||||
]);
|
||||
}
|
||||
|
||||
warn(message: any, category: string, ...optionalParams: any[]) {
|
||||
this.driver.warn.apply(this.driver, [message, category, ...optionalParams]);
|
||||
}
|
||||
|
||||
debug?(message: any, category: string, ...optionalParams: any[]) {
|
||||
this.driver.debug?.apply(this.driver, [
|
||||
message,
|
||||
category,
|
||||
...optionalParams,
|
||||
]);
|
||||
}
|
||||
|
||||
verbose?(message: any, category: string, ...optionalParams: any[]) {
|
||||
this.driver.verbose?.apply(this.driver, [
|
||||
message,
|
||||
category,
|
||||
...optionalParams,
|
||||
]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user