sentry-javascript icon indicating copy to clipboard operation
sentry-javascript copied to clipboard

Unable to instrument Nestjs app when the Fastify Adapter is used

Open samuelgoldenbaum opened this issue 1 year ago • 5 comments

Is there an existing issue for this?

  • [x] I have checked for existing issues https://github.com/getsentry/sentry-javascript/issues
  • [x] I have reviewed the documentation https://docs.sentry.io/
  • [x] I am using the latest SDK release https://github.com/getsentry/sentry-javascript/releases

How do you use Sentry?

Sentry Saas (sentry.io)

Which SDK are you using?

@sentry/nestjs

SDK Version

8.26.0

Framework Version

@nestjs/platform-fastify ^10.4.1

Link to Sentry event

No response

Reproduction Example/SDK Setup

The following will not instrument...

const initSentry = (): Promise<void> => {
  return new Promise((resolve) => {
    Sentry.init({
      dsn: 'DSN,
      integrations: [nodeProfilingIntegration()],
      tracesSampleRate: 1.0,
      profilesSampleRate: 1.0
    });
    return resolve();
  });
};

async function bootstrap() {
  const app = await NestFactory.create<NestFastifyApplication>(
    AppModule,
    new FastifyAdapter()
  );

  await app.listen(3000);
}

initSentry().then(() => bootstrap());

But using Express will

const initSentry = (): Promise<void> => {
  return new Promise((resolve) => {
    Sentry.init({
      dsn: 'DSN',
      integrations: [nodeProfilingIntegration()],
      tracesSampleRate: 1.0,
      profilesSampleRate: 1.0
    });
    return resolve();
  });
};

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  await app.listen(3000);
}

initSentry().then(() => bootstrap());

Steps to Reproduce

Swap to the Fastify adapter:

  const app = await NestFactory.create<NestFastifyApplication>(
    AppModule,
    new FastifyAdapter()
  );

  await app.listen(3000);

Expected Result

Should instrument and show data in Performance tab

Actual Result

No instrumentation

samuelgoldenbaum avatar Aug 15 '24 03:08 samuelgoldenbaum

@samuelgoldenbaum thanks for writing in.

Could you add debug: true to your Sentry.init and share the sentry logs for the fastify setup?

AbhiPrasad avatar Aug 16 '24 02:08 AbhiPrasad

@samuelgoldenbaum thanks for writing in.

Could you add debug: true to your Sentry.init and share the sentry logs for the fastify setup?

Logs:

Sentry Logger [log]: Initializing Sentry: process: 40771, thread: main.
Sentry Logger [log]: Integration installed: InboundFilters
Sentry Logger [log]: Integration installed: FunctionToString
Sentry Logger [log]: Integration installed: LinkedErrors
Sentry Logger [log]: Integration installed: RequestData
Sentry Logger [log]: Integration installed: Console
Sentry Logger [log]: Integration installed: Http
Sentry Logger [log]: Integration installed: NodeFetch
Sentry Logger [log]: Integration installed: OnUncaughtException
Sentry Logger [log]: Integration installed: OnUnhandledRejection
Sentry Logger [log]: Integration installed: ContextLines
Sentry Logger [log]: Integration installed: LocalVariablesAsync
Sentry Logger [log]: Integration installed: Context
Sentry Logger [log]: Integration installed: Modules
Sentry Logger [log]: Integration installed: Express
Sentry Logger [log]: Integration installed: Fastify
Sentry Logger [log]: Integration installed: Graphql
Sentry Logger [log]: Integration installed: Mongo
Sentry Logger [log]: Integration installed: Mongoose
Sentry Logger [log]: Integration installed: Mysql
Sentry Logger [log]: Integration installed: Mysql2
Sentry Logger [log]: Integration installed: Redis
Sentry Logger [log]: Integration installed: Postgres
Sentry Logger [log]: Integration installed: Nest
Sentry Logger [log]: Integration installed: Hapi
Sentry Logger [log]: Integration installed: Koa
Sentry Logger [log]: Integration installed: Connect
Sentry Logger [log]: [Profiling] Profiling integration setup.
Sentry Logger [log]: [Profiling] Span profiler mode enabled.
Sentry Logger [log]: Integration installed: ProfilingIntegration
Sentry Logger [log]: Running in CommonJS mode.
Sentry Logger [debug]: @opentelemetry/api: Registered a global for diag v1.9.0.
Sentry Logger [debug]: @opentelemetry/api: Registered a global for trace v1.9.0.
Sentry Logger [debug]: @opentelemetry/api: Registered a global for context v1.9.0.
Sentry Logger [debug]: @opentelemetry/api: Registered a global for propagation v1.9.0.
[Nest] 40771  - 08/18/2024, 12:05:51 PM     LOG [NestFactory] Starting Nest application...
[Nest] 40771  - 08/18/2024, 12:05:51 PM     LOG [InstanceLoader] SentryModule dependencies initialized +6ms
[Nest] 40771  - 08/18/2024, 12:05:51 PM     LOG [InstanceLoader] AppModule dependencies initialized +1ms
[Nest] 40771  - 08/18/2024, 12:05:51 PM     LOG [RoutesResolver] AppController {/}: +1ms
[Nest] 40771  - 08/18/2024, 12:05:51 PM     LOG [RouterExplorer] Mapped {/, GET} route +2ms
[Nest] 40771  - 08/18/2024, 12:05:51 PM     LOG [RouterExplorer] Mapped {/debug-sentry, GET} route +0ms
[Nest] 40771  - 08/18/2024, 12:05:51 PM     LOG [NestApplication] Nest application successfully started +1ms
Sentry Logger [log]: Flushing client reports based on interval.
Sentry Logger [log]: Flushing outcomes...
Sentry Logger [log]: No outcomes to send
Sentry Logger [log]: Flushing client reports based on interval.
Sentry Logger [log]: Flushing outcomes...
Sentry Logger [log]: No outcomes to send

Implementation:

import 'dotenv/config'; // needed as we init Sentry before bootstrapping Nest
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

import * as Sentry from '@sentry/nestjs';
import { nodeProfilingIntegration } from '@sentry/profiling-node';
import {
  FastifyAdapter,
  NestFastifyApplication
} from '@nestjs/platform-fastify';

const initSentry = (): Promise<void> => {
  return new Promise((resolve) => {
    Sentry.init({
      dsn: process.env.SENTRY_DSN,
      integrations: [nodeProfilingIntegration()],
      tracesSampleRate: 1.0,
      profilesSampleRate: 1.0,
      debug: true
    });
    return resolve();
  });
};

async function bootstrap() {
  const app = await NestFactory.create<NestFastifyApplication>(
    AppModule,
    new FastifyAdapter()
  );

  await app.listen(3000);
}

initSentry().then(() => bootstrap());

package.json:

  "dependencies": {
    "@nestjs/common": "^10.0.0",
    "@nestjs/config": "^3.2.3",
    "@nestjs/core": "^10.0.0",
    "@nestjs/microservices": "^10.4.1",
    "@nestjs/platform-express": "^10.0.0",
    "@nestjs/platform-fastify": "^10.4.1",
    "@sentry/cli": "^2.33.1",
    "@sentry/nestjs": "^8.26.0",
    "@sentry/profiling-node": "^8.26.0",
    "reflect-metadata": "^0.2.0",
    "rxjs": "^7.8.1"
  }

samuelgoldenbaum avatar Aug 18 '24 22:08 samuelgoldenbaum

Hey @samuelgoldenbaum thanks for writing in!

We'll look into your issue next week as this week is Hackweek at Sentry (see #13421).

Lms24 avatar Aug 19 '24 09:08 Lms24

@samuelgoldenbaum can you try set up the SDK like it is recommended here: https://docs.sentry.io/platforms/javascript/guides/fastify/#configure

It might be the case that Sentry.init() is running too late and isn't able to patch the fastify imports. Thanks!

lforst avatar Aug 26 '24 08:08 lforst

Looks like I manage to make it work like this

  import * as Sentry from '@sentry/node';

  async function bootstrap() {
    const fastifyAdapter = new FastifyAdapter();
    Sentry.setupFastifyErrorHandler(fastifyAdapter.getInstance());
    const app = await NestFactory.create<NestFastifyApplication>(AppModule, fastifyAdapter);
  }

ctjhoa avatar Oct 14 '24 13:10 ctjhoa

closed by https://github.com/getsentry/sentry-javascript/pull/14549

chargome avatar Dec 10 '24 14:12 chargome