Last active
July 5, 2023 13:02
-
-
Save Blackfaded/aa7a0044176734c3527819353277728c to your computer and use it in GitHub Desktop.
sentry-nestjs-files
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { MiddlewareConsumer, Module, RequestMethod } from '@nestjs/common'; | |
| import { RewriteFrames } from '@sentry/integrations'; | |
| import * as Sentry from '@sentry/node'; | |
| import { version } from '../package.json'; | |
| @Module({ | |
| imports: [ | |
| NgSentryModule.forRoot({ | |
| // this does not have to be a secret | |
| dsn: 'your_dsn_string', | |
| tracesSampleRate: 1.0, | |
| environment: process.env.NODE_ENV, | |
| // version must match the version when uploading the source maps | |
| release: version, | |
| // dist must match the dist when uploading the source maps | |
| dist: process.env.NODE_ENV, | |
| integrations: [ | |
| new RewriteFrames({ | |
| iteratee: frame => { | |
| if (!frame.filename) return frame; | |
| frame.filename = 'app://' + frame.filename; | |
| return frame; | |
| }, | |
| }), | |
| ], | |
| }), | |
| // ... | |
| ], | |
| providers: [], | |
| controllers: [], | |
| }) | |
| export class AppModule { | |
| configure(consumer: MiddlewareConsumer): void { | |
| consumer.apply(Sentry.Handlers.requestHandler()).forRoutes({ | |
| path: '*', | |
| method: RequestMethod.ALL, | |
| }); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { | |
| CallHandler, | |
| ExecutionContext, | |
| Injectable, | |
| NestInterceptor, | |
| Scope, | |
| } from '@nestjs/common'; | |
| import * as Sentry from '@sentry/node'; | |
| import { catchError, finalize, Observable, throwError } from 'rxjs'; | |
| import { NgSentryService } from './ngsentry.service'; | |
| /** | |
| * We must be in Request scope as we inject SentryService | |
| */ | |
| @Injectable({ scope: Scope.REQUEST }) | |
| export class NgSentryInterceptor implements NestInterceptor { | |
| constructor(private sentryService: NgSentryService) {} | |
| intercept(context: ExecutionContext, next: CallHandler): Observable<any> { | |
| // start a child span for performance tracing | |
| const span = this.sentryService.startChild({ op: `route handler` }); | |
| return next.handle().pipe( | |
| catchError(error => { | |
| // capture the error, you can filter out some errors here | |
| Sentry.captureException( | |
| error, | |
| this.sentryService.span.getTraceContext(), | |
| ); | |
| // throw again the error | |
| return throwError(() => error); | |
| }), | |
| finalize(() => { | |
| span.finish(); | |
| this.sentryService.span.finish(); | |
| }), | |
| ); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { Module } from '@nestjs/common'; | |
| import { APP_INTERCEPTOR } from '@nestjs/core'; | |
| import * as Sentry from '@sentry/node'; | |
| import { NgSentryInterceptor } from './ngsentry.interceptor'; | |
| import { NgSentryService } from './ngsentry.service'; | |
| export const SENTRY_OPTIONS = 'SENTRY_OPTIONS'; | |
| @Module({}) | |
| export class NgSentryModule { | |
| static forRoot(options: Sentry.NodeOptions) { | |
| // initialization of Sentry, this is where Sentry will create a Hub | |
| Sentry.init(options); | |
| return { | |
| module: NgSentryModule, | |
| global: true, | |
| providers: [ | |
| { | |
| provide: SENTRY_OPTIONS, | |
| useValue: options, | |
| }, | |
| NgSentryService, | |
| { | |
| provide: APP_INTERCEPTOR, | |
| useClass: NgSentryInterceptor, | |
| }, | |
| ], | |
| exports: [NgSentryService], | |
| }; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { Scope } from '@nestjs/common'; | |
| import { Inject, Injectable } from '@nestjs/common'; | |
| import { REQUEST } from '@nestjs/core'; | |
| import * as Sentry from '@sentry/node'; | |
| import { Span, SpanContext } from '@sentry/types'; | |
| import { Request } from 'express'; | |
| /** | |
| * Because we inject REQUEST we need to set the service as request scoped | |
| */ | |
| @Injectable({ scope: Scope.REQUEST }) | |
| export class NgSentryService { | |
| /** | |
| * Return the current span defined in the current Hub and Scope | |
| */ | |
| get span(): Span { | |
| return Sentry.getCurrentHub().getScope().getSpan(); | |
| } | |
| /** | |
| * When injecting the service it will create the main transaction | |
| * | |
| * @param request | |
| */ | |
| constructor(@Inject(REQUEST) private request: Request) { | |
| console.log('construct'); | |
| const { method, headers, url } = this.request; | |
| // recreate transaction based from HTTP request | |
| const transaction = Sentry.startTransaction({ | |
| name: `Route: ${method} ${url}`, | |
| op: 'transaction', | |
| }); | |
| // setup context of newly created transaction | |
| Sentry.getCurrentHub().configureScope(scope => { | |
| scope.setSpan(transaction); | |
| // customize your context here | |
| scope.setContext('http', { | |
| method, | |
| url, | |
| headers, | |
| }); | |
| }); | |
| } | |
| /** | |
| * This will simply start a new child span in the current span | |
| * | |
| * @param spanContext | |
| */ | |
| startChild(spanContext: SpanContext) { | |
| return this.span.startChild(spanContext); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { ExceptionFilter, Catch, ArgumentsHost } from '@nestjs/common'; | |
| import { BaseExceptionFilter } from '@nestjs/core'; | |
| import * as Sentry from '@sentry/node'; | |
| @Catch() | |
| export class SentryExceptionFilter | |
| extends BaseExceptionFilter | |
| implements ExceptionFilter | |
| { | |
| catch(exception: any, host: ArgumentsHost) { | |
| Sentry.captureException(exception); | |
| super.catch(exception, host); | |
| } | |
| } | |
| ``` | |
| --- | |
| `src/ngsentry/ngsentry.interceptor.ts` | |
| ```ts | |
| import { | |
| CallHandler, | |
| ExecutionContext, | |
| Injectable, | |
| NestInterceptor, | |
| Scope, | |
| } from '@nestjs/common'; | |
| import * as Sentry from '@sentry/node'; | |
| import { catchError, finalize, Observable, throwError } from 'rxjs'; | |
| import { NgSentryService } from './ngsentry.service'; | |
| /** | |
| * We must be in Request scope as we inject SentryService | |
| */ | |
| @Injectable({ scope: Scope.REQUEST }) | |
| export class NgSentryInterceptor implements NestInterceptor { | |
| constructor(private sentryService: NgSentryService) {} | |
| intercept(context: ExecutionContext, next: CallHandler): Observable<any> { | |
| // start a child span for performance tracing | |
| const span = this.sentryService.startChild({ op: `route handler` }); | |
| return next.handle().pipe( | |
| catchError(error => { | |
| // capture the error, you can filter out some errors here | |
| Sentry.captureException( | |
| error, | |
| this.sentryService.span.getTraceContext(), | |
| ); | |
| // throw again the error | |
| return throwError(() => error); | |
| }), | |
| finalize(() => { | |
| span.finish(); | |
| this.sentryService.span.finish(); | |
| }), | |
| ); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment