Code Monkey home page Code Monkey logo

nestjs-sentry's Introduction

npm version Codecov Coverage ISC license Donate

@ntegral/nestjs-sentry

Provides an injectable sentry.io client to provide enterprise logging nestjs modules

Table Of Contents

NestJS 10 Support

Version 4.x.x will support NestJS 10+. If you need support for older versions please see reference below. Thanks for you support!

NestJS 8 Support

Version 3.x.x will support NestJS 8+. If you need support for NestJS 7 please continue to use Version 2.x.x. Thanks for you support!

About

@ntegral/nestjs-sentry implements a module, SentryModule, which when imported into your nestjs project provides a Sentry.io client to any class that injects it. This lets Sentry.io be worked into your dependency injection workflow without having to do any extra work outside of the initial setup.

Installation

npm install --save @ntegral/nestjs-sentry @sentry/node

Github Sample Project using @ntegral/nestjs-sentry

The following project was created as a sample starter project to get you going... (if needed...).

Getting Started

The simplest way to use @ntegral/nestjs-sentry is to use SentryModule.forRoot

import { Module } from '@nestjs-common';
import { SentryModule } from '@ntegral/nestjs-sentry';

@Module({
  imports: [
    SentryModule.forRoot({
      dsn: 'sentry_io_dsn',
      debug: true | false,
      environment: 'dev' | 'production' | 'some_environment',
      release: 'some_release', | null, // must create a release in sentry.io dashboard
      logLevels: ['debug'] //based on sentry.io loglevel //
    }),
  ],
})
export class AppModule {}

The async way @ntegral/nestjs-sentry is to use SentryModule.forRootAsync

import { Module } from '@nestjs-common';
import { SentryModule } from '@ntegral/nestjs-sentry';
import { ConfigModule } from '@ntegral/nestjs-config';
import { ConfigService } from '@ntegral/nestjs-config';

@Module({
  imports: [
    SentryModule.forRootAsync({
      imports: [ConfigModule],
      useFactory: async (cfg:ConfigService) => ({
        dsn: cfg.get('SENTRY_DSN'),
        debug: true | false,
        environment: 'dev' | 'production' | 'some_environment',
        release: 'some_release', | null, // must create a release in sentry.io dashboard
        logLevels: ['debug'] //based on sentry.io loglevel //
      }),
      inject: [ConfigService],
    })
  ]
})

export class AppModule {}

You can then inject the Sentry client into any of your injectables by using a custom decorator

import { Injectable } from '@nestjs/common';
import { InjectSentry, SentryService } from '@ntegral/nestjs-sentry';

@Injectable()
export class AppService {
  public constructor(@InjectSentry() private readonly client: SentryService) {
      client.instance().captureMessage(message, Sentry.Severity.Log);
      client.instance().captureException(exception);
      ... and more
  }
}

You can instruct Nest to use the SentryService as the default logger:

async function bootstrap() {
  const app = await NestFactory.create(AppModule, { logger: false });

  app.useLogger(SentryService.SentryServiceInstance());
  await app.listen(3000);
}
bootstrap();

You can instuct use the SentryService to log non-error messages as breadcrumbs or use the native Sentry.addBreadcrumb method.

import { Injectable } from '@nestjs/common';
import { InjectSentry, SentryService } from '@ntegral/nestjs-sentry';

@Injectable()
export class AppService {
  constructor(@InjectSentry() private readonly client: SentryService) {
    client.log('AppSevice Loaded','test', true); // creates log asBreadcrumb //
    client.instance().addBreadcrumb({level: 'debug' , message: 'How to use native breadcrumb', data: { context: 'WhatEver'}})
    client.debug('AppService Debug', 'context');
  }
  getHello(): string {
    return 'Hello World!';
  }
}

Interceptors

BREAKING CHANGES: The SentryInterceptor can be used in projects that don't require GraphQL. If you will be needed GraphQL support, use the GraphqlInterceptor. Using the GraphqlInterceptor will create a dependancy for the @nestjs/graphql package.

npm install --save @nestjs/graphql

Using graphql interceptor globally

import { Module } from '@nestjs/common';
import { APP_INTERCEPTOR } from '@nestjs/core';
import { GraphqlInterceptor } from '@ntegral/nestjs-sentry';

@Module({
  ....
  providers: [
    {
      provide: APP_INTERCEPTOR,
      useFactory: () => new GraphqlInterceptor(),
    },
  ],
})
export class AppModule {}

Using the sentry interceptor globally

import { Module } from '@nestjs/common';
import { APP_INTERCEPTOR } from '@nestjs/core';
import { SentryInterceptor } from '@ntegral/nestjs-sentry';

@Module({
  ....
  providers: [
    {
      provide: APP_INTERCEPTOR,
      useFactory: () => new SentryInterceptor({
        filters: [{
          type: HttpException,
          filter: (exception: HttpException) => 500 > exception.getStatus() // Only report 500 errors
        }]
      }),
    }
  ],
})
export class AppModule {}

Flushing sentry

Sentry does not flush all the errors by itself, it does it in background so that it doesn't block the main thread. If you kill the nestjs app forcefully some exceptions have to be flushed and logged successfully.

If you want to force that behaviour use the close flag in your options. That is handy if using nestjs as a console runner. Keep in mind that you need to have app.enableShutdownHooks(); enabled in order for closing (flushing) to work.

import { Module } from '@nestjs-common';
import { SentryModule } from '@ntegral/nestjs-sentry';

@Module({
  imports: [
    SentryModule.forRoot({
      dsn: 'sentry_io_dsn',
      debug: true | false,
      environment: 'dev' | 'production' | 'some_environment',
      release: 'some_release', | null, // must create a release in sentry.io dashboard
      logLevels: ['debug'] //based on sentry.io loglevel //
      close: {
        enabled: true,
        // Time in milliseconds to forcefully quit the application  
        timeout?: number,  
      }
    }),
  ],
})
export class AppModule {}

Contributing

I would greatly appreciate any contributions to make this project better. Please make sure to follow the below guidelines before getting your hands dirty.

  1. Fork the repository
  2. Create your branch (git checkout -b my-branch)
  3. Commit any changes to your branch
  4. Push your changes to your remote branch
  5. Open a pull request

License

Distributed under the ISC License. See LICENSE for more information.

Acknowledgements

Copyright © 2019 Ntegral Inc.

nestjs-sentry's People

Contributors

dependabot[bot] avatar hardydex avatar hileomsi avatar holm avatar juzerali avatar ntegral avatar reastyn avatar swift-nicholas avatar uptownhr avatar vpanwar821 avatar xiifain avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

nestjs-sentry's Issues

The process exit before sending event to sentry

I don't see any events on my sentry dashboard.

My AppModule looks like follow (after 2 seconds when app started it generated a test exception):
image

Dashboard still empty:
image

But I think I have found a cause.
When I go to compiled code, and then comment line with process.exit(1); (https://github.com/ntegral/nestjs-sentry/blob/master/dist/services/sentry.service.js#L52) (on src code: https://github.com/ntegral/nestjs-sentry/blob/master/lib/services/sentry.service.ts#L35)

it started working. I saw event on dashboard:
image

I have one conclusion, process was closed too fast, without waiting for succeed emitting event.
Any other idea?

Typo in Graphql Interceptor

with the commit 2dbdd79 there seems to be a type for the import:

({ GqlExecutionContxt } = require('@nestjs/graphql'));

instead of GqlExecutionContxt I think it should be GqlExecutionContext

Sentry module does't capture errors

I imported to my app module

SentryModule.forRootAsync({
      imports: [ConfigModule],
      useFactory: async (cfg: ConfigService) => ({
        dsn: cfg.sentryDns,
        debug: true,
        enabled: true,
        environment: cfg.nodeEnv,
        tracesSampleRate: 1.0,
        release: cfg.version
      }),
      inject: [ConfigService],
    })

"@ntegral/nestjs-sentry": "2.0.6",
"@sentry/node": "6.2.3",

And also try add in main.ts app.useGlobalInterceptors(new SentryInterceptor()).

But any exption doesen’t catch in sentry.
Erorrs catch if I init sentry in main.ts and throw error in mian.ts bootsrap function after init sentry;

If I try to add to app controller @UseInterceptors(new SentryInterceptor())
Its catch only like that, how I understand sentry must by default catch any 500 errors and upper.

Wrong documentation ?

README.md show client.captureMessage(..), while there is no method called captureMessage on SentryService.ts but this method can accessed through client.instance().captureMessage()

Sentry.init beforeSend option is not being executed

We have an app where we need the ability to manipulate payloads before being sent to sentry. It doesn't appear that the beforeSend .init option is respected when instantiating via forRootAsync

  Sentry.init({
    dsn: config.get('SENTRY_DSN'),
    environment: config.get('NODE_ENV'),
    beforeSend(event) {
      if (event.secret_info)) {
        delete event.secret_info;
      }
      return event;
    }
  });

Error: Cannot find module 'graphql'

Package ask for graphql to be installed even if it's an optionalDependency
"@ntegral/nestjs-sentry": "^2.0.6"

internal/modules/cjs/loader.js:888
  throw err;
  ^

Error: Cannot find module 'graphql'
Require stack:
- /home/adrian/code/posterlab-mvp/nest-backend/node_modules/@nestjs/graphql/dist/decorators/directive.decorator.js
- /home/adrian/code/posterlab-mvp/nest-backend/node_modules/@nestjs/graphql/dist/decorators/index.js
- /home/adrian/code/posterlab-mvp/nest-backend/node_modules/@nestjs/graphql/dist/index.js
- /home/adrian/code/posterlab-mvp/nest-backend/node_modules/@nestjs/graphql/index.js
- /home/adrian/code/posterlab-mvp/nest-backend/node_modules/@ntegral/nestjs-sentry/dist/graphql.interceptor.js
- /home/adrian/code/posterlab-mvp/nest-backend/node_modules/@ntegral/nestjs-sentry/dist/index.js
- /home/adrian/code/posterlab-mvp/nest-backend/dist/src/app.module.js
- /home/adrian/code/posterlab-mvp/nest-backend/dist/src/main.js
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:885:15)
    at Function.Module._resolveFilename (/home/adrian/code/posterlab-mvp/nest-backend/node_modules/module-alias/index.js:49:29)
    at Function.Module._load (internal/modules/cjs/loader.js:730:27)
    at Module.require (internal/modules/cjs/loader.js:957:19)
    at require (internal/modules/cjs/helpers.js:88:18)
    at Object.<anonymous> (/home/adrian/code/posterlab-mvp/nest-backend/node_modules/@nestjs/graphql/dist/decorators/directive.decorator.js:4:19)
    at Module._compile (internal/modules/cjs/loader.js:1068:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1097:10)
    at Module.load (internal/modules/cjs/loader.js:933:32)
    at Function.Module._load (internal/modules/cjs/loader.js:774:14) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [
    '/home/adrian/code/posterlab-mvp/nest-backend/node_modules/@nestjs/graphql/dist/decorators/directive.decorator.js',
    '/home/adrian/code/posterlab-mvp/nest-backend/node_modules/@nestjs/graphql/dist/decorators/index.js',
    '/home/adrian/code/posterlab-mvp/nest-backend/node_modules/@nestjs/graphql/dist/index.js',
    '/home/adrian/code/posterlab-mvp/nest-backend/node_modules/@nestjs/graphql/index.js',
    '/home/adrian/code/posterlab-mvp/nest-backend/node_modules/@ntegral/nestjs-sentry/dist/graphql.interceptor.js',
    '/home/adrian/code/posterlab-mvp/nest-backend/node_modules/@ntegral/nestjs-sentry/dist/index.js',
    '/home/adrian/code/posterlab-mvp/nest-backend/dist/src/app.module.js',
    '/home/adrian/code/posterlab-mvp/nest-backend/dist/src/main.js'
  ]
}

Error: Cannot find module 'graphql' (is graphql mandatory?)

I installed nestjs-sentry package, but it seems that graphql is a mandatory package to have as a dependency.
I've seen in the README something about Interceptors but I'm not sure if I understood it.

app.module.ts

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AuthModule } from './auth/auth.module';
import { UsersModule } from './users/users.module';
import { TypeOrmModule } from '@nestjs/typeorm';
import { getConnectionOptions } from 'typeorm';
import { LevelsModule } from './levels/levels.module';
import { MoviesModule } from './movies/movies.module';
import { LevelsQuotesModule } from './levels-quotes/levels-quotes.module';
import { UsersProgressesModule } from './users-progresses/users-progresses.module';
import { ProductsModule } from './products/products.module';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { LeaderboardsModule } from './leaderboards/leaderboards.module';
import { SentryModule } from '@ntegral/nestjs-sentry';
import { LogLevel } from '@sentry/types';

@Module({
  imports: [
    SentryModule.forRootAsync({
      imports: [ConfigModule],
      useFactory: async (cfg: ConfigService) => ({
        dsn: cfg.get('SENTRY_DSN'),
        debug: false,
        environment: process.env.NODE_ENV,
        release: null, // must create a release in sentry.io dashboard
        logLevel: LogLevel.Debug, //based on sentry.io loglevel //
      }),
      inject: [ConfigService],
    }),
    ConfigModule.forRoot(),
    TypeOrmModule.forRootAsync({
      useFactory: async () =>
        Object.assign(await getConnectionOptions(), {
          autoLoadEntities: true,
        }),
    }),
    AuthModule,
    UsersModule,
    LevelsModule,
    MoviesModule,
    LevelsQuotesModule,
    UsersProgressesModule,
    ProductsModule,
    LeaderboardsModule,
  ],
  controllers: [AppController],
})
export class AppModule {}

logs

[18:58:29] Found 0 errors. Watching for file changes.

internal/modules/cjs/loader.js:775
    throw err;
    ^

Error: Cannot find module 'graphql'
Require stack:
- C:\Users\Jeremy\www\memorable-nest-api\node_modules\@nestjs\graphql\dist\decorators\directive.decorator.js
- C:\Users\Jeremy\www\memorable-nest-api\node_modules\@nestjs\graphql\dist\decorators\index.js
- C:\Users\Jeremy\www\memorable-nest-api\node_modules\@nestjs\graphql\dist\index.js
- C:\Users\Jeremy\www\memorable-nest-api\node_modules\@nestjs\graphql\index.js
- C:\Users\Jeremy\www\memorable-nest-api\node_modules\@ntegral\nestjs-sentry\dist\graphql.interceptor.js
- C:\Users\Jeremy\www\memorable-nest-api\node_modules\@ntegral\nestjs-sentry\dist\index.js
- C:\Users\Jeremy\www\memorable-nest-api\dist\app.module.js
- C:\Users\Jeremy\www\memorable-nest-api\dist\main.js
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:772:15)
    at Function.Module._load (internal/modules/cjs/loader.js:677:27)
    at Module.require (internal/modules/cjs/loader.js:830:19)
    at require (internal/modules/cjs/helpers.js:68:18)
    at Object.<anonymous> (C:\Users\Jeremy\www\memorable-nest-api\node_modules\@nestjs\graphql\dist\decorators\directive.
decorator.js:4:19)
    at Module._compile (internal/modules/cjs/loader.js:936:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:947:10)
    at Module.load (internal/modules/cjs/loader.js:790:32)
    at Function.Module._load (internal/modules/cjs/loader.js:703:12)
    at Module.require (internal/modules/cjs/loader.js:830:19) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [
    'C:\\Users\\Jeremy\\www\\memorable-nest-api\\node_modules\\@nestjs\\graphql\\dist\\decorators\\directive.decorator.js
',
    'C:\\Users\\Jeremy\\www\\memorable-nest-api\\node_modules\\@nestjs\\graphql\\dist\\decorators\\index.js',
    'C:\\Users\\Jeremy\\www\\memorable-nest-api\\node_modules\\@nestjs\\graphql\\dist\\index.js',
    'C:\\Users\\Jeremy\\www\\memorable-nest-api\\node_modules\\@nestjs\\graphql\\index.js',
    'C:\\Users\\Jeremy\\www\\memorable-nest-api\\node_modules\\@ntegral\\nestjs-sentry\\dist\\graphql.interceptor.js',
    'C:\\Users\\Jeremy\\www\\memorable-nest-api\\node_modules\\@ntegral\\nestjs-sentry\\dist\\index.js',
    'C:\\Users\\Jeremy\\www\\memorable-nest-api\\dist\\app.module.js',
    'C:\\Users\\Jeremy\\www\\memorable-nest-api\\dist\\main.js'
  ]
}
package.json
{
  "name": "memorable-nest-api",
  "version": "0.0.1",
  "description": "",
  "author": "",
  "private": true,
  "license": "UNLICENSED",
  "scripts": {
    "prebuild": "rimraf dist",
    "build": "nest build",
    "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
    "start": "nest start",
    "start:dev": "nest start --watch",
    "start:debug": "nest start --debug --watch",
    "start:prod": "node dist/main",
    "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
    "test": "jest",
    "test:watch": "jest --watch",
    "test:cov": "jest --coverage",
    "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
    "test:e2e": "jest --config ./test/jest-e2e.json"
  },
  "dependencies": {
    "@nestjs/common": "^7.6.13",
    "@nestjs/config": "^0.6.3",
    "@nestjs/core": "^7.6.13",
    "@nestjs/jwt": "^7.2.0",
    "@nestjs/passport": "^7.1.5",
    "@nestjs/platform-express": "^7.6.13",
    "@nestjs/swagger": "^4.8.0",
    "@nestjs/typeorm": "^7.1.5",
    "@nestjsx/crud": "^5.0.0-alpha.3",
    "@nestjsx/crud-typeorm": "^5.0.0-alpha.3",
    "@ntegral/nestjs-sentry": "^2.0.6",
    "@sentry/node": "^6.2.3",
    "@types/node-fetch": "^2.5.8",
    "class-transformer": "^0.4.0",
    "class-validator": "^0.13.1",
    "google-auth-library": "^7.0.2",
    "http-status-codes": "^2.1.4",
    "mysql2": "^2.2.5",
    "passport": "^0.4.1",
    "passport-jwt": "^4.0.0",
    "passport-local": "^1.0.0",
    "reflect-metadata": "^0.1.13",
    "rimraf": "^3.0.2",
    "rxjs": "^6.6.6",
    "typeorm": "^0.2.31"
  },
  "devDependencies": {
    "@nestjs/cli": "^7.5.6",
    "@nestjs/schematics": "^7.2.7",
    "@nestjs/testing": "^7.6.13",
    "@types/express": "^4.17.11",
    "@types/jest": "^26.0.20",
    "@types/node": "^14.14.31",
    "@types/passport-jwt": "^3.0.5",
    "@types/passport-local": "^1.0.33",
    "@types/supertest": "^2.0.10",
    "@typescript-eslint/eslint-plugin": "^4.15.2",
    "@typescript-eslint/parser": "^4.15.2",
    "eslint": "^7.20.0",
    "eslint-config-prettier": "^8.1.0",
    "eslint-plugin-prettier": "^3.3.1",
    "jest": "^26.6.3",
    "prettier": "^2.2.1",
    "supertest": "^6.1.3",
    "ts-jest": "^26.5.2",
    "ts-loader": "^8.0.17",
    "ts-node": "^9.1.1",
    "tsconfig-paths": "^3.9.0",
    "typescript": "^4.1.5"
  },
  "jest": {
    "moduleFileExtensions": [
      "js",
      "json",
      "ts"
    ],
    "rootDir": "src",
    "testRegex": ".*\\.spec\\.ts$",
    "transform": {
      "^.+\\.(t|j)s$": "ts-jest"
    },
    "collectCoverageFrom": [
      "**/*.(t|j)s"
    ],
    "coverageDirectory": "../coverage",
    "testEnvironment": "node"
  }
}

Feature request: implement `enabled` option

Hello there!

Thanks for the amazing package, we are using it right now and loving it !

I just have a small request, as of now, @sentry/node implements an option enabled which will indicate if sentry should report errors to the platform.

This will allow for quick disabling Sentry on dev environment for example.

If the request is approuve, I can work on a PR to implement this.

Thanks !

[bug]: Sentry does not capture exceptions

Input Code?

I'm trying to configure Sentry for nestjs application.
I do not want to handle errors manually by using ::captureException.
Instead, I want to send all my uncaught errors to the sentry.

@Module({
  imports: [
    SentryModule.forRootAsync({
      imports: [ConfigModule],
      useFactory: function (configService: ConfigService) {
        return {
          dsn: configService.get<string>('SENTRY_DSN'),
          environment: process.env.NODE_ENV,
        };
      },
      inject: [ConfigService],
    }),
    ConfigModule.forRoot({ isGlobal: true }),
  ],
})
export class AppModule implements OnApplicationBootstrap {
  onApplicationBootstrap(): never {
    setTimeout(() => {
      throw new Error('Test error');
    }, 0);
  }
}

Current and expected behavior

Current: Command failed with exit code 1 with no exception sent to sentry
Expected: Command failed with exit code 1 and exception sent to sentry

Environment

  • @nestjs/core: 8.2.5
  • @nestjs/common: 8.2.5
  • @nestjs/config: 1.1.6
  • @ntegral/nestjs-sentry: 3.0.7

Node version — 16.13.1

Possible solution

We need to flush the sentry and wait before we terminate the process.

// lib/sentry.service.ts
  (Sentry.getCurrentHub().getClient<Client<Options>>() as Client<Options>).captureException(err);
  await Sentry.flush(); // <----- flush here
  process.exit(1);

Err during installation

Hi,
I have followed the documentation, I am getting following err during startup,

src/app.module.ts:52:3 - error TS2345: Argument of type '{ imports: (DynamicModule | typeof QueryModule)[]; controllers: (typeof AppController)[]; providers: (typeof AppService)[]; SentryModule: typeof SentryModule; "": any; }' is not assignable to parameter of type 'ModuleMetadata'. Object literal may only specify known properties, and 'SentryModule' does not exist in type 'ModuleMetadata'.

Catch GraphQL Errors

Currently the interceptor ignores errors if the context is "graphql"

https://github.com/ntegral/nestjs-sentry/blob/master/lib/services/sentry.interceptor.ts#L25

Something like this should work:

              case 'graphql':
                return this.captureGraphqlException(
                  scope, 
                  GqlExecutionContext.create(context), 
                  exception
                );
  private captureGraphqlException(scope: Scope, gqlContext: GqlExecutionContext, exception: any): void {
    const info = gqlContext.getInfo()
    const context = gqlContext.getContext() 

    scope.setExtra('type', info.parentType.name)

    if (context.req) {
      // req within graphql context needs modification in 
      const data = Handlers.parseRequest(<any>{} context.req, this.options);

      scope.setExtra('req', data.request);

      data.extra && scope.setExtras(data.extra);
      if (data.user) scope.setUser(data.user);
   }

    this.captureException(scope, exception);
  }

Question - How to use this package with Nest js rabbit mq microservices

I have added the Sentry module in app.module.ts,

But even if I manually throw error it does not get logged in sentry

SentryModule.forRootAsync({
imports: [ConfigModule],
useFactory: async (configService: ConfigService) => ({
dsn: configService.get('SENTRY_DSN_BACKGROUND'),
debug: configService.get('NODE_ENV') !== 'production',
environment: configService.get('NODE_ENV'),
release: configService.get('RELEASE'),
logLevel: LogLevel.Error,
tracesSampleRate: 0.5,
}),
inject: [ConfigService],
}),

Logging messages to Sentry via standard console

Hey ya, probably Im missing something, but I'm wondering if it is possible to send error console logs to Sentry out of the box?

I figured, I can probably do a wrapper, but I wonder if there is a way without it?

Thank you.

Question - Support for traces?

While trying to set up integrations for the traces, I found that integrations keys are omitted from the module options. Or am I missing something?

Can't import SentryInterceptor

It looks like there may be an issue with the version 1.0.4 release / build.

Based on lib/services/index.ts#L2 I would expect to be able to import SentryInterceptor:

import { SentryInterceptor } from '@ntegral/nestjs-sentry';

However this fails. Inspecting the dist I noticed that SentryInterceptor is not exported from dist/services/index.js

I have re-built the dist locally and the SentryInterceptor can then be imported ands works as expected.

I am not sure if it is a release issue, but would it be possible to create a new version with the SentryInterceptor exported.

Nest can't resolve dependencies of the TestController (SentryToken, ?)

Hi, I face, this issue when trying to setup Sentry for my Nestjs project:

Nest can't resolve dependencies of the TestController (SentryToken, ?)

The source code I used:

@Module({
  imports: [
    ConfigModule.forRoot(),
    MongooseModule.forRootAsync({
      imports: [ConfigModule],
      useFactory: (config: ConfigService) => {
        return { uri: config.get<string>('MONGODB_URI') };
      },
      inject: [ConfigService],
    }),
    MongooseModule.forFeature([{ name: TestModel.name, schema: TestSchema }]),
    SentryModule.forRootAsync({
      imports: [ConfigModule],
      useFactory: (config: ConfigService) => {
        return {
          dsn: config.get<string>('SENTRY_DSN_WORKER'),
          release: config.get<string>('VERSION'),
          environment: config.get<string>('NODE_ENV'),
        };
      },
      inject: [ConfigService],
    }),
  ],
  controllers: [TestController],
  providers: [TestService],
})
export class TestModule {}

options not found. Did you use SentryModule.forRoot?

Hi,

I'm using version 2.x because I have Nest 7.x

Everything seems to be working (logs are sending to sentry and local debug works) but I am curious about this console log I am getting ("options not found. Did you use SentryModule.forRoot?"). I noticed that in 3.x this log was commented out (shown below). Should I be concerned that the service isn't being initialized correctly?

Thanks for the awesome library!

3.x:

export class SentryService extends ConsoleLogger {
  app = '@ntegral/nestjs-sentry: ';
  private static serviceInstance: SentryService;
  constructor(
    @Inject(SENTRY_MODULE_OPTIONS)
    readonly opts?: SentryModuleOptions,
  ) {
    super();
    if (!(opts && opts.dsn)) {
      // console.log('options not found. Did you use SentryModule.forRoot?');
      return;
    }

2.x:

export class SentryService extends Logger {
  app: string = '@ntegral/nestjs-sentry: ';
  private static serviceInstance: SentryService;
  constructor(
    @Inject(SENTRY_MODULE_OPTIONS)
    private readonly options?: SentryModuleOptions,
    @Optional() prior?: SentryService
  ) {
    super();
    if (!(options && options.dsn)) {
      console.log('options not found. Did you use SentryModule.forRoot?');
      return;
    }

For reference, here is how I am importing:

SentryModule.forRootAsync({
  imports: [ConfigModule],
  useFactory: async (config: ConfigService) => {
    return {
      dsn: config.get('SENTRY_DSN'),
      debug: true,
      environment: 'development',
      logLevel: LogLevel.Error
    }
  },
  inject: [ConfigService],
}),

^ made sure sentry dsn is set correctly

and my bootstrap (not sure this is relevant):

async function bootstrap() {
  const app = await NestFactory.create(AppModule, {
    logger: false
  });
  app.useLogger(SentryService.SentryServiceInstance());
  await app.listen(3000);
}
bootstrap();

Unable to resolve signature of property decorator when called as an expression

The following code generates the error "Unable to resolve signature of property decorator when called as an expression" from InjectSentry()

import { Catch, ArgumentsHost } from '@nestjs/common'
import { BaseExceptionFilter } from '@nestjs/core'
import { InjectSentry, SentryService } from '@ntegral/nestjs-sentry'

@Catch()
export class AllExceptionsFilter extends BaseExceptionFilter {
    @InjectSentry() private readonly sentry: SentryService

    catch(exception: unknown, host: ArgumentsHost): void {
        const Sentry = this.sentry.instance()

        Sentry.captureException(exception)

        super.catch(exception, host)
    }
}

Question - Globally enable sentry in whole app without adding interceptor or injectables

I am already using sentry with ReactJs and it is working great with my project. All errors are logging in Sentry dashboard globally without doing anything special or any 3rd party logging in entire application manually.

I am trying to implement the same feature globally by just adding the package's settings in AppModule,

SentryModule.forRoot({
		dsn: envConfig.SENTRY_DSN,
		debug: true,
		environment: currentEnv,
		release: null, // must create a release in sentry.io dashboard
		logLevel: LogLevel.Debug //based on sentry.io loglevel 
}),

This is not working properly even when all settings are correct.

Base Errors are not captured

When throwing an error that is other than, http, rpc, or ws no exception is captured. For example if I bootstrap the app and call a service, i.e. for a background task, per the docs https://docs.nestjs.com/standalone-applications

const app = await NestFactory.create(AppModule);
app.get(MyService).doSomething();

Reviewing the code here https://github.com/ntegral/nestjs-sentry/blob/master/lib/services/sentry.interceptor.ts#L18 I see that there is case logic that has no fallback to handle ordinary node.js errors. Again these errors might occur when services are called outside the context of an http request, like a background task so would be good to call captureException as a default https://github.com/ntegral/nestjs-sentry/blob/master/lib/services/sentry.interceptor.ts#L81

Perhaps this is a limitation of NestJs interceptor error handling and regular Errors are not caught?

Side bar, and not related would be nice to have an AWSLambda integration that is compatible with your module or at least an option to flush immediately. As the default sentry plugin does not work on AWS because it must flush.

Sentry.captureException(error);
Sentry.flush();

TypeError: Class extends value undefined is not a constructor or null

I have used the SentryModule.forRoot example as mentioned in the readme file.

Error logs:

let SentryService = SentryService_1 = class SentryService extends common_1.ConsoleLogger {
TypeError: Class extends value undefined is not a constructor or null                                                                                                                            
at Object.<anonymous> (C:\project\server\node_modules\@ntegral\nestjs-sentry\dist\sentry.service.js:39:76)
at Module._compile (internal/modules/cjs/loader.js:1138:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1158:10)
at Module.load (internal/modules/cjs/loader.js:986:32)
at Function.Module._load (internal/modules/cjs/loader.js:879:14)
at Module.require (internal/modules/cjs/loader.js:1026:19)
at require (internal/modules/cjs/helpers.js:72:18)
at Object.<anonymous> (C:\project\server\node_modules\@ntegral\nestjs-sentry\dist\sentry-core.module.js:21:26)
at Module._compile (internal/modules/cjs/loader.js:1138:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1158:10)

Versions:

    "@nestjs/common": "6.5.3",
    "@nestjs/core": "6.5.3",
    "@nestjs/jwt": "6.1.1",
    "@nestjs/passport": "6.1.0",
    "@nestjs/platform-express": "6.5.3",
    "@nestjs/serve-static": "^2.1.3",
    "@nestjs/swagger": "3.1.0",
    "@nestjs/typeorm": "6.1.3",
    "@ntegral/nestjs-sentry": "^3.0.3",
    "@sentry/node": "^6.10.0",
    "@sentry/tracing": "^6.10.0",
    "node": "12.18.0"

Please suggest a workaround/way forward.

[Feature Request] Allow to disable console logging or allow to provide custom logger

Hey!

In my Nest project I have a custom Logger implementation which is optimized for SumoLogic format. In case of errors I use my logger to print logs and @ntegral/nestjs-sentry to send error to Sentry. The problem is that lib by default also prints logs in default Nest format because of SentryService extends ConsoleLogger.

I would to have an ability to disable that default behaviour in order to keep my logs clean and without duplication.

Or, as another solution, would be great to have an ability to provide own custom logger to @ntegral/nestjs-sentry.

What do you think about that?

don`t work without graphql

internal/modules/cjs/loader.js:818
throw err;
^

Error: Cannot find module 'graphql'
Require stack:

  • /dist/node_modules/@nestjs/graphql/dist/decorators/directive.decorator.js
  • /dist/node_modules/@nestjs/graphql/dist/decorators/index.js
  • /dist/node_modules/@nestjs/graphql/dist/index.js
  • /dist/node_modules/@nestjs/graphql/index.js
  • /dist/node_modules/@ntegral/nestjs-sentry/dist/sentry.interceptor.js
  • /dist/node_modules/@ntegral/nestjs-sentry/dist/index.js
  • /dist/main.js
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:815:15)
    at Function.Module._load (internal/modules/cjs/loader.js:667:27)
    at Module.require (internal/modules/cjs/loader.js:887:19)
    at require (internal/modules/cjs/helpers.js:74:18)
    at Object. (/dist/node_modules/@nestjs/graphql/dist/decorators/directive.decorator.js:4:19)
    at Module._compile (internal/modules/cjs/loader.js:999:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)
    at Module.load (internal/modules/cjs/loader.js:863:32)
    at Function.Module._load (internal/modules/cjs/loader.js:708:14)
    at Module.require (internal/modules/cjs/loader.js:887:19)
    at require (internal/modules/cjs/helpers.js:74:18)
    at Object. (/dist/node_modules/@nestjs/graphql/dist/decorators/index.js:7:22)
    at Module._compile (internal/modules/cjs/loader.js:999:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)
    at Module.load (internal/modules/cjs/loader.js:863:32)
    at Function.Module._load (internal/modules/cjs/loader.js:708:14) {
    code: 'MODULE_NOT_FOUND',
    requireStack: [
    '/dist/node_modules/@nestjs/graphql/dist/decorators/directive.decorator.js',
    '/dist/node_modules/@nestjs/graphql/dist/decorators/index.js',
    '/dist/node_modules/@nestjs/graphql/dist/index.js',
    '/dist/node_modules/@nestjs/graphql/index.js',
    '/dist/node_modules/@ntegral/nestjs-sentry/dist/sentry.interceptor.js',
    '/dist/node_modules/@ntegral/nestjs-sentry/dist/index.js',
    '/dist/main.js'
    ]

Logger implementation should log non-error messages as breadcrumbs.

The default behaviour of any Sentry SDK is to capture non-error logs as breadcrumbs and send them all together as soon as an error happens.

I see SentryService extends Logger but the methods log, debug, verbose and warn are actually calling captureMessage and I think they should be storing that log as a breadcrumb in the current scope.

This way, replacing the default NestJS logger with this library would be a no-brainer and we'd get proper log messages before an exception on Sentry.

logLevel options doesn't seem to do anything

I set logLevel to LogLevel.Error and used SentryService as my logger.
Expected: Only when logging messages using logger.error will the messages be sent to sentry.
Actual: Log messages of all levels reach sentry.
You can easily see that logLevel isn't being used anywhere in the code if you search this repo

SentryInterceptor can not resolve dependencies

Hey,
I have imported the SentryInterceptor and wanted to use it on my controllers.

import { SentryInterceptor } from '@ntegral/nestjs-sentry';


@UseInterceptors(SentryInterceptor)
@Controller()
export class MyController {}

Although, Sentry throws the following error:

Nest can't resolve dependencies of the SentryInterceptor (SentryToken, ?). Please make sure that the argument Object at index [1] is available in the AppModule context

I have tried to put the SentryInterceptor as a provider, but no luck.

Uniform license information

I find it confusing that the license information on the README.md are set as MIT and in the package.json as ISC.

Please update the information and provide a license file.

Nest can't resolve dependencies of the GraphqlInterceptor (?)

Are there better instructions on how I should be loading in other dependencies for the providers sample code in the README.md to work?

image

Adding in the providers with APP_INTERCEPTOR for GraphqlInterceptor results in

ERROR [ExceptionHandler] Nest can't resolve dependencies of the GraphqlInterceptor (?). Please make sure that the argument Object at index [0] is available in the AppModule context.

Potential solutions:
- If Object is a provider, is it part of the current AppModule?
- If Object is exported from a separate @Module, is that module imported within AppModule?
  @Module({
    imports: [ /* the Module containing Object */ ]
  })

How to use this in middleware?

Currently I have middleware that read X-Request-ID header passed to our nestjs service or generate a new one if it's not found, I want to set request_id tag in Sentry, but how can I expose this into the middleware?

The code from Sentry docs sample

Sentry.configureScope((scope) => {
  scope.setTag("request_id", requestId);
});

Errors when using v3.0.3

Hello,

I was trying to use this package to connect to sentry but I'm having this error.

node_modules/@ntegral/nestjs-sentry/dist/sentry.interfaces.d.ts:4:10 - error TS2305: Module '"../../../@nestjs/common"' has no exported member 'ConsoleLoggerOptions'.

4 import { ConsoleLoggerOptions } from "@nestjs/common";
           ~~~~~~~~~~~~~~~~~~~~

node_modules/@ntegral/nestjs-sentry/dist/sentry.service.d.ts:1:10 - error TS2305: Module '"../../../@nestjs/common"' has no exported member 'ConsoleLogger'.

1 import { ConsoleLogger } from '@nestjs/common';

Im using the following versions on package.json

"@ntegral/nestjs-sentry": "^3.0.3",
 "@nestjs/common": "^7.6.18",
 "@nestjs/config": "^0.6.3",
 "@nestjs/core": "^7.6.18",

Am I missing something?

node_modules/@ntegral/nestjs-sentry/dist/sentry.service.d.ts:1:10 - error TS2305: Module '"@nestjs/common"' has no exported member 'ConsoleLogger'.

after install and configure like this:

imports: [
SentryModule.forRoot({
dsn: 'sentry_io_dsn',
debug: true | false,
environment: 'dev' | 'production' | 'some_environment',
release: 'some_release', | null, // must create a release in sentry.io dashboard
logLevel: LogLevel.Debug //based on sentry.io loglevel //
}),
],

Obs: i change the values to my need...

return 2 errors:

node_modules/@ntegral/nestjs-sentry/dist/sentry.interfaces.d.ts:4:10 - error TS2305: Module '"@nestjs/common"' has no exported member 'ConsoleLoggerOptions'.

and

node_modules/@ntegral/nestjs-sentry/dist/sentry.service.d.ts:1:10 - error TS2305: Module '"@nestjs/common"' has no exported member 'ConsoleLogger'.

Can you create a sample project where this is working?

Tried to integrate this and ran into all sorts of issues based on the directions in the readme.
LogLevel is not defined in your example syntax
Sentry.Severity.Log is not defined , definitely needs to be imported or maybe you can expose those constants from the Sentry SDK?

Also, when trying to do the Async implementation I got errors about the return types for UseFactory method. Would it be possible to have you create a simple example app that uses your library? Thanks in advance

Is LogLevel exported?

It would be nice to be able to do this.

import { SentryModule, LogLevel } from "@ntegral/nestjs-sentry"

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.