diff --git a/apps/api/src/aop/logging.interceptor.ts b/apps/api/src/aop/logging.interceptor.ts new file mode 100644 index 000000000..b98c3d31b --- /dev/null +++ b/apps/api/src/aop/logging.interceptor.ts @@ -0,0 +1,55 @@ +import { Logger } from '@nestjs/common'; +import { + Injectable, + NestInterceptor, + ExecutionContext, + CallHandler +} from '@nestjs/common'; +import { Observable } from 'rxjs'; +import { tap } from 'rxjs/operators'; + +const dict = {}; + +@Injectable() +export class LoggingInterceptor implements NestInterceptor { + intercept(context: ExecutionContext, next: CallHandler): Observable { + const methodName = + context.getClass().name + ':' + context.getHandler().name; + Logger.debug(`Before ${methodName}...`); + + const now = Date.now(); + return next + .handle() + .pipe( + tap(() => Logger.debug(`After ${methodName}... ${Date.now() - now}ms`)) + ); + } +} + +export function LogPerformance( + target: any, + propertyKey: string, + descriptor: PropertyDescriptor +) { + const originalMethod = descriptor.value; + if (Object.keys(dict).includes(propertyKey)) { + dict[propertyKey] += 1; + } else { + dict[propertyKey] = 1; + } + + descriptor.value = function (...args: any[]) { + const time = Date.now(); + const result = originalMethod.apply(this, args); + const now = Date.now(); + if (now - time > 100) { + Logger.debug(`${propertyKey} returned within: ${now - time} ms`); + } else if (dict[propertyKey] > 100) { + Logger.debug(`${propertyKey} was called the 100th time`); + dict[propertyKey] = 0; + } + return result; + }; + + return descriptor; +} diff --git a/apps/api/src/app/account-balance/account-balance.service.ts b/apps/api/src/app/account-balance/account-balance.service.ts index 8a9d7b83e..a75a1cbd1 100644 --- a/apps/api/src/app/account-balance/account-balance.service.ts +++ b/apps/api/src/app/account-balance/account-balance.service.ts @@ -1,3 +1,4 @@ +import { LogPerformance } from '@ghostfolio/api/aop/logging.interceptor'; import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; import { PrismaService } from '@ghostfolio/api/services/prisma/prisma.service'; import { AccountBalancesResponse, Filter } from '@ghostfolio/common/interfaces'; @@ -40,6 +41,7 @@ export class AccountBalanceService { }); } + @LogPerformance public async getAccountBalances({ filters, user, diff --git a/apps/api/src/main.ts b/apps/api/src/main.ts index 016f82473..b7b9a548a 100644 --- a/apps/api/src/main.ts +++ b/apps/api/src/main.ts @@ -5,6 +5,7 @@ import type { NestExpressApplication } from '@nestjs/platform-express'; import * as bodyParser from 'body-parser'; import helmet from 'helmet'; +import { LoggingInterceptor } from './aop/logging.interceptor'; import { AppModule } from './app/app.module'; import { environment } from './environments/environment'; import { HtmlTemplateMiddleware } from './middlewares/html-template.middleware'; @@ -25,6 +26,7 @@ async function bootstrap() { type: VersioningType.URI }); app.setGlobalPrefix('api', { exclude: ['sitemap.xml'] }); + app.useGlobalInterceptors(new LoggingInterceptor()); app.useGlobalPipes( new ValidationPipe({ forbidNonWhitelisted: true, diff --git a/apps/api/src/services/data-provider/data-provider.service.ts b/apps/api/src/services/data-provider/data-provider.service.ts index f8aca3723..1c951f4d7 100644 --- a/apps/api/src/services/data-provider/data-provider.service.ts +++ b/apps/api/src/services/data-provider/data-provider.service.ts @@ -1,3 +1,4 @@ +import { LogPerformance } from '@ghostfolio/api/aop/logging.interceptor'; import { RedisCacheService } from '@ghostfolio/api/app/redis-cache/redis-cache.service'; import { LookupItem } from '@ghostfolio/api/app/symbol/interfaces/lookup-item.interface'; import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; @@ -332,6 +333,7 @@ export class DataProviderService { return result; } + @LogPerformance public async getQuotes({ items, requestTimeout, diff --git a/apps/api/src/services/symbol-profile/symbol-profile.service.ts b/apps/api/src/services/symbol-profile/symbol-profile.service.ts index ce5337c17..abf973029 100644 --- a/apps/api/src/services/symbol-profile/symbol-profile.service.ts +++ b/apps/api/src/services/symbol-profile/symbol-profile.service.ts @@ -1,3 +1,4 @@ +import { LogPerformance } from '@ghostfolio/api/aop/logging.interceptor'; import { PrismaService } from '@ghostfolio/api/services/prisma/prisma.service'; import { UNKNOWN_KEY } from '@ghostfolio/common/config'; import { @@ -39,6 +40,7 @@ export class SymbolProfileService { }); } + @LogPerformance public async getSymbolProfiles( aUniqueAssets: UniqueAsset[] ): Promise {