Skip to content

Commit 7e9a038

Browse files
authored
feat(nestjs): Automatic instrumentation of nestjs interceptors after route execution (#13264)
Adding a span 'Interceptor - After Span' to improve instrumentation for operations happening after the route execution is done. Tracking what happens in individual interceptors after the route is hard, so currently we create one span to trace everything that happens after the route is executed.
1 parent b192678 commit 7e9a038

File tree

14 files changed

+794
-68
lines changed

14 files changed

+794
-68
lines changed

dev-packages/e2e-tests/test-applications/nestjs-basic/src/app.controller.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
import { Controller, Get, Param, ParseIntPipe, UseFilters, UseGuards, UseInterceptors } from '@nestjs/common';
22
import { flush } from '@sentry/nestjs';
33
import { AppService } from './app.service';
4+
import { AsyncInterceptor } from './async-example.interceptor';
5+
import { ExampleInterceptor1 } from './example-1.interceptor';
6+
import { ExampleInterceptor2 } from './example-2.interceptor';
47
import { ExampleExceptionGlobalFilter } from './example-global-filter.exception';
58
import { ExampleExceptionLocalFilter } from './example-local-filter.exception';
69
import { ExampleLocalFilter } from './example-local.filter';
710
import { ExampleGuard } from './example.guard';
8-
import { ExampleInterceptor } from './example.interceptor';
911

1012
@Controller()
1113
@UseFilters(ExampleLocalFilter)
@@ -29,11 +31,17 @@ export class AppController {
2931
}
3032

3133
@Get('test-interceptor-instrumentation')
32-
@UseInterceptors(ExampleInterceptor)
34+
@UseInterceptors(ExampleInterceptor1, ExampleInterceptor2)
3335
testInterceptorInstrumentation() {
3436
return this.appService.testSpan();
3537
}
3638

39+
@Get('test-async-interceptor-instrumentation')
40+
@UseInterceptors(AsyncInterceptor)
41+
testAsyncInterceptorInstrumentation() {
42+
return this.appService.testSpan();
43+
}
44+
3745
@Get('test-pipe-instrumentation/:id')
3846
testPipeInstrumentation(@Param('id', ParseIntPipe) id: number) {
3947
return { value: id };
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { CallHandler, ExecutionContext, Injectable, NestInterceptor } from '@nestjs/common';
2+
import * as Sentry from '@sentry/nestjs';
3+
import { tap } from 'rxjs';
4+
5+
@Injectable()
6+
export class AsyncInterceptor implements NestInterceptor {
7+
intercept(context: ExecutionContext, next: CallHandler) {
8+
Sentry.startSpan({ name: 'test-async-interceptor-span' }, () => {});
9+
return Promise.resolve(
10+
next.handle().pipe(
11+
tap(() => {
12+
Sentry.startSpan({ name: 'test-async-interceptor-span-after-route' }, () => {});
13+
}),
14+
),
15+
);
16+
}
17+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { CallHandler, ExecutionContext, Injectable, NestInterceptor } from '@nestjs/common';
2+
import * as Sentry from '@sentry/nestjs';
3+
import { tap } from 'rxjs';
4+
5+
@Injectable()
6+
export class ExampleInterceptor1 implements NestInterceptor {
7+
intercept(context: ExecutionContext, next: CallHandler) {
8+
Sentry.startSpan({ name: 'test-interceptor-span-1' }, () => {});
9+
return next.handle().pipe(
10+
tap(() => {
11+
Sentry.startSpan({ name: 'test-interceptor-span-after-route' }, () => {});
12+
}),
13+
);
14+
}
15+
}

dev-packages/e2e-tests/test-applications/nestjs-basic/src/example.interceptor.ts renamed to dev-packages/e2e-tests/test-applications/nestjs-basic/src/example-2.interceptor.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ import { CallHandler, ExecutionContext, Injectable, NestInterceptor } from '@nes
22
import * as Sentry from '@sentry/nestjs';
33

44
@Injectable()
5-
export class ExampleInterceptor implements NestInterceptor {
5+
export class ExampleInterceptor2 implements NestInterceptor {
66
intercept(context: ExecutionContext, next: CallHandler) {
7-
Sentry.startSpan({ name: 'test-interceptor-span' }, () => {});
7+
Sentry.startSpan({ name: 'test-interceptor-span-2' }, () => {});
88
return next.handle().pipe();
99
}
1010
}

0 commit comments

Comments
 (0)