84 lines
2.4 KiB
TypeScript
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()
|
|
}
|