hikky36
hikky36

Reputation: 335

How to log stacktrace on NestJS + GraphQL?

I'm trying out NestJS + GraphQL using Apollo underneath. When I set the Apollo 'debug' option to be true, I can see the stacktrace in the response but I cannot find a way to log this stacktrace in our application logs.

I would like to have it in the log to troubleshoot issues in production. Is there a way to do this?

Upvotes: 1

Views: 2174

Answers (2)

hikky36
hikky36

Reputation: 335

Here's the ApolloServerPlugin I use

import { Plugin } from '@nestjs/apollo';
import { Logger } from '@nestjs/common';
import {
  ApolloServerPlugin,
  GraphQLRequestListener,
} from 'apollo-server-plugin-base';
import {
  BaseContext,
  GraphQLRequestContext,
  GraphQLRequestContextWillSendResponse,
} from 'apollo-server-types';
import * as util from 'util';

@Plugin()
export class LoggingPlugin implements ApolloServerPlugin {
  constructor(private readonly logger: Logger) {}

  async requestDidStart(
    requestContext: GraphQLRequestContext,
  ): Promise<GraphQLRequestListener> {
    const thatLogger = this.logger;
    if (requestContext.request.operationName !== 'IntrospectionQuery') {
      thatLogger.log(
        `request query: ${requestContext.request.query || 'undefined'}`,
      );
    }
    return {
      async willSendResponse(
        requestContextWillSendResponse: GraphQLRequestContextWillSendResponse<BaseContext>,
      ): Promise<void> {
        if (
          requestContextWillSendResponse.request.operationName !==
          'IntrospectionQuery'
        ) {
          if (!requestContextWillSendResponse.errors) {
            thatLogger.log(`response without any errors`);
          } else {
            const errors = requestContextWillSendResponse.errors.concat();
            const responseErrors =
              requestContextWillSendResponse.response.errors?.concat();
            if (errors && responseErrors) {
              for (let i = 0; i < errors.length; i++) {
                const result = {
                  ...responseErrors[i],
                  stack: errors[i].stack,
                };
                if (result.extensions) {
                  delete result.extensions.exception;
                }
                if (
                  result.extensions &&
                  result.extensions.code !== 'INTERNAL_SERVER_ERROR'
                ) {
                  thatLogger.warn(
                    `response with errors: ${util.inspect(result, {
                      depth: 4,
                    })}`,
                  );
                } else {
                  thatLogger.error(
                    `response with errors: ${util.inspect(result, {
                      depth: 4,
                    })}`,
                  );
                }
              }
            }
          }
        }
      },
    };
  }
}

Upvotes: 2

hikky36
hikky36

Reputation: 335

I was able to do this using ApolloServerPlugin.

Upvotes: 0

Related Questions