Hello
The strapi-plugin-sentry
works greate but it does not support the Performance Tracing functionality, so I decided to implement it myself.
I followed their documentation (Koa | Sentry Documentation) and ended up with a middelware that works with the strapi-plugin-sentry
installed.
const {
extractTraceparentData,
Span,
stripUrlQueryAndFragment,
} = require("@sentry/tracing");
const domain = require("domain");
// not mandatory, but adding domains does help a lot with breadcrumbs
const requestHandler = (ctx, next) => {
const sentryInstance = strapi.plugins.sentry.services.sentry.getInstance();
return new Promise((resolve, _) => {
const local = domain.create();
local.add(ctx);
local.on("error", (err) => {
ctx.status = err.status || 500;
ctx.body = err.message;
ctx.app.emit("error", err, ctx);
});
local.run(async () => {
sentryInstance.getCurrentHub().configureScope((scope) =>
scope.addEventProcessor((event) =>
sentryInstance.Handlers.parseRequest(event, ctx.request, {
user: false,
})
)
);
await next();
resolve();
});
});
};
// this tracing middleware creates a transaction per request
const tracingMiddleWare = async (ctx, next) => {
console.log("tracingMiddleWare called");
const sentryInstance = strapi.plugins.sentry.services.sentry.getInstance();
const reqMethod = (ctx.method || "").toUpperCase();
const reqUrl = ctx.url && stripUrlQueryAndFragment(ctx.url);
console.log(
"sentryInstance.getCurrentHub()._stack[0].client",
sentryInstance.getCurrentHub()._stack[0].client
);
// connect to trace of upstream app
let traceparentData;
if (ctx.request.get("sentry-trace")) {
traceparentData = extractTraceparentData(ctx.request.get("sentry-trace"));
}
const transaction = sentryInstance.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
sentryInstance.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 || "";
transaction.setName(`${reqMethod} ${mountPath}${ctx._matchedRoute}`);
}
transaction.setHttpStatus(ctx.status);
transaction.finish();
// console.log("transaction done 2", transaction);
});
});
await next();
};
module.exports = (strapi) => {
return {
initialize() {
strapi.app.use(requestHandler);
strapi.app.use(tracingMiddleWare);
},
};
};
But (as you may guess) it does not work . The middleware seems to work well, but can’t manage to get the data in the Sentry Dashboard. Do you see anything weird with my translation from Koa to Strapi Middleware looks right or I’m missing something.
( I posted a question on the Sentry documentation also Sentry Tracing Node appears to work but noting logged, how to debug? - SDKs - #sentry)
Thanks!