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: update sentry #1370

Merged
merged 10 commits into from
Oct 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
18 changes: 11 additions & 7 deletions .talismanrc
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,15 @@ fileignoreconfig:
- filename: server/src/http/controllers/__snapshots__/etablissementRecruteur.controller.test.ts.snap
checksum: 1844a9ad314c3074adc11bd09ec0aac528802aed67d05e9e3da788545be88c92
- filename: server/src/http/controllers/application.controller.test.ts
checksum: 1f3c9b8cd7c578252a0c41ca9028672712a5bca2ce1686cba83ff60305708305
checksum: 00cac67c8e138098126ae98702e2bdc3e1092e1bbf188d9a437197e9ca94e16a
- filename: server/src/http/controllers/appointments/appointments.controller.ts
checksum: dc77c04efc26dcd8ca4816f392ab24a32a92cb45ca4b94adb593a08e7a2d231e
- filename: server/src/http/controllers/etablissementRecruteur.controller.test.ts
checksum: 6e187972b61616791476704a51dcbd97404489e66db72c00912e7aa1436966e5
- filename: server/src/http/controllers/updateRecruteurLba.controller.test.ts
checksum: 71dd55af4f1f44fd2b69dee91f0fc8006f3b9e0bd80d40271c73697d4eea9ea2
- filename: server/src/http/controllers/user.controller.test.ts
checksum: 2c8a4a9e141d7829c7f717dc5a179435313f157a052df3dfe55fd64104754a35
checksum: e01d1b9c54d1e6d0c98fd7984f32c3a93f3e9bde92887bdab320cb7af91fdd92
- filename: server/src/http/controllers/v2/applications.controller.v2.test.ts
checksum: 91f4cb9a288d144a19596772bc8ceed1903476df3faeeac6f235162560de8e3b
- filename: server/src/http/controllers/v2/appointment.controller.v2.test.ts
Expand Down Expand Up @@ -74,7 +74,7 @@ fileignoreconfig:
- filename: server/src/security/apiApprentissageService.ts
checksum: 0e6d208dc8de66d2a440ff40a1260a76e41bf69fb414ccbfc6d99396df3f3b91
- filename: server/src/services/__snapshots__/formulaire.service.test.ts.snap
checksum: cbed2837ec4143df8ec123d725f07a2d836b2de40250e4d48759328b1482a73e
checksum: 71d9956fd03fcec52d37b3799fc5bc806d42ec40200254b1740819b3d5a2b0d1
- filename: server/src/services/application.service.test.ts
checksum: 02c7f8874a880cc0f9913469d6ef097ad42bbea8df79d7f08451410f7b32e2c0
- filename: server/src/services/application.service.ts
Expand Down Expand Up @@ -186,13 +186,15 @@ fileignoreconfig:
- filename: ui/components/ItemDetail/LbaJobComponents/LbaJobTechniques.tsx
checksum: 553720667140e5bbf7cef1969c02cbcd3c234defc30bb08208398c1900e29e3b
- filename: ui/components/ItemDetail/LbaJobDetail.tsx
checksum: e1c36f9a6cd1cec8d459da178e5c42d723760a63a867dac1f50dd941a334696c
checksum: 74951335936fd8df7dbbda0dfcb9fd36d01ec96a34d04d61761e5b081ac2bd96
- filename: ui/components/ItemDetail/LbaJobComponents/LbaJobDetail.tsx
checksum: 74951335936fd8df7dbbda0dfcb9fd36d01ec96a34d04d61761e5b081ac2bd96
- filename: ui/components/ItemDetail/LbaRecruteurComponents/LbaRecruteurDetail.tsx
checksum: 6e552b66f9238645f70705a0c43c81905e8dbee1c83d364cd89f951f80cb7ea0
- filename: ui/components/ItemDetail/RecruteurLbaComponents/RecruteurLbaDetail.tsx
checksum: e61fa8a7bca174c70714ce633165436127f89e9fd8cf9005af681ca870465806
checksum: 5d8d24178d6390f4745bcddcaca7e7ea3f8f6af79ef304bb48187a6bea7ccfa1
- filename: ui/components/ItemDetail/TrainingDetail.tsx
checksum: 01556e58758449693529955a0de80ba4a2c243bfb8a41d1829df0daeca83e456
checksum: a681f3f410db93db9fc2640636b70df05fe2d9e3d0879f8afc19f9cd451bae59
- filename: ui/components/ItemDetail/loadedItemDetail.tsx
checksum: 9db6a64f202979b07251fd40445961d8db03bdb18b6668f9813bdbdf0d56aa65
- filename: ui/components/RDV/DemandeDeContact.tsx
Expand All @@ -210,7 +212,7 @@ fileignoreconfig:
- filename: ui/components/espace_pro/Admin/utilisateurs/infoDetails/InfoDetails.tsx
checksum: be2ad6ca5c2bd36d26cd7aebb33ab876bd32662be3735fee3b167325c284ccff
- filename: ui/components/espace_pro/AjouterVoeux.tsx
checksum: 8ba50b9d7127114cd71789bbf7c26dc19b4b915ab4ae2e2e033c1ca65accee94
checksum: bd5e3fc26e296e4e0e8b51305082dcb718a355b2000bb0b2b45dd9751bc81269
- filename: ui/components/footer.tsx
checksum: e0dd3ec2ac813053ee5e672472b545719c95e49f0891cf2f8e1b5db484d00479
- filename: ui/pages/accessibilite.tsx
Expand All @@ -229,6 +231,8 @@ fileignoreconfig:
checksum: 324cd501354cfff65447c2599c4cc8966aa8aac30dda7854623dd6f7f7b0d34e
- filename: yarn.lock
checksum: 21c8c4f9064194196622ad215768893c1756eec1cbc175efffcb1428d8821c9f
- filename: server/src/jobs/offrePartenaire/importHelloWork.test.input.xml
checksum: 6f28aee7664d1ec1e4b4da34b96b63e23781538b3fe3e8d50dddbdad3884fa3f
scopeconfig:
- scope: node
custom_patterns:
Expand Down
9 changes: 4 additions & 5 deletions server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,8 @@
"@fastify/swagger": "^8.10.1",
"@fastify/swagger-ui": "^1.9.3",
"@hapi/boom": "^10.0.1",
"@immobiliarelabs/fastify-sentry": "^7.1.1",
"@sentry/integrations": "^7.72.0",
"@sentry/node": "^7.72.0",
"@sentry/node": "^8.33.1",
"@sentry/profiling-node": "^8.33.1",
"@smithy/types": "^3.4.2",
"@turf/distance": "^6.5.0",
"@types/netmask": "^2.0.3",
Expand Down Expand Up @@ -68,7 +67,7 @@
"got": "^12.5.2",
"iconv-lite": "^0.6.3",
"is-semver": "^1.0.11",
"job-processor": "^1.6.0",
"job-processor": "^1.6.2",
"joi": "^17.6.0",
"jsonwebtoken": "^8.5.1",
"lil-http-terminator": "^1.2.3",
Expand Down Expand Up @@ -101,7 +100,7 @@
"zod-mongodb-schema": "^1.0.2"
},
"devDependencies": {
"@sentry/types": "^7.72.0",
"@sentry/types": "^8.19.0",
"@swc/core": "^1.3.90",
"@types/bunyan": "^1.8.9",
"@types/ejs": "^3.1.3",
Expand Down
4 changes: 1 addition & 3 deletions server/src/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ import HttpTerminator from "lil-http-terminator"

import { closeMemoryCache } from "./common/apis/client"
import { logger } from "./common/logger"
import { closeSentry } from "./common/sentry/sentry"
import { closeMongodbConnection } from "./common/utils/mongodbUtils"
import { notifyToSlack } from "./common/utils/slackUtils"
import config from "./config"
import { bindProcessorServer } from "./http/jobProcessorServer"
import { closeSentry, initSentryProcessor } from "./http/sentry"
import { bindFastifyServer } from "./http/server"
import { setupJobProcessor } from "./jobs/jobs"

Expand Down Expand Up @@ -60,8 +60,6 @@ program
// on définit le module du logger en global pour distinguer les logs des jobs
if (command !== "start") {
logger.fields.module = `cli:${command}`
// Pas besoin d'init Sentry dans le cas du server car il est start automatiquement
initSentryProcessor()
}
logger.info(`Starting command ${command}`)
})
Expand Down
66 changes: 66 additions & 0 deletions server/src/common/sentry/sentry.fastify.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import * as Sentry from "@sentry/node"
import type { FastifyRequest } from "fastify"
import { assertUnreachable } from "shared"

import { Server } from "../../http/server"

type UserData = {
segment: string
id?: string | number
email?: string
} & Record<string, unknown>

function extractUserData(request: FastifyRequest): UserData {
const user = request.user

if (!user) {
return {
segment: "anonymous",
}
}

const userType = user.type

if (userType === "ICredential") {
return {
segment: "api-key",
id: user.value._id.toString(),
email: user.value.email,
}
}

if (userType === "IAccessToken") {
const identity = user.value.identity
return {
segment: "access-token",
id: "_id" in identity ? identity._id.toString() : identity.email,
email: identity.email,
}
}
if (userType === "IUser2") {
return {
segment: "session",
id: user.value._id.toString(),
email: user.value.email,
}
}
if (userType === "IApiApprentissage") {
return {
segment: "api-apprentissage",
email: user.value.email,
}
}
assertUnreachable(userType)
}

export function initSentryFastify(app: Server) {
app.addHook("onRequest", async (request, _reply) => {
const scope = Sentry.getIsolationScope()
scope
.setUser(extractUserData(request))
.setExtra("headers", request.headers)
.setExtra("method", request.method)
.setExtra("protocol", request.protocol)
.setExtra("query_string", request.query)
})
}
30 changes: 30 additions & 0 deletions server/src/common/sentry/sentry.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import * as Sentry from "@sentry/node"
import { nodeProfilingIntegration } from "@sentry/profiling-node"

import config from "../../config"

function getOptions(): Sentry.NodeOptions {
return {
tracesSampleRate: config.env === "production" ? 0.1 : 1.0,
tracePropagationTargets: [/^https:\/\/[^/]*\.apprentissage\.beta\.gouv\.fr/],
profilesSampleRate: config.env === "production" ? 0.1 : 1.0,
environment: config.env,
release: config.version,
enabled: config.env !== "local",
integrations: [
Sentry.httpIntegration(),
Sentry.mongoIntegration(),
Sentry.captureConsoleIntegration({ levels: ["error"] }),
Sentry.extraErrorDataIntegration({ depth: 16 }),
nodeProfilingIntegration(),
],
}
}

export function initSentry(): void {
Sentry.init(getOptions())
}

export async function closeSentry(): Promise<void> {
await Sentry.close(2_000)
}
31 changes: 9 additions & 22 deletions server/src/common/utils/sentryUtils.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,15 @@
import Sentry from "@sentry/node"
import * as Sentry from "@sentry/node"

export const sentryCaptureException = (error: any, options?: object): void => {
Sentry.captureException(error, options)
}

function getTransaction() {
return Sentry.getCurrentHub()?.getScope()?.getSpan()
}

export function startSentryPerfRecording(
category: string,
operation: string,
data?: {
[key: string]: any
}
): () => void {
const childTransaction =
getTransaction()?.startChild({
op: category,
description: operation,
data,
}) ?? null

return () => {
childTransaction?.finish()
}
export function startSentryPerfRecording({ name, operation }: { name: string; operation: string }, callback: () => void) {
Sentry.startSpan(
{
name,
op: operation,
},
callback
)
}
100 changes: 0 additions & 100 deletions server/src/http/sentry.ts

This file was deleted.

2 changes: 1 addition & 1 deletion server/src/http/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { IRouteSchema, WithSecurityScheme } from "shared/routes/common.routes"

import { localOrigin } from "@/common/utils/isOriginLocal"

import { initSentryFastify } from "../common/sentry/sentry.fastify"
import config from "../config"
import { initBrevoWebhooks } from "../services/brevo.service"

Expand Down Expand Up @@ -52,7 +53,6 @@ import version from "./controllers/version.controller"
import { auth } from "./middlewares/authMiddleware"
import { errorMiddleware } from "./middlewares/errorMiddleware"
import { logMiddleware } from "./middlewares/logMiddleware"
import { initSentryFastify } from "./sentry"

export interface Server
extends FastifyInstance<RawServerDefault, RawRequestDefaultExpression<RawServerDefault>, RawReplyDefaultExpression<RawServerDefault>, FastifyBaseLogger, ZodTypeProvider> {}
Expand Down
10 changes: 8 additions & 2 deletions server/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,11 @@ import { config } from "dotenv"
config({ path: ".env" })
config({ path: ".env.local", override: true })

// Dynamic import to start server after env are loaded
import("./main")
import("./common/sentry/sentry.js")
.then(async ({ initSentry }) => {
initSentry()
})
.then(async () => {
// Dynamic import to start server after env are loaded
return import("./main.js")
})
2 changes: 1 addition & 1 deletion server/src/jobs/database/schemaValidation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export async function validateDocuments(collectionName: string) {
const invalidCount = await countInvalidDocuments(collectionName)
if (invalidCount > 0) {
const error = new Error(`Collection ${collectionName} contains ${invalidCount} invalid documents`)
captureException(error)
captureException(error, { level: "fatal" })
throw error
}
}
Expand Down
Loading
Loading