Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(api): Add Sentry Integeration #133

Merged
merged 21 commits into from
Feb 18, 2024
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ GITHUB_CLIENT_ID=
GITHUB_CLIENT_SECRET=
GITHUB_CALLBACK_URL=

SENTRY_DSN=
SENTRY_ORG=
SENTRY_PROJECT=
SENTRY_TRACES_SAMPLE_RATE=
SENTRY_PROFILES_SAMPLE_RATE=

SENTRY_ENV=
SMTP_HOST=
SMTP_PORT=
SMTP_EMAIL_ADDRESS=
Expand Down
8 changes: 7 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,13 @@ Thumbs.db
.next
.vscode
.env
.env.local
HarshPatel5940 marked this conversation as resolved.
Show resolved Hide resolved
pnpm-lock.yaml

# Database
data/
data/
# Sentry Config File
.sentryclirc

# Sentry Config File
.env.sentry-build-plugin
48 changes: 46 additions & 2 deletions apps/api/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,18 @@
* This is only a minimal backend to get started.
*/

import { LoggerService, ValidationPipe } from '@nestjs/common'
import { Logger, LoggerService, ValidationPipe } from '@nestjs/common'
import { NestFactory } from '@nestjs/core'

import { AppModule } from './app/app.module'
import chalk from 'chalk'
import moment from 'moment'
import { QueryTransformPipe } from './common/query.transform.pipe'
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger'
import * as Sentry from '@sentry/node'
import { ProfilingIntegration } from '@sentry/profiling-node'

export const sentryEnv = process.env.SENTRY_ENV || 'production'

class CustomLogger implements LoggerService {
log(message: string) {
Expand Down Expand Up @@ -42,11 +46,32 @@ class CustomLogger implements LoggerService {
}
}

async function bootstrap() {
async function initializeSentry() {
if (!process.env.SENTRY_DSN) {
HarshPatel5940 marked this conversation as resolved.
Show resolved Hide resolved
Logger.error('Missing environment variable: SENTRY_DSN')
process.exit(1)
}

Sentry.init({
dsn: process.env.SENTRY_DSN,
enabled: sentryEnv !== 'test' && sentryEnv !== 'e2e',
environment: sentryEnv,
tracesSampleRate: parseFloat(process.env.SENTRY_TRACES_SAMPLE_RATE) || 1.0,
profilesSampleRate:
parseFloat(process.env.SENTRY_PROFILES_SAMPLE_RATE) || 1.0,
integrations: [new ProfilingIntegration()],
debug: process.env.SENTRY_ENV.startsWith('dev')
})
}

async function initializeNestApp() {
const logger = new CustomLogger()
const app = await NestFactory.create(AppModule, {
logger
})
app.use(Sentry.Handlers.requestHandler())
app.use(Sentry.Handlers.tracingHandler())

const globalPrefix = 'api'
app.setGlobalPrefix(globalPrefix)
app.useGlobalPipes(
Expand All @@ -64,10 +89,29 @@ async function bootstrap() {
.build()
const document = SwaggerModule.createDocument(app, swaggerConfig)
SwaggerModule.setup('docs', app, document)
app.use(Sentry.Handlers.errorHandler())
await app.listen(port)
logger.log(
`🚀 Application is running on: http://localhost:${port}/${globalPrefix}`
)
}

async function bootstrap() {
try {
await initializeSentry()
await Sentry.startSpan(
{
op: 'applicationBootstrap',
name: 'Application Bootstrap Process'
},
async () => {
await initializeNestApp()
}
)
} catch (error) {
Sentry.captureException(error)
Logger.error(error)
}
}

bootstrap()
19 changes: 15 additions & 4 deletions apps/api/webpack.config.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,24 @@
const { composePlugins, withNx } = require('@nx/webpack')
const { sentryWebpackPlugin } = require('@sentry/webpack-plugin')

// Nx plugins for webpack.
module.exports = composePlugins(
withNx({
target: 'node'
target: 'node',
devtool: 'source-map',
plugins: [
...(process.env.SENTRY_ENV === 'production' ||
process.env.SENTRY_ENV === 'stage'
? [
sentryWebpackPlugin({
org: process.env.SENTRY_ORG,
project: process.env.SENTRY_PROJECT,
authToken: process.env.SENTRY_AUTH_TOKEN
})
]
: [])
]
}),
(config) => {
// Update the webpack config as needed here.
// e.g. `config.plugins.push(new MyPlugin())`
return config
}
)
6 changes: 6 additions & 0 deletions docs/contributing-to-keyshade/environment-variables.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ Here's the description of the environment variables used in the project. You can
* **SMTP\_EMAIL\_ADDRESS:** The email address you want to be sending out the emails from.
* **SMTP\_PASSWORD:** The app password for your email account.  
* **GITHUB\_CLIENT\_ID, GITHUB\_CLIENT\_SECRET, GITHUB\_CALLBACK\_URL:** These settings can be configured by adding an OAuth app in your GitHub account's developer section. Please note that it's not mandatory, until and unless you want to support GitHub OAuth.
* **SENTRY\_DSN**: The Data Source Name (DSN) for Sentry, a platform for monitoring, troubleshooting, and resolving issues in real-time. This is used to configure error tracking in the project.
* **SENTRY\_ORG**: The organization ID associated with your Sentry account.
* **SENTRY\_PROJECT**: The project ID within your Sentry organization where events will be reported.
* **SENTRY\_TRACES\_SAMPLE\_RATE**: The sample rate for collecting transaction traces in Sentry. It determines the percentage of transactions to capture traces for.
* **SENTRY\_PROFILES\_SAMPLE\_RATE**: The sample rate for collecting performance profiles in Sentry. It determines the percentage of requests to capture performance profiles for.
HarshPatel5940 marked this conversation as resolved.
Show resolved Hide resolved
* **SENTRY\_ENV**: The The environment in which the app is running. It can be either 'development', 'production', or 'test'. Please note that it's not mandatory, it will default to "production" enviroment for the sentry configuration.
* **FROM\_EMAIL**: The display of the email sender title.
* **JWT\_SECRET**: The secret used to sign the JWT tokens. It is insignificant in the development environment.
* **WEB\_FRONTEND\_URL, WORKSPACE\_FRONTEND\_URL**: The URLs of the web and workspace frontend respectively. These are used in the emails sometimes and in other spaces of the application too.
16 changes: 14 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@
"prettier:fix": "nx run-many -t prettier:lint --parallel",
"prettier:fix:api": "nx run api:prettier:fix",
"build": "nx run-many -t build -p api web workspace --parallel --maxParallel 3",
"build:api": "nx run api:build --configuration=production",
"build:api": "nx run api:build --configuration=production && pnpm sentry:sourcemaps",
HarshPatel5940 marked this conversation as resolved.
Show resolved Hide resolved
"build:web": "nx run web:build --configuration=production",
"build:workspace": "nx run workspace:build",
"test": "nx run-many -t test --parallel",
Expand All @@ -114,7 +114,9 @@
"db:validate": "nx run api:prisma:validate",
"db:format": "nx run api:prisma:format",
"db:reset": "nx run api:prisma:reset",
"prepare": "husky install"
"prepare": "husky install",
"sentry:sourcemaps": "sentry-cli sourcemaps inject ./dist && sentry-cli sourcemaps upload ./dist || pnpm run sentry:sourcemaps:exit",
"sentry:sourcemaps:exit": "echo 'Failed to upload source maps to Sentry' && exit 1"
},
"devDependencies": {
"@nestjs/schematics": "^10.0.3",
Expand All @@ -129,6 +131,7 @@
"@nx/react": "17.2.7",
"@nx/webpack": "17.2.7",
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.11",
"@sentry/webpack-plugin": "^2.14.1",
"@svgr/webpack": "^8.1.0",
"@swc-node/register": "~1.6.8",
"@swc/core": "~1.3.102",
Expand Down Expand Up @@ -183,6 +186,15 @@
"@nestjs/schedule": "^4.0.0",
"@nestjs/swagger": "^7.1.17",
"@prisma/client": "^5.7.1",
"@semantic-release/changelog": "^6.0.3",
"@semantic-release/commit-analyzer": "^11.1.0",
"@semantic-release/git": "^10.0.1",
"@semantic-release/release-notes-generator": "^12.1.0",
"@sentry/cli": "^2.28.0",
"@sentry/node": "^7.100.1",
"@sentry/profiling-node": "^7.100.1",
"@supabase/supabase-js": "^2.39.2",
"@types/jsonwebtoken": "^9.0.5",
"axios": "^1.6.5",
"chalk": "4.1.2",
"class-transformer": "^0.5.1",
Expand Down
6 changes: 5 additions & 1 deletion tsconfig.base.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,13 @@
"skipLibCheck": true,
"skipDefaultLibCheck": true,
"baseUrl": ".",

"paths": {
"cli": ["apps/cli/src/index.ts"]
}
},

"inlineSources": true,
"sourceRoot": "/"
},
"exclude": ["node_modules", "tmp"]
}
Loading