shared/common/modules/apm/elastic-apm.interceptor.ts
Methods |
|
constructor(apmService: ApmService, reflector: Reflector)
|
|||||||||
Parameters :
|
intercept | |||||||||
intercept(context: ExecutionContext, next: CallHandler
|
|||||||||
Parameters :
Returns :
Observable | Promise
|
Private preparePayload | ||||||
preparePayload(payload: object | string | number)
|
||||||
Parameters :
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,
}
}
}