mon-entreprise/api/source/sentry.ts

84 lines
2.4 KiB
TypeScript

import { RouterContext } from '@koa/router'
import Sentry from '@sentry/node'
import { stripUrlQueryAndFragment } from '@sentry/utils'
import { Context, Next } from 'koa'
const release =
(process.env.APP ?? '') +
'-' +
(process.env.CONTAINER_VERSION ?? '').substring(0, 7)
Sentry.init({
dsn: 'https://21ddaba2424b46b4b14185dba51b1288@sentry.incubateur.net/42',
// Set tracesSampleRate to 1.0 to capture 100%
// of transactions for performance monitoring.
// We recommend adjusting this value in production
tracesSampleRate: 0.5,
release,
environment: release.includes('api-pr') ? 'test' : 'production',
integrations: [
// Automatically instrument Node.js libraries and frameworks
...Sentry.autoDiscoverNodePerformanceMonitoringIntegrations(),
],
})
export default Sentry
export const requestHandler = async (ctx: Context, next: Next) =>
Sentry.runWithAsyncContext(() => {
const hub = Sentry.getCurrentHub()
hub.configureScope((scope) =>
scope.addEventProcessor((event) =>
Sentry.addRequestDataToEvent(event, ctx.request, {
include: { user: false },
})
)
)
return next()
})
// this tracing middleware creates a transaction per request
export const tracingMiddleWare = async (ctx: RouterContext, next: Next) => {
const reqMethod = (ctx.method || '').toUpperCase()
const reqUrl = ctx.url && stripUrlQueryAndFragment(ctx.url)
// connect to trace of upstream app
let traceparentData
if (ctx.request.get('sentry-trace')) {
traceparentData = Sentry.extractTraceparentData(
ctx.request.get('sentry-trace')
)
}
const transaction = Sentry.startTransaction({
name: `${reqMethod} ${reqUrl}`,
op: 'http.server',
...traceparentData,
})
ctx.__sentry_transaction = transaction
// We put the transaction on the scope so users can attach children to it
Sentry.getCurrentHub().configureScope((scope) => {
scope.setSpan(transaction)
})
ctx.res.on('finish', () => {
// Push `transaction.finish` to the next event loop so open spans have a chance to finish before the transaction closes
setImmediate(() => {
// if using koa router, a nicer way to capture transaction using the matched route
if (ctx._matchedRoute) {
const mountPath = (ctx.mountPath as undefined | string) || ''
transaction.setName(`${reqMethod} ${mountPath}${ctx._matchedRoute}`)
}
transaction.setHttpStatus(ctx.status)
transaction.finish()
})
})
await next()
}