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 17 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
6 changes: 6 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ GITHUB_CLIENT_ID=
GITHUB_CLIENT_SECRET=
GITHUB_CALLBACK_URL=

SENTRY_DSN=
SENTRY_ORG=
SENTRY_PROJECT=
SENTRY_TRACES_SAMPLE_RATE=
SENTRY_PROFILES_SAMPLE_RATE=

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
6 changes: 6 additions & 0 deletions apps/api/src/app/app.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,10 @@ export class AppController {
health(): string {
return 'UP'
}

@Get('break')
HarshPatel5940 marked this conversation as resolved.
Show resolved Hide resolved
@Public()
break(): string {
throw new Error('Broken')
}
}
46 changes: 44 additions & 2 deletions apps/api/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,16 @@
* 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'

class CustomLogger implements LoggerService {
log(message: string) {
Expand Down Expand Up @@ -42,11 +44,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: process.env.NODE_ENV !== 'test' && process.env.NODE_ENV !== 'e2e',
environment: process.env.NODE_ENV || 'production',
HarshPatel5940 marked this conversation as resolved.
Show resolved Hide resolved
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.NODE_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 +87,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()
16 changes: 12 additions & 4 deletions apps/api/webpack.config.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,21 @@
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.NODE_ENV || 'production') === 'production'
HarshPatel5940 marked this conversation as resolved.
Show resolved Hide resolved
? 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 @@ -8,6 +8,7 @@ description: Get to know the environment you are working with

Here's the description of the environment variables used in the project. You can find the values for these variables in \`.env.example\`.

* **NODE\_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.
HarshPatel5940 marked this conversation as resolved.
Show resolved Hide resolved
* **DATABASE\_URL**: The URL of the PSQL database to connect to. This is used by the [Prisma Client](https://www.prisma.io/docs/orm/prisma-client) to connect to the database.
* **SUPABASE\_API\_URL**: The URL of the Supabase API. This is used by the [Supabase Client](https://supabase.io/docs/reference/javascript/supabase-client) to connect to the Supabase API. Make sure you create a Supabase project and get the API URL from the project settings.
* **SUPABASE\_ANON\_KEY**: The anonymous key of the Supabase project. This is used by the Supabase Client to connect to the Supabase API. Make sure you create a Supabase project and get the anonymous key from the project settings.
Expand All @@ -16,6 +17,11 @@ 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
* **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.
15 changes: 13 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,8 @@
"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 || echo 'Failed to upload source maps to Sentry'"
HarshPatel5940 marked this conversation as resolved.
Show resolved Hide resolved
},
"devDependencies": {
"@nestjs/schematics": "^10.0.3",
Expand All @@ -129,6 +130,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 +185,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