Browse Source

Setup performance logging service

pull/3703/head
Thomas Kaul 1 year ago
parent
commit
6213fa385c
  1. 2
      apps/api/src/app/account-balance/account-balance.service.ts
  2. 2
      apps/api/src/app/order/order.service.ts
  3. 4
      apps/api/src/app/portfolio/calculator/portfolio-calculator.ts
  4. 2
      apps/api/src/app/portfolio/portfolio.controller.ts
  5. 2
      apps/api/src/app/portfolio/portfolio.module.ts
  6. 80
      apps/api/src/interceptors/performance-logging/performance-logging.interceptor.ts
  7. 10
      apps/api/src/interceptors/performance-logging/performance-logging.module.ts
  8. 21
      apps/api/src/interceptors/performance-logging/performance-logging.service.ts
  9. 2
      apps/api/src/services/exchange-rate-data/exchange-rate-data.service.ts

2
apps/api/src/app/account-balance/account-balance.service.ts

@ -1,4 +1,5 @@
import { PortfolioChangedEvent } from '@ghostfolio/api/events/portfolio-changed.event';
import { LogPerformance } from '@ghostfolio/api/interceptors/performance-logging/performance-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 { resetHours } from '@ghostfolio/common/helper';
@ -90,6 +91,7 @@ export class AccountBalanceService {
return accountBalance;
}
@LogPerformance
public async getAccountBalances({
filters,
user,

2
apps/api/src/app/order/order.service.ts

@ -1,5 +1,6 @@
import { AccountService } from '@ghostfolio/api/app/account/account.service';
import { PortfolioChangedEvent } from '@ghostfolio/api/events/portfolio-changed.event';
import { LogPerformance } from '@ghostfolio/api/interceptors/performance-logging/performance-logging.interceptor';
import { DataGatheringService } from '@ghostfolio/api/services/data-gathering/data-gathering.service';
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service';
import { PrismaService } from '@ghostfolio/api/services/prisma/prisma.service';
@ -519,6 +520,7 @@ export class OrderService {
return { activities, count };
}
@LogPerformance
public async getOrdersForPortfolioCalculator({
filters,
userCurrency,

4
apps/api/src/app/portfolio/calculator/portfolio-calculator.ts

@ -5,6 +5,7 @@ import { TransactionPointSymbol } from '@ghostfolio/api/app/portfolio/interfaces
import { TransactionPoint } from '@ghostfolio/api/app/portfolio/interfaces/transaction-point.interface';
import { RedisCacheService } from '@ghostfolio/api/app/redis-cache/redis-cache.service';
import { getFactor } from '@ghostfolio/api/helper/portfolio.helper';
import { LogPerformance } from '@ghostfolio/api/interceptors/performance-logging/performance-logging.interceptor';
import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service';
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service';
import { IDataGatheringItem } from '@ghostfolio/api/services/interfaces/interfaces';
@ -148,6 +149,7 @@ export abstract class PortfolioCalculator {
positions: TimelinePosition[]
): PortfolioSnapshot;
@LogPerformance
private async computeSnapshot(): Promise<PortfolioSnapshot> {
const lastTransactionPoint = last(this.transactionPoints);
@ -861,6 +863,7 @@ export abstract class PortfolioCalculator {
return chartDateMap;
}
@LogPerformance
private computeTransactionPoints() {
this.transactionPoints = [];
const symbols: { [symbol: string]: TransactionPointSymbol } = {};
@ -999,6 +1002,7 @@ export abstract class PortfolioCalculator {
}
}
@LogPerformance
private async initialize() {
const startTimeTotal = performance.now();

2
apps/api/src/app/portfolio/portfolio.controller.ts

@ -7,6 +7,7 @@ import {
hasNotDefinedValuesInObject,
nullifyValuesInObject
} from '@ghostfolio/api/helper/object.helper';
import { PerformanceLoggingInterceptor } from '@ghostfolio/api/interceptors/performance-logging/performance-logging.interceptor';
import { RedactValuesInResponseInterceptor } from '@ghostfolio/api/interceptors/redact-values-in-response/redact-values-in-response.interceptor';
import { TransformDataSourceInRequestInterceptor } from '@ghostfolio/api/interceptors/transform-data-source-in-request/transform-data-source-in-request.interceptor';
import { TransformDataSourceInResponseInterceptor } from '@ghostfolio/api/interceptors/transform-data-source-in-response/transform-data-source-in-response.interceptor';
@ -390,6 +391,7 @@ export class PortfolioController {
@Get('performance')
@UseGuards(AuthGuard('jwt'), HasPermissionGuard)
@UseInterceptors(PerformanceLoggingInterceptor)
@UseInterceptors(TransformDataSourceInResponseInterceptor)
@Version('2')
public async getPerformanceV2(

2
apps/api/src/app/portfolio/portfolio.module.ts

@ -4,6 +4,7 @@ import { AccountService } from '@ghostfolio/api/app/account/account.service';
import { OrderModule } from '@ghostfolio/api/app/order/order.module';
import { RedisCacheModule } from '@ghostfolio/api/app/redis-cache/redis-cache.module';
import { UserModule } from '@ghostfolio/api/app/user/user.module';
import { PerformanceLoggingModule } from '@ghostfolio/api/interceptors/performance-logging/performance-logging.module';
import { RedactValuesInResponseModule } from '@ghostfolio/api/interceptors/redact-values-in-response/redact-values-in-response.module';
import { TransformDataSourceInRequestModule } from '@ghostfolio/api/interceptors/transform-data-source-in-request/transform-data-source-in-request.module';
import { TransformDataSourceInResponseModule } from '@ghostfolio/api/interceptors/transform-data-source-in-response/transform-data-source-in-response.module';
@ -38,6 +39,7 @@ import { RulesService } from './rules.service';
ImpersonationModule,
MarketDataModule,
OrderModule,
PerformanceLoggingModule,
PrismaModule,
RedactValuesInResponseModule,
RedisCacheModule,

80
apps/api/src/interceptors/performance-logging/performance-logging.interceptor.ts

@ -0,0 +1,80 @@
import {
Injectable,
NestInterceptor,
ExecutionContext,
CallHandler
} from '@nestjs/common';
import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';
import { PerformanceLoggingService } from './performance-logging.service';
@Injectable()
export class PerformanceLoggingInterceptor implements NestInterceptor {
public constructor(
private readonly performanceLoggingService: PerformanceLoggingService
) {}
public intercept(
context: ExecutionContext,
next: CallHandler
): Observable<any> {
const startTime = performance.now();
const className = context.getClass().name;
const methodName = context.getHandler().name;
return next.handle().pipe(
tap(() => {
return this.performanceLoggingService.logPerformance({
className,
methodName,
startTime
});
})
);
}
}
export function LogPerformance(
target: any,
propertyKey: string,
descriptor: PropertyDescriptor
) {
const originalMethod = descriptor.value;
descriptor.value = async function (...args: any[]) {
const startTime = performance.now();
const performanceLoggingService = new PerformanceLoggingService();
const result = originalMethod.apply(this, args);
if (result instanceof Promise) {
// Handle async method
return result
.then((res: any) => {
performanceLoggingService.logPerformance({
startTime,
className: target.constructor.name,
methodName: propertyKey
});
return res;
})
.catch((error: any) => {
throw error;
});
} else {
// Handle sync method
performanceLoggingService.logPerformance({
startTime,
className: target.constructor.name,
methodName: propertyKey
});
return result;
}
};
return descriptor;
}

10
apps/api/src/interceptors/performance-logging/performance-logging.module.ts

@ -0,0 +1,10 @@
import { Module } from '@nestjs/common';
import { PerformanceLoggingInterceptor } from './performance-logging.interceptor';
import { PerformanceLoggingService } from './performance-logging.service';
@Module({
exports: [PerformanceLoggingInterceptor, PerformanceLoggingService],
providers: [PerformanceLoggingInterceptor, PerformanceLoggingService]
})
export class PerformanceLoggingModule {}

21
apps/api/src/interceptors/performance-logging/performance-logging.service.ts

@ -0,0 +1,21 @@
import { Injectable, Logger } from '@nestjs/common';
@Injectable()
export class PerformanceLoggingService {
public logPerformance({
className,
methodName,
startTime
}: {
className: string;
methodName: string;
startTime: number;
}) {
const endTime = performance.now();
Logger.debug(
`Completed execution of ${methodName}() in ${((endTime - startTime) / 1000).toFixed(3)} seconds`,
className
);
}
}

2
apps/api/src/services/exchange-rate-data/exchange-rate-data.service.ts

@ -1,3 +1,4 @@
import { LogPerformance } from '@ghostfolio/api/interceptors/performance-logging/performance-logging.interceptor';
import { DataProviderService } from '@ghostfolio/api/services/data-provider/data-provider.service';
import { IDataGatheringItem } from '@ghostfolio/api/services/interfaces/interfaces';
import { MarketDataService } from '@ghostfolio/api/services/market-data/market-data.service';
@ -46,6 +47,7 @@ export class ExchangeRateDataService {
return this.currencyPairs;
}
@LogPerformance
public async getExchangeRatesByCurrency({
currencies,
endDate = new Date(),

Loading…
Cancel
Save