File

shared/common/modules/apm/elastic-apm.interceptor.ts

Index

Methods

Constructor

constructor(apmService: ApmService, reflector: Reflector)
Parameters :
Name Type Optional
apmService ApmService No
reflector Reflector No

Methods

intercept
intercept(context: ExecutionContext, next: CallHandler)
Parameters :
Name Type Optional
context ExecutionContext No
next CallHandler<any> No
Returns : Observable | Promise
Private preparePayload
preparePayload(payload: object | string | number)
Parameters :
Name Type Optional
payload object | string | number No
Returns : object
import {
  CallHandler,
  ExecutionContext,
  Injectable,
  NestInterceptor
} from '@nestjs/common';
import {catchError, Observable, tap} from 'rxjs';
import {ApmService} from './apm.service';
import {Socket} from 'socket.io';
import {Reflector} from '@nestjs/core';
import {APM_TRANSACTION_DECORATOR} from './constants';
import {TransactionDecoratorData} from './interfaces';
import {AbstractGameClient} from '../../../interfaces/game';

@Injectable()
export class ElasticAPMInterceptor implements NestInterceptor {
  constructor(protected readonly apmService: ApmService,
              protected readonly reflector: Reflector) {
  }

  intercept(context: ExecutionContext, next: CallHandler<any>): Observable<any> | Promise<Observable<any>> {
    const transDecData: TransactionDecoratorData = this.reflector.get(APM_TRANSACTION_DECORATOR, context.getHandler());
    const host = context.switchToWs();
    const client: Socket = host.getClient();
    let socketName: string = client.nsp.name || '';
    socketName = socketName.endsWith('/') ? socketName : socketName + '/';
    const decTransNameFormatted = transDecData.name || '';
    const transName = socketName + decTransNameFormatted;
    const trans = this.apmService.startTransaction(transName, 'websocket');
    const userData: AbstractGameClient | undefined = client.data.user;
    this.apmService.setUserContext({
      id: userData?.clientId,
    });
    const payload = this.preparePayload(host.getData());
    this.apmService.setCustomContext(payload);
    return next.handle().pipe(catchError(e => trans.result = 'error'), tap(() => trans.end()));
  }

  private preparePayload(payload: object | string | number): object {
    return typeof payload === 'object' ? payload : {
      data: payload,
    }
  }
}

results matching ""

    No results matching ""