Replies: 1 comment 1 reply
-
Hi, I have been looking at different APMs lately for work and finally decided to settle with sentry. Was having issues with transaction names, saw a couple of issues and finally got to this discussion. Mostly the issue was with nested routers and pretty much our whole server is built using those. I checked out quite a number of issues mentioned in the above post, saw a bunch of articles and looked into some other projects and finally decided on patching express. I think this reply is closest to what ended up doing and this seems like the best option to go with in my opinion. So, basically, I have patched I have tested it with node18, express v4.18.2, and sentry v7.35.0. Haven't faced any issues as of yet. I haven't fixed the array issue in this right now but should be doable, I guess. I have put the express patcher in a package if anyone wants to check it out - px5 (it's quite messy 😅). Hoping something like this is added to the agent soon. |
Beta Was this translation helpful? Give feedback.
-
Background
In this (meta) Issue, we would like to summarize and categorize different opportunities to improve Sentry support for Express. Most things are related to Sentry's performance monitoring product but in case we come across improvement opportunities for error monitoring, we're more than happy to collect them here.
Improvement Opportunities
The following sections list possible improvements for Express
Transaction names and URL Parameterization
We recently improved URL parameterization in #5450. Briefly summarized, we patch the Express router prototype to get to a fully parameterized route before that route's handler callback is executed. This solution isn't perfect (there are still timing issues) but it's probably the best we can do for now.
(In theory, we could explore building a tree of all possible routes and then matching incoming request URLs against this tree (with Express's matching strategies), but IMO we shouldn't open this box as it has a lot of potential to turn into an edge case nightmare without any guarantee for success. Possibly related: #5050)
Parameterization termination criterion
One thing we could look into, would be a detail in our current router instrumentation: The criterium that determines when we have reached the "last" partial route and hence the full parameterized route was found. We currently do this by comparing the number of URL segments in the incoming vs. the accumulated parameterized route. This approach clearly has its limitations (e.g. it being brittle with regex and array routes).
Transaction names of array routes
If users currently have a route defined with an array of paths (which can be strings or regexes (mixed)), like so:
The resulting transaction names they get will be a concatenation of all items in the array:
One could argue that this is not a nice transaction name because it is not clear which item of the array actually matched the incoming array. Instead, a transaction name like so might be better:
For more info and explanations see #5489
It's important to note that a change here does not improve transaction name cardinality. In fact, it would slightly increase the number of transactions because we would create separate (but still parameterized) transactions for each item in the routes array.
Express 5
Express 5 has been in beta for quite some time but we were recently notified that our new router instrumentation caused problems there (see #5501). For now we simply disabled early URL parameterization for the case that we don't encounter Express 4. Besides adapting our router instrumentation in the future for Express 5, we should investigate what else needs to be done to support Express 5.
For more information, see #5501
Span Creation in Nested Routers
Due to a timing conflict when nested routers are initialized vs. when Sentry is initialized, we mostly fail to instrument the registration methods (
router.get(...)
) of nested routers. These methods are usually executed when the nested router is imported, which happens beforeSentry.init
is called. This leads to missing spans of the child routers because we do not instrument the callbacks.More context: #3155
Proper
@sentry/express
packageWe've discussed creating a
@sentry/express
package that builds on top of@sentry/node
. Currently, our Express-specific support is limited to the Express integration users add to the Node SDK. Transactions are e.g. created in the Node SDK (in thetracingHandler
middleware) and middleware spans + transaction parameterization happens in the Express integration.This has already been requested by the community: #4700
Potential pros/cons:
+ Signals proper Express support (similarly to what we intend to do for Svelte)
+ Gives us the possibility to add more express-specific stuff without cluttering (or also influencing) the Node SDK used in other frameworks
+ Might help us to declutter the Node SDK/define more clearly what's Express-specific and what was just added on top
+ Lets us declare express versions as peer dependencies
+ Gives us the possibility to track Express SDK vs. rest of Node SDK usage
- What about other frameworks that build on top or are similar to Express (Koa, Connect)
- Are there dependencies between Express stuff and NextJs/Serverless?
~ We'd probably need to de-unify types (e.g.
CrossplatformRequest
) which might lead to a small portion of duplicated code. This, however, might not be too bad (or worth the sacrifice) considering that the type is problematic atm (#5768)Misc; Bugfixes
Call for Feedback
As always, we'd appreciate feedback! Have you been using our Node SDK (with Express) and you would like to see something changed or some feature implemented? Please let us know! Also, which of the items listed above would be most important to you?
Please feel free to give this post a 👍 if you would like to see us dedicating time to improving Express. Community feedback helps us prioritizing what to work on next.
Beta Was this translation helpful? Give feedback.
All reactions