diff --git a/packages/core/src/app.module.ts b/packages/core/src/app.module.ts index 971280eedd4..c9dca6f2ec9 100644 --- a/packages/core/src/app.module.ts +++ b/packages/core/src/app.module.ts @@ -5,7 +5,7 @@ import { APP_GUARD, APP_INTERCEPTOR, HttpAdapterHost } from '@nestjs/core'; import { MulterModule } from '@nestjs/platform-express'; import { ThrottlerModule, ThrottlerModuleOptions } from '@nestjs/throttler'; import { ThrottlerBehindProxyGuard } from 'throttler/throttler-behind-proxy.guard'; -import { SentryModule } from './core/sentry/ntegral'; +import { SentryModule, SentryModuleOptions, SENTRY_MODULE_OPTIONS } from './core/sentry/ntegral'; import { GraphqlInterceptor } from './core/sentry/ntegral'; import { ServeStaticModule, ServeStaticModuleOptions } from '@nestjs/serve-static'; import { HeaderResolver, I18nModule } from 'nestjs-i18n'; @@ -237,6 +237,36 @@ if (environment.sentry && environment.sentry.dsn) { console.log('Sentry Request Data Enabled'); } +function createSentryOptions(host: HttpAdapterHost): SentryModuleOptions { + return { + dsn: environment.sentry.dsn, + debug: process.env.SENTRY_DEBUG === 'true' || !environment.production, + environment: environment.production ? 'production' : 'development', + // TODO: we should use some internal function which returns version of Gauzy + release: 'gauzy@' + process.env.npm_package_version, + logLevels: ['error'], + integrations: [ + ...sentryIntegrations, + host?.httpAdapter + ? new Integrations.Express({ + app: host.httpAdapter.getInstance() + }) + : null + ].filter((i) => !!i), + tracesSampleRate: process.env.SENTRY_TRACES_SAMPLE_RATE + ? parseInt(process.env.SENTRY_TRACES_SAMPLE_RATE) + : 0.01, + profilesSampleRate: process.env.SENTRY_PROFILE_SAMPLE_RATE + ? parseInt(process.env.SENTRY_PROFILE_SAMPLE_RATE) + : 1, + close: { + enabled: true, + // Time in milliseconds to forcefully quit the application + timeout: 3000 + } + }; +} + @Module({ imports: [ ...(process.env.REDIS_ENABLED === 'true' @@ -283,11 +313,32 @@ if (environment.sentry && environment.sentry.dsn) { url: url, username: username, password: password, - ttl: 60 * 60 * 24 * 7 // 1 week + ttl: 60 * 60 * 24 * 7 // 1 week, }; const store = await redisStore(storeOptions); + store.client + .on('error', (err) => { + console.log('Redis Client Error: ', err); + }) + .on('connect', () => { + console.log('Redis Client Connected'); + }) + .on('ready', () => { + console.log('Redis Client Ready'); + }) + .on('reconnecting', () => { + console.log('Redis Client Reconnecting'); + }) + .on('end', () => { + console.log('Redis Client End'); + }); + + // ping Redis + const res = await store.client.ping(); + console.log('Redis Client Cache Ping: ', res); + return { store: () => store }; @@ -315,33 +366,7 @@ if (environment.sentry && environment.sentry.dsn) { ? [ SentryModule.forRootAsync({ inject: [ConfigService, HttpAdapterHost], - useFactory: async (config: ConfigService, host: HttpAdapterHost) => ({ - dsn: environment.sentry.dsn, - debug: process.env.SENTRY_DEBUG === 'true' || !environment.production, - environment: environment.production ? 'production' : 'development', - // TODO: we should use some internal function which returns version of Gauzy - release: 'gauzy@' + process.env.npm_package_version, - logLevels: ['error'], - integrations: [ - ...sentryIntegrations, - host?.httpAdapter - ? new Integrations.Express({ - app: host.httpAdapter.getInstance() - }) - : null - ].filter((i) => !!i), - tracesSampleRate: process.env.SENTRY_TRACES_SAMPLE_RATE - ? parseInt(process.env.SENTRY_TRACES_SAMPLE_RATE) - : 0.01, - profilesSampleRate: process.env.SENTRY_PROFILE_SAMPLE_RATE - ? parseInt(process.env.SENTRY_PROFILE_SAMPLE_RATE) - : 1, - close: { - enabled: true, - // Time in milliseconds to forcefully quit the application - timeout: 3000 - } - }) + useFactory: createSentryOptions }) ] : []), @@ -533,6 +558,11 @@ if (environment.sentry && environment.sentry.dsn) { }, ...(environment.sentry && environment.sentry.dsn ? [ + { + provide: SENTRY_MODULE_OPTIONS, + useFactory: createSentryOptions, + inject: [HttpAdapterHost] + }, { provide: APP_INTERCEPTOR, useFactory: () => new SentryCustomInterceptor() diff --git a/packages/core/src/bootstrap/index.ts b/packages/core/src/bootstrap/index.ts index b65e150346e..6fa3e2289f1 100644 --- a/packages/core/src/bootstrap/index.ts +++ b/packages/core/src/bootstrap/index.ts @@ -178,7 +178,7 @@ export async function bootstrap(pluginConfig?: Partial): Promise< // ping Redis const res = await redisClient.ping(); - console.log('Redis Client ping: ', res); + console.log('Redis Client Sessions Ping: ', res); const redisStore = new RedisStore({ client: redisClient, diff --git a/packages/core/src/core/sentry/ntegral/sentry.interfaces.ts b/packages/core/src/core/sentry/ntegral/sentry.interfaces.ts index 4410406e059..0cba510e8f1 100644 --- a/packages/core/src/core/sentry/ntegral/sentry.interfaces.ts +++ b/packages/core/src/core/sentry/ntegral/sentry.interfaces.ts @@ -1,52 +1,53 @@ -import { ModuleMetadata, Type } from "@nestjs/common/interfaces"; +import { ModuleMetadata, Type } from '@nestjs/common/interfaces'; import { Integration, Options } from '@sentry/types'; -import { ConsoleLoggerOptions, HttpException } from "@nestjs/common"; -import { SeverityLevel } from "@sentry/node"; +import { ConsoleLoggerOptions } from '@nestjs/common'; +import { SeverityLevel } from '@sentry/node'; export interface SentryCloseOptions { - enabled: boolean; - // timeout – Maximum time in ms the client should wait until closing forcefully - timeout?: number; + enabled: boolean; + // timeout – Maximum time in ms the client should wait until closing forcefully + timeout?: number; } export type SentryModuleOptions = Omit & { - integrations?: Integration[]; - close?: SentryCloseOptions + integrations?: Integration[]; + close?: SentryCloseOptions; + profilesSampleRate?: number; } & ConsoleLoggerOptions; export interface SentryOptionsFactory { - createSentryModuleOptions(): Promise | SentryModuleOptions; + createSentryModuleOptions(): Promise | SentryModuleOptions; } export interface SentryModuleAsyncOptions extends Pick { - inject?: any[]; - useClass?: Type; - useExisting?: Type; - useFactory?: (...args: any[]) => Promise | SentryModuleOptions; + inject?: any[]; + useClass?: Type; + useExisting?: Type; + useFactory?: (...args: any[]) => Promise | SentryModuleOptions; } export type SentryTransaction = boolean | 'path' | 'methodPath' | 'handler'; export interface SentryFilterFunction { - (exception:any): boolean + (exception: any): boolean; } export interface SentryInterceptorOptionsFilter { - type: any; - filter?: SentryFilterFunction; + type: any; + filter?: SentryFilterFunction; } export interface SentryInterceptorOptions { - filters?: SentryInterceptorOptionsFilter[]; - tags?: { [key: string]: string }; - extra?: { [key: string]: any }; - fingerprint?: string[]; - level?: SeverityLevel; - - // https://github.com/getsentry/sentry-javascript/blob/master/packages/node/src/handlers.ts#L163 - request?: boolean; - serverName?: boolean; - transaction?: boolean | 'path' | 'methodPath' | 'handler'; // https://github.com/getsentry/sentry-javascript/blob/master/packages/node/src/handlers.ts#L16 - user?: boolean | string[]; - version?: boolean; -} \ No newline at end of file + filters?: SentryInterceptorOptionsFilter[]; + tags?: { [key: string]: string }; + extra?: { [key: string]: any }; + fingerprint?: string[]; + level?: SeverityLevel; + + // https://github.com/getsentry/sentry-javascript/blob/master/packages/node/src/handlers.ts#L163 + request?: boolean; + serverName?: boolean; + transaction?: boolean | 'path' | 'methodPath' | 'handler'; // https://github.com/getsentry/sentry-javascript/blob/master/packages/node/src/handlers.ts#L16 + user?: boolean | string[]; + version?: boolean; +} diff --git a/packages/core/src/core/sentry/sentry-request.middleware.ts b/packages/core/src/core/sentry/sentry-request.middleware.ts index 3082b9861c2..13c809aa276 100644 --- a/packages/core/src/core/sentry/sentry-request.middleware.ts +++ b/packages/core/src/core/sentry/sentry-request.middleware.ts @@ -1,5 +1,4 @@ import { Injectable, NestMiddleware } from '@nestjs/common'; -import { InjectSentry, SentryService } from './ntegral'; import { Handlers } from '@sentry/node'; import { NextFunction, Request, Response } from 'express'; @@ -14,7 +13,7 @@ export class SentryRequestMiddleware implements NestMiddleware { } }); - constructor(@InjectSentry() private readonly sentry: SentryService) {} + constructor() {} use(req: Request, res: Response, next: NextFunction): void { this.handler(req, res, next); } diff --git a/packages/core/src/core/sentry/sentry-trace.middleware.ts b/packages/core/src/core/sentry/sentry-trace.middleware.ts index 49e326f86e7..773cc253536 100644 --- a/packages/core/src/core/sentry/sentry-trace.middleware.ts +++ b/packages/core/src/core/sentry/sentry-trace.middleware.ts @@ -1,5 +1,4 @@ import { Injectable, NestMiddleware } from '@nestjs/common'; -import { InjectSentry, SentryService } from './ntegral'; import { Handlers } from '@sentry/node'; import { NextFunction, Request, Response } from 'express'; @@ -7,7 +6,6 @@ import { NextFunction, Request, Response } from 'express'; export class SentryTraceMiddleware implements NestMiddleware { private readonly handler = Handlers.tracingHandler(); - constructor(@InjectSentry() private readonly sentry: SentryService) {} use(req: Request, res: Response, next: NextFunction): void { this.handler(req, res, next); }