nestjs-sentry-example
nestjs-sentry-example copied to clipboard
Explanations and example project on how to setup Sentry in a Nest.js project
Description
Simple Sentry setup on Nest framework.
Just explore the code for more details, especially the files in the sentry
folder.
Installation
To run this simple example, first copy .env.sample and insert your own Sentry dns.
Then run Nest using the usual command:
$ npm run start:debug
Step by step
Below are some explanations on how to do a clean setup in your existing project.
Dependencies
Create a new Nest app using the CLI
$ nest new sentry-setup
Install Sentry
$ npm install --save @sentry/node @sentry/tracing
Create the needed elements
Create Sentry module, service and interceptor
$ nest g module sentry
$ nest g service sentry
$ nest g interceptor sentry/sentry
SentryModule
Create the SentryModule.forRoot() method and add the Sentry.init(options) in it.
Call the Sentry.Module.forRoot({...}) in the AppModule.
Add the call to the Express requestHandler middleware in the AppModule.
configure(consumer: MiddlewareConsumer): void {
consumer.apply(Sentry.Handlers.requestHandler()).forRoutes({
path: '*',
method: RequestMethod.ALL,
});
}
It is important to use that middleware otherwise the current Hub will be global and you will run into conflict as Sentry create a Hub by thread and Node.js is not multi-thread.
SentryService
We want to initialize the transaction in the constructor of the service. You can customize your main transaction there.
Note that because I inject the Express request, the service must be request scoped. You can read more about that here.
@Injectable({ scope: Scope.REQUEST })
export class SentryService {
constructor(@Inject(REQUEST) private request: Request) {
// ... etc ...
}
}
SentryInterceptor
The SentryInterceptor will capture the exception and finish the transaction. Please also
note that it must be request scoped as we inject the SentryService:
@Injectable({ scope: Scope.REQUEST })
export class SentryInterceptor implements NestInterceptor {
constructor(private sentryService: SentryService) {}
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
// ... etc ...
}
}
As an example I added a span. This is not necessary, but it will just make the trace nicer in the performance tab of Sentry.
You can add more span anywhere in your application simply by injecting the SentryService.