GithubHelp home page GithubHelp logo

Comments (3)

CalMlynarczyk avatar CalMlynarczyk commented on July 30, 2024 8

I was able to get performance monitoring, including tracing, working on Sentry v7.31.1 using the below module configuration (thanks to @mahendradambe and their own Sentry/NestJS integration for pointing me in the right direction on how to inject the Express application object into the tracing integration).

Root Module (ex. AppModule)

SentryModule.forRootAsync({
  imports: [ConfigModule],
  inject: [ConfigService, HttpAdapterHost],
  useFactory: async (
    config: ConfigService,
    adapterHost: HttpAdapterHost,
  ) => ({
    dsn: "...",
    // ...
    integrations: [
      // ...,
      new Sentry.Integrations.Http({ tracing: true }),
      new Tracing.Integrations.Express({
        app: adapterHost.httpAdapter.getInstance(),
      }),
    ] as Integration[],
    tracesSampleRate: 1.0,
  }),
})

App Init

const app = await NestFactory.create<NestExpressApplication>(AppModule);

app.use(Sentry.Handlers.tracingHandler());

await app.listen(8080);

from nestjs-sentry.

mpx2m avatar mpx2m commented on July 30, 2024 4

here is some code, maybe help you

import { Plugin } from '@nestjs/apollo'
import { ApolloServerPlugin, GraphQLRequestListener } from 'apollo-server-plugin-base'
import { InjectSentry, SentryService } from '@ntegral/nestjs-sentry'
import { GraphQLRequestContext } from 'apollo-server-types'
import '@sentry/tracing'

/**
 * @document: https://develop.sentry.dev/sdk/event-payloads/request/
 * @document: https://github.com/ntegral/nestjs-sentry/issues/63
 * @document: https://www.apollographql.com/docs/apollo-server/integrations/plugins/
 * @document: https://blog.sentry.io/2021/08/31/guest-post-performance-monitoring-in-graphql
 * @document: https://github.com/getsentry/sentry-javascript/issues/4731
 */

@Plugin()
export class SentryPlugin implements ApolloServerPlugin {
  constructor(@InjectSentry() private readonly sentry: SentryService) {}

  async requestDidStart({ request, context }: GraphQLRequestContext): Promise<GraphQLRequestListener> {
    const transaction = this.sentry.instance().startTransaction({
      op: 'gql',
      name: request.operationName ? `graphql: ${request.operationName}` : 'GraphQLTransaction'
    })

    this.sentry
      .instance()
      .getCurrentHub()
      .configureScope(scope => {
        const { headers, body: data, method, baseUrl: url } = context.req
        scope.addEventProcessor(event => {
          event.request = { method, url, headers, data }
          return event
        })
      })

    this.sentry.instance().configureScope(scope => {
      scope.setSpan(transaction)
    })

    return {
      // hook for transaction finished
      async willSendResponse() {
        transaction.finish()
      },
      async executionDidStart() {
        return {
          // hook for each new resolver
          willResolveField({ info }) {
            const span = transaction.startChild({
              op: 'resolver',
              description: `${info.parentType.name}.${info.fieldName}`
            })
            // this will execute once the resolver is finished
            return () => {
              span.finish()
            }
          }
        }
      }
    }
  }
}

I update code to below to solve some problems of tracing overflow

@Plugin()
export class SentryPlugin implements ApolloServerPlugin {
  constructor(@InjectSentry() private readonly sentry: SentryService) {}

  async requestDidStart({ request, context }: GraphQLRequestContext): Promise<GraphQLRequestListener> {
    context.transaction = this.sentry.instance().startTransaction({
      op: 'gql',
      name: request.operationName ? `graphql: ${request.operationName}` : 'graphql: withoutOperationName'
    })

    this.sentry
      .instance()
      .getCurrentHub()
      .configureScope(scope => {
        scope.addEventProcessor(event => {
          const { headers, body: data, method, baseUrl: url } = context.req
          // eslint-disable-next-line no-param-reassign
          event.request = { method, url, headers, data }
          return event
        })
      })

    this.sentry.instance().configureScope(scope => {
      scope.setSpan(context.transaction)
    })

    return {
      // hook for transaction finished
      async willSendResponse({ context }) {
        context.transaction.finish()
      },
      async executionDidStart() {
        return {
          // hook for each new resolver
          willResolveField({ context, info }) {
            const span = context.transaction.startChild({
              op: 'resolver',
              description: `${info.parentType.name}.${info.fieldName}`
            })
            // this will execute once the resolver is finished
            return () => {
              span.finish()
            }
          }
        }
      }
    }
  }
}

from nestjs-sentry.

AdamGerthel avatar AdamGerthel commented on July 30, 2024 1

@CalMlynarczyk it seems your example has become outdated. Tracing.Integrations.Express is deprecated in @sentry/tracing. But even without that, it seems that only my first request to the server works after adding app.use(Sentry.Handlers.tracingHandler());. After that, the server stops responding to requests (but is still running). This is with @sentry/node running on ^6.13.3.

Are you using this sample still?

Update:

I got it working on @sentry/node 7.69.0 without using Tracing.Integrations.Express:

    SentryModule.forRoot({
      dsn: process.env.SENTRY_DSN,
      // ...
      integrations: [
        new Sentry.Integrations.Http({ tracing: true })
      ] as unknown as Integration[],
    }),

from nestjs-sentry.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.