Skip to content

Commit

Permalink
ash/sentry setup (#71)
Browse files Browse the repository at this point in the history
Co-authored-by: Tejas Mehta <[email protected]>
  • Loading branch information
ahong75 and tmthecoder authored Sep 10, 2024
1 parent bc5c7aa commit b47ff29
Show file tree
Hide file tree
Showing 27 changed files with 793 additions and 49 deletions.
5 changes: 5 additions & 0 deletions docker-compose-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ services:
AUTH_SERVICE_ADDR: auth-service:5000
EMAIL_SERVICE_ADDR: email-service:5000
LOGGING_SERVICE_ADDR: logging-service:5000
SENTRY_DSN: 'https://895c35e671ebe116967d7818f6c99efb@o4506876382609408.ingest.us.sentry.io/4507926410559488'
networks:
- bog-api-net
depends_on:
Expand All @@ -36,6 +37,7 @@ services:
DB_SERVICE_ADDR: db-service:5000
EMAIL_SERVICE_ADDR: email-service:5000
LOGGING_SERVICE_ADDR: logging-service:5000
SENTRY_DSN: 'https://f65c541f1d3217cf4752046e8ce46ec4@o4506876382609408.ingest.us.sentry.io/4507926438346752'
networks:
- bog-api-net
depends_on:
Expand All @@ -62,6 +64,7 @@ services:
LOGGING_SERVICE_ADDR: logging-service:5000
NODE_ENV: test
SENDGRID_API_KEY: test-key
SENTRY_DSN: 'https://46b6656a920cc32333cc37cdc2c1ce12@o4506876382609408.ingest.us.sentry.io/4507926519873536'
networks:
- bog-api-net
depends_on:
Expand All @@ -87,6 +90,7 @@ services:
EMAIL_SERVICE_ADDR: email-service:5000
LOGGING_SERVICE_ADDR: logging-service:5000
DATABASE_URL: postgresql://user:password@db
SENTRY_DSN: 'https://9057d8b86db87880b424db0d8e923cfc@o4506876382609408.ingest.us.sentry.io/4507926523478016'
networks:
- bog-api-net
healthcheck:
Expand All @@ -109,6 +113,7 @@ services:
EMAIL_SERVICE_ADDR: email-service:5000
DATABASE_URL: postgresql://user:password@db
NODE_ENV: test
SENTRY_DSN: 'https://235226366783809ee8337a530785707f@o4506876382609408.ingest.us.sentry.io/4507926518038528'
networks:
- bog-api-net
depends_on:
Expand Down
3 changes: 2 additions & 1 deletion packages/api-gateway/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
"@nestjs/microservices": "^10.2.7",
"@nestjs/platform-express": "^10.0.0",
"@nestjs/swagger": "^7.3.0",
"@sentry/nestjs": "^8.29.0",
"@sentry/profiling-node": "^7.108.0",
"bcrypt": "^5.1.1",
"class-transformer": "^0.5.1",
"class-validator": "^0.14.0",
Expand All @@ -40,7 +42,6 @@
"@nestjs/cli": "^10.0.0",
"@nestjs/schematics": "^10.0.0",
"@nestjs/testing": "^10.0.0",
"@openapitools/openapi-generator-cli": "^2.13.1",
"@types/express": "^4.17.17",
"@types/jest": "^29.5.2",
"@types/node": "^20.3.1",
Expand Down
9 changes: 8 additions & 1 deletion packages/api-gateway/src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,15 @@ import { AuthModule } from './modules/auth/auth.module';
import { ProjectModule } from './modules/project/project.module';
import { UserModule } from './modules/user/user.module';
import { EmailModule } from './modules/email/email.module';
import { SentryModule } from '@sentry/nestjs/setup';

@Module({
imports: [AuthModule, ProjectModule, UserModule, EmailModule],
imports: [
SentryModule.forRoot(),
AuthModule,
ProjectModule,
UserModule,
EmailModule,
],
})
export class AppModule {}
19 changes: 19 additions & 0 deletions packages/api-gateway/src/instrument.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import * as Sentry from '@sentry/nestjs';
import { nodeProfilingIntegration } from '@sentry/profiling-node';

// Ensure to call this before importing any other modules!
Sentry.init({
dsn: process.env.SENTRY_DSN,
integrations: [
// Add our Profiling integration
nodeProfilingIntegration(),
],

// Add Tracing by setting tracesSampleRate
// We recommend adjusting this value in production
tracesSampleRate: 1.0,

// Set sampling rate for profiling
// This is relative to tracesSampleRate
profilesSampleRate: 1.0,
});
7 changes: 7 additions & 0 deletions packages/api-gateway/src/main.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,23 @@
import './instrument';
import { NestFactory, Reflector } from '@nestjs/core';
import { AppModule } from './app.module';
import { ConfigModule } from '@nestjs/config';
import { join } from 'path';
import { ClassSerializerInterceptor, ValidationPipe } from '@nestjs/common';
import { RpcExceptionFilter } from './rpc_exception_filter';
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';

async function bootstrap() {
ConfigModule.forRoot({
envFilePath: join(__dirname, '../../../.env.local'),
});
const app = await NestFactory.create(AppModule);
app.useGlobalPipes(
new ValidationPipe({
transform: true,
}),
);

app.useGlobalFilters(new RpcExceptionFilter());
app.useGlobalInterceptors(new ClassSerializerInterceptor(app.get(Reflector)));

Expand Down
7 changes: 7 additions & 0 deletions packages/api-gateway/src/rpc_exception_filter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,17 @@ import {
} from '@nestjs/common';
import { RpcException } from '@nestjs/microservices';
import { Response } from 'express';
import * as Sentry from '@sentry/nestjs';

@Catch(RpcException, Error)
export class RpcExceptionFilter implements ExceptionFilter {
catch(exception: RpcException | Error, host: ArgumentsHost) {
const ctx = host.switchToHttp();
const response = ctx.getResponse<Response>();
if (exception instanceof HttpException) {
if (exception.getStatus() >= 500) {
Sentry.captureException(exception);
}
response.status(exception.getStatus()).send(exception.getResponse());
return;
} else {
Expand All @@ -24,6 +28,9 @@ export class RpcExceptionFilter implements ExceptionFilter {
ex = exception;
}
const error: any = ex.getError();
if (rpcStatusToHttp(error.code) >= 500) {
Sentry.captureException(exception);
}
response.status(rpcStatusToHttp(error.code)).send(ex.message);
}
}
Expand Down
2 changes: 2 additions & 0 deletions packages/auth-service/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
"@nestjs/core": "^10.0.0",
"@nestjs/microservices": "^10.2.7",
"@nestjs/platform-express": "^10.0.0",
"@sentry/nestjs": "^8.29.0",
"@sentry/profiling-node": "^8.29.0",
"bcrypt": "^5.1.1",
"jsonwebtoken": "^9.0.2",
"juno-proto": "file:../proto",
Expand Down
9 changes: 8 additions & 1 deletion packages/auth-service/src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,16 @@ import { JwtModule } from './modules/jwt/jwt.module';
import { ApiKeyModule } from './modules/api_key/api_key.module';
import { HealthModule } from './modules/health/health.module';
import { UserModule } from './modules/user/user.module';
import { SentryModule } from '@sentry/nestjs/setup';

@Module({
imports: [ApiKeyModule, JwtModule, HealthModule, UserModule],
imports: [
SentryModule.forRoot(),
ApiKeyModule,
JwtModule,
HealthModule,
UserModule,
],
controllers: [AppController],
providers: [AppService],
})
Expand Down
19 changes: 19 additions & 0 deletions packages/auth-service/src/instrument.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import * as Sentry from '@sentry/nestjs';
import { nodeProfilingIntegration } from '@sentry/profiling-node';

// Ensure to call this before importing any other modules!
Sentry.init({
dsn: process.env.SENTRY_DSN,
integrations: [
// Add our Profiling integration
nodeProfilingIntegration(),
],

// Add Tracing by setting tracesSampleRate
// We recommend adjusting this value in production
tracesSampleRate: 1.0,

// Set sampling rate for profiling
// This is relative to tracesSampleRate
profilesSampleRate: 1.0,
});
7 changes: 6 additions & 1 deletion packages/auth-service/src/main.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { NestFactory } from '@nestjs/core';
import './instrument';
import { NestFactory, HttpAdapterHost } from '@nestjs/core';
import { AppModule } from './app.module';
import { MicroserviceOptions, Transport } from '@nestjs/microservices';
import { join } from 'path';
Expand All @@ -13,6 +14,7 @@ import {
UserProto,
UserProtoFile,
} from 'juno-proto';
import { SentryFilter } from './sentry.filter';

async function bootstrap() {
ConfigModule.forRoot({
Expand All @@ -39,6 +41,9 @@ async function bootstrap() {
},
},
);
const { httpAdapter } = app.get(HttpAdapterHost);
app.useGlobalFilters(new SentryFilter(httpAdapter));

await app.listen();
}
bootstrap();
14 changes: 14 additions & 0 deletions packages/auth-service/src/sentry.filter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Catch, ArgumentsHost } from '@nestjs/common';
import { BaseExceptionFilter } from '@nestjs/core';
import { RpcException } from '@nestjs/microservices';
import * as Sentry from '@sentry/node';

@Catch()
export class SentryFilter extends BaseExceptionFilter {
catch(exception: any, host: ArgumentsHost) {
if (!(exception instanceof RpcException)) {
Sentry.captureException(exception);
}
super.catch(exception, host);
}
}
2 changes: 2 additions & 0 deletions packages/db-service/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
"@nestjs/microservices": "^10.2.7",
"@nestjs/platform-express": "^10.0.0",
"@prisma/client": "^5.4.2",
"@sentry/nestjs": "^8.29.0",
"@sentry/profiling-node": "^8.29.0",
"bcrypt": "^5.1.1",
"juno-proto": "file:../proto",
"reflect-metadata": "^0.1.13",
Expand Down
2 changes: 2 additions & 0 deletions packages/db-service/src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@ import { HealthModule } from './modules/health/health.module';
import { ResetModule } from './modules/reset/reset.module';
import { AuthModule } from './modules/auth/auth.module';
import { EmailModule } from './modules/email/email.module';
import { SentryModule } from '@sentry/nestjs/setup';

@Module({
imports: [
SentryModule.forRoot(),
UserModule,
ProjectModule,
HealthModule,
Expand Down
2 changes: 2 additions & 0 deletions packages/db-service/src/global-exception.filter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Prisma } from '@prisma/client';
import { Observable, throwError } from 'rxjs';
import { Catch, RpcExceptionFilter } from '@nestjs/common';
import { status } from '@grpc/grpc-js';
import * as Sentry from '@sentry/nestjs';

function mapPrismaErrorToRpcException(
error: Prisma.PrismaClientKnownRequestError,
Expand Down Expand Up @@ -51,6 +52,7 @@ export class CustomRpcExceptionFilter
return throwError(() => exception.getError());
} else {
console.error(`Unexpected Error: ${JSON.stringify(exception)}`);
Sentry.captureException(exception);
return throwError(() =>
new RpcException({
code: status.INTERNAL,
Expand Down
19 changes: 19 additions & 0 deletions packages/db-service/src/instrument.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import * as Sentry from '@sentry/nestjs';
import { nodeProfilingIntegration } from '@sentry/profiling-node';

// Ensure to call this before importing any other modules!
Sentry.init({
dsn: process.env.SENTRY_DSN,
integrations: [
// Add our Profiling integration
nodeProfilingIntegration(),
],

// Add Tracing by setting tracesSampleRate
// We recommend adjusting this value in production
tracesSampleRate: 1.0,

// Set sampling rate for profiling
// This is relative to tracesSampleRate
profilesSampleRate: 1.0,
});
2 changes: 2 additions & 0 deletions packages/db-service/src/main.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import './instrument';
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { MicroserviceOptions, Transport } from '@nestjs/microservices';
Expand Down Expand Up @@ -50,6 +51,7 @@ async function bootstrap() {
},
},
);

app.useGlobalFilters(new CustomRpcExceptionFilter());
await app.listen();
}
Expand Down
2 changes: 2 additions & 0 deletions packages/email-service/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
"@nestjs/core": "^10.0.0",
"@nestjs/microservices": "^10.2.7",
"@nestjs/platform-express": "^10.0.0",
"@sentry/nestjs": "^8.29.0",
"@sentry/profiling-node": "^8.29.0",
"juno-proto": "file:../proto",
"reflect-metadata": "^0.1.13",
"rxjs": "^7.8.1"
Expand Down
3 changes: 2 additions & 1 deletion packages/email-service/src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { EmailModule } from './modules/email/email.module';
import { SentryModule } from '@sentry/nestjs/setup';

@Module({
imports: [EmailModule],
imports: [SentryModule.forRoot(), EmailModule],
controllers: [AppController],
providers: [AppService],
})
Expand Down
19 changes: 19 additions & 0 deletions packages/email-service/src/instrument.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import * as Sentry from '@sentry/nestjs';
import { nodeProfilingIntegration } from '@sentry/profiling-node';

// Ensure to call this before importing any other modules!
Sentry.init({
dsn: process.env.SENTRY_DSN,
integrations: [
// Add our Profiling integration
nodeProfilingIntegration(),
],

// Add Tracing by setting tracesSampleRate
// We recommend adjusting this value in production
tracesSampleRate: 1.0,

// Set sampling rate for profiling
// This is relative to tracesSampleRate
profilesSampleRate: 1.0,
});
7 changes: 6 additions & 1 deletion packages/email-service/src/main.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { NestFactory } from '@nestjs/core';
import './instrument';
import { NestFactory, HttpAdapterHost } from '@nestjs/core';
import { AppModule } from './app.module';
import { MicroserviceOptions, Transport } from '@nestjs/microservices';
import { join } from 'path';
import { ConfigModule } from '@nestjs/config';
import { EmailProtoFile, EmailProto } from 'juno-proto';
import { SentryFilter } from './sentry.filter';

async function bootstrap() {
ConfigModule.forRoot({
Expand All @@ -20,6 +22,9 @@ async function bootstrap() {
},
},
);
const { httpAdapter } = app.get(HttpAdapterHost);
app.useGlobalFilters(new SentryFilter(httpAdapter));

await app.listen();
}
bootstrap();
14 changes: 14 additions & 0 deletions packages/email-service/src/sentry.filter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Catch, ArgumentsHost } from '@nestjs/common';
import { BaseExceptionFilter } from '@nestjs/core';
import { RpcException } from '@nestjs/microservices';
import * as Sentry from '@sentry/node';

@Catch()
export class SentryFilter extends BaseExceptionFilter {
catch(exception: any, host: ArgumentsHost) {
if (!(exception instanceof RpcException)) {
Sentry.captureException(exception);
}
super.catch(exception, host);
}
}
3 changes: 3 additions & 0 deletions packages/logging-service/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@
"@nestjs/core": "^10.0.0",
"@nestjs/microservices": "^10.2.7",
"@nestjs/platform-express": "^10.0.0",
"@sentry/nestjs": "^8.29.0",
"@sentry/node": "^8.29.0",
"@sentry/profiling-node": "^8.29.0",
"juno-proto": "file:../proto",
"reflect-metadata": "^0.1.13",
"rxjs": "^7.8.1"
Expand Down
Loading

0 comments on commit b47ff29

Please sign in to comment.