Skip to content

Commit

Permalink
MEX-623: custom logging for filteredPairs query
Browse files Browse the repository at this point in the history
  • Loading branch information
mad2sm0key committed Dec 13, 2024
1 parent 8ba9388 commit 8337d37
Showing 1 changed file with 67 additions and 8 deletions.
75 changes: 67 additions & 8 deletions src/utils/query.metrics.plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,35 @@ import { Plugin } from '@nestjs/apollo';
import { PerformanceProfiler } from './performance.profiler';
import { CpuProfiler } from '@multiversx/sdk-nestjs-monitoring';
import { MetricsCollector } from './metrics.collector';
import { Kind, OperationTypeNode } from 'graphql';
import { FieldNode, Kind, OperationTypeNode, SelectionNode } from 'graphql';
import { WINSTON_MODULE_PROVIDER } from 'nest-winston';
import { Inject } from '@nestjs/common';
import { Logger } from 'winston';

type QueryField = {
name: string;
subfields?: QueryField[];
};

@Plugin()
export class QueryMetricsPlugin implements ApolloServerPlugin {
constructor(
@Inject(WINSTON_MODULE_PROVIDER) private readonly logger: Logger,
) {}

async requestDidStart(): Promise<GraphQLRequestListener<any>> {
const logger = this.logger;
let profiler: PerformanceProfiler;
let cpuProfiler: CpuProfiler;
let operationName: string;
let origin: string;
let queryFields: string;

return {
async executionDidStart(
requestContext: GraphQLRequestContext<any>,
): Promise<void | GraphQLRequestExecutionListener<any>> {
operationName = deanonymizeQuery(requestContext);
[operationName, queryFields] = deanonymizeQuery(requestContext);
origin =
requestContext.request.http?.headers.get('origin') ??
'Unknown';
Expand All @@ -35,6 +49,12 @@ export class QueryMetricsPlugin implements ApolloServerPlugin {
profiler.stop(operationName);
const cpuTime = cpuProfiler.stop();

if (operationName === 'filteredPairs') {
logger.info(queryFields, {
context: QueryMetricsPlugin.name,
});
}

MetricsCollector.setQueryDuration(
operationName,
origin,
Expand All @@ -47,15 +67,19 @@ export class QueryMetricsPlugin implements ApolloServerPlugin {
}
}

function deanonymizeQuery(requestContext: GraphQLRequestContext<any>): string {
function deanonymizeQuery(
requestContext: GraphQLRequestContext<any>,
): [string, string] {
if (requestContext.operationName) {
return requestContext.operationName;
return [requestContext.operationName, ''];
}

if (!requestContext.document) {
return requestContext.queryHash;
return [requestContext.queryHash, ''];
}

let debugFields: string;

const queryNames = [];
const definitions = requestContext.document.definitions;
for (const definition of definitions) {
Expand All @@ -74,11 +98,46 @@ function deanonymizeQuery(requestContext: GraphQLRequestContext<any>): string {

const name = selection.name?.value ?? 'undefined';

if (name === 'filteredPairs') {
const fields = extractQueryFields(
selection.selectionSet?.selections || [],
);
debugFields = JSON.stringify(fields);
}

queryNames.push(name);
}
}

return queryNames.length > 0
? queryNames.join('|')
: requestContext.queryHash;
const deanonymizedQuery =
queryNames.length > 0 ? queryNames.join('|') : requestContext.queryHash;

return [deanonymizedQuery, debugFields];
}

function extractQueryFields(
selectionNodes: readonly SelectionNode[],
): QueryField[] {
const fields: QueryField[] = [];

selectionNodes
.filter((node): node is FieldNode => node.kind === Kind.FIELD)
.forEach((node) => {
if (node.selectionSet) {
const subfields = extractQueryFields(
node.selectionSet.selections,
);

fields.push({
name: node.name.value,
subfields: subfields,
});
} else {
fields.push({
name: node.name.value,
});
}
});

return fields;
}

0 comments on commit 8337d37

Please sign in to comment.