-
-
Couldn't load subscription status.
- Fork 1.7k
2023 and the JavaScript SDK #5878
-
2023 and the JavaScript SDK
As we look toward the next year, we wanted to take some time to write down higher level initiatives we can take a look at:
- Unplugin (expanding the bundlers) https://github.com/getsentry/hackweek-sentry-unplugin
- Isolated exceptions/transactions (micro-frontends/browser extensions/3rd party scripts isolation) [request feedback] Micro Frontend support #5217
- Hub/scopes changes
- Parent child relationship with tracing
- Establishing proper context propogation
- Support different JS runtimes Support different JS runtimes #5611
- Extensible lifecycle hooks for the SDK SDK lifecycle hooks #7262
- Node SDK improvements (async hooks Introduce Async Hooks into the SDK #7691 , v8 instrumentation)
- Sessions in the Browser What is a session? sentry-replay#38
- Sourcemaps improvements
- Becoming community leaders
- Dynamic Loading of SDK functionality
Some of this can only be solved with a new major version, but we've started to think about that: https://github.com/getsentry/sentry-javascript/milestone/15
Unplugin
✅ Done with https://github.com/getsentry/sentry-javascript-bundler-plugins/
Unplugin is a unified plugin system for JavaScript bundlers. Using the unplugin library, we can have a single codebase that support 4 bundlers: Webpack, Rollup, Vite and Esbuild.
Right now we only support Webpack though the Sentry Webpack Plugin, and so by adopting Unplugin, we would get 3 extra bundlers out of the box! Supporting more bundlers leads to better out of the box experience for users - they don't have to worry about figuring out sourcemap uploads or setting up releases.
As per the numbers, combining Vite, Esbuild and Rollup gives us 20 million downloads total, 80% of webpack's total downloads, allowing us to improve the Sentry experience for thousands of orgs and users.
Expanded support for JavaScript bundlers also provides us the opportunity to do more build time manipulation. For example, we had a great amount of success in our NextJS SDK automatically generating and injecting code at build-time to wrap functions for performance monitoring. If we supported every major bundler, we could do similar things for frameworks like React, Vue and Angular. Imagine automatically detecting the most high impact components and wrapping them with Sentry instrumentation - no configuration needed.
None of our competitors are thinking about expanding support for bundlers or exploring this problem space - we'll have a real first mover advantage if we invest here.
Exceptions/Scope Data Quality (micro-frontends/browser extensions/3rd party scripts isolation)
Right now with the current model for the unified API, there are possibilities of data quality issues. These are apparent in two ways.
- Multiple instances of the SDK on a single page
When you are running multiple instances of the SDK on the same page like with (Micro Frontend with multiple apps) or have a chrome extension that runs Sentry on your Sentry instrumented webpage, often times data is not routed correctly to the correct Sentry instance. All current attempts at making this work are unsuccessful - and it's a source of pain from customers. The web can be a wild west - we need to make sure that our SDKs account for these more interesting scenarios.
- Incorrect parent-child relationship between spans
Because of how having multiple hubs/scopes/clients on the same page works, it's hard for us to maintain a proper parent-child relationship between executed spans. In performance monitoring, we associate all spans to the root transaction, which makes it difficult for user to understand execution flows. It also reduces our ability to generate more impactful performance issues.
The root cause of both of these issues are our current hub/scopes model. We don't correctly follow the flow of execution to ensure that exceptions are routed to the correct sentry instance, and scope is applied properly to the correct exception/transaction.
Steps:
- Fix
getCurrentHub()in Node (for ex.setTimeout()does not work). We do this by usingasync_hooksin Node. - Monkey-patch all native async calls + Promises in the browser. This makes
hub.run()work in the browser. - Re-evaluate how global instrumentation works with multiple hubs. How do we route global errors, breadcrumbs to a hub.
- Decide what breaking changes to make for v8 (getting rid of the hub, removing
pushScopeandpopScope)
(Potentially useful for step 2: https://developer.chrome.com/blog/devtools-modern-web-debugging/#linked-stack-traces)
WinterCG Support
WinterCG is a spec for JavaScript runtimes. It essentially describes a base amount of APIs and standards a JS runtime has to follow. As per what they say:
The Web-interoperable Runtimes Community Group (WinterCG) is a community of people who are interested in using Web Platform APIs outside of browsers, namely on the server (Deno / Node.js) or edge runtimes (Cloudflare Workers / Deno).
We only support NodeJS through @sentry/node, but right now it's not possible to support other things because we use NodeJS APIs everywhere. By making changes to how we structure our packages (which Tim describes here: #5611 (comment)), we can make it easy for SDKs for Deno, Cloudflare Workers, and Vercel Edge Middleware (and whatever else comes next) to be built.
This means we can expand our support to more developers - and help push the server-side JavaScript community.
[Before Major] Part 1: Make changes to get it working for errors.
[v8 - Breaking Changes] Part 2: Update tracing package to make it work with performance.
This is also an opportunity for us to get involved early in this working group and help define standards around errors, performance, profiling and more in this community.
Extensible lifecycle hooks for the SDK
✅ Done with getsentry/rfcs#34 and #7262
Recently Sentry announced some exciting news - we would be adding products for Browser Session Replay and Profiling. These products will become new JavaScript SDKs that we have to start looking to support.
These will have to be separate packages though, since we don't want them to be bundled. In browser this is especially important, but for profiling this is important because bundle size also matters for serverless.
One thing we noted was that hooking into the SDK was difficult as the entry points into the SDK were not exposed (@JonasBa for Profiling and @billyvg for Replay to comment more about this). In the SDK we only expose the event processors as part of the integrations API, so Profiling and Replay folks ended up having to monkey patch the API to construct new envelope types and send them to Sentry.
To solve this, and future issues, we can adopt a hook system, where users of the SDK can register callbacks that will be executed by the SDK at various parts of the event processing pipeline.
For example:
Sentry.register('on-session-create', () => {}); Sentry.register('on-envelope-create', () => {});
Node SDK improvements
There are a variety of improvements we can make to the Node SDK to improve reliability, performance, and data quality.
- Adopting Async Hooks. Node Domains are deprecated, and all other APM vendors (including OpenTelemetry) use Async Hooks for instrumentations. Domains are also slow, and can cause unexpected behaviour in complex use cases.
✅ Done with #7691
- Expanding instrumentation by hooking into v8. The Node Profiling SDK hooks into the Native Layer for Profiling. We can use similar bindings to expand instrumentation for both errors and performance monitoring on the Node SDK.
- Introducing specific packages for Node frameworks, like
@sentry/expressand similar.
We can also look at using worker threads.
Sessions in the Browser
Currently sessions in the Browser are page based. Every history change we generate a new session.
With the introduction of a session replay product though, we now have two different semantic meanings of a session. Sessions in the Session Replay product persist between navigations, and even tab switches, since they use SessionStorage to track session state.
Having two definitions about will be very confusing to users (since it means different numbers will show up on the Release Health screen vs. what they are being billed for in Replay) - we need to make sure we align here.
A part of this is also exploring instrumenting user Interactions in the Browser #5750
Sourcemaps Improvements
✅ Done with https://www.notion.so/sentry/Debug-IDs-for-Source-Maps-Brainstorming-66601f1cd5f646a399f9b46fa0dfa3a5
By adopting unplugin, we can look at further improvements around sourcemaps. For example, we could inject metadata at the module level in the browser bundle so that we automatically can associate sourcemaps to errors without needing to rely on a configured release or proper filename.
TODO more ideas
Becoming Community Leaders
At Sentry we're exposed to JavaScript at all levels building our SDKs. We support SDKs for Browser, Node, Electron, React Native, and more, and deal with low/high level APIs in all these platforms. With that domain knowledge, we should work toward getting more involved with the JavaScript community, notably with TC39 and W3C, so we can help push forward our opinions on error tracking and performance monitoring.
Dynamic Loading of SDK functionality
- User Feedback Integration
- React.lazy()
- dynamic imports of integrations?
- dynamic imports of client processing pipeline?
Beta Was this translation helpful? Give feedback.
All reactions
-
🎉 2 -
❤️ 5 -
🚀 8
Replies: 4 comments 5 replies
-
Roadmap
We put together a rough roadmap for the 3 top items listed above. Internal Sentry Notion link.
Unplugin
- [PRE] Update unplugin to add necessary build hooks [Medium Risk, Medium Reward]
- We need this for sourcemaps upload
- Option to fork unplugin if we can’t get our changes merged in
- [PRE] Feature parity with Webpack Plugin [Low Risk, High Reward]
- All the webpack plugin options supported
- PRE because we only release for Rollup, Vite, Esbuild
- Webpack Plugin is blocked on how we decide to approach sentry-cli configuration (
.sentryclirc+sentry.properties+ environmental variables)
- Webpack Plugin is blocked on how we decide to approach sentry-cli configuration (
- Demo: create-vite-app + Vite unplugin just worksTM️
- [BREAKING] Release Webpack Plugin with unplugin [Medium Risk, Medium Reward]
- Need to figure out sentry-cli configuration
- Remove dependency on sentry-cli binary
- [PRE] Use Unplugin Webpack Plugin in NextJS SDK [Medium Risk, Low Reward]
- Deprecate old Webpack Plugin Repo [HAS TO HAPPEN]
- 🫡
https://github.com/getsentry/hackweek-sentry-unplugin
WinterCG + Multiple JS Runtimes
- [PRE] Make it work for the Errors product [Low Risk, High Reward] Support different JS runtimes #5611
- Demo: Have Sentry run on NextJS Middleware and send an error
- [PRE] Have someone from the team join the WinterCG working group [Medium Risk, Medium Reward]
- Demo: a nice #shipped email
- [BREAKING] Make it work for the Performance product [Medium Risk, High Reward]
- Remove
@sentry/tracingfor Node and Browser (no separate package, no extra installation complications, no versioning problems) - Open up opportunity for 1st party WinterCG SDK (NextJS Middleware, Deno)
- Demo: SDK works with Deno
- Remove
TODO: Think about #5886
Exceptions/Scope Data Quality (micro-frontends/browser extensions/3rd party scripts isolation)
- [PRE] Move toward
async_hooksinstead of domains in the Node SDK [Low Risk, Low Reward]- Possible performance improvements, better parent-child reference for spans, removal of deprecated API that people complain about (domains)
- We learn about how hub propagation/scope propagation APIs should work, figure out edge cases, do more research about async context mechanisms
- Demo: Fastify (framework we don’t support) works without explicitly using Domains
- Demo: Compare performance before vs. after
- [PRE] Wrap Browser built-ins (native async methods + Promises) to automatically propagate hub/scope [High Risk, High Reward]
- Same behaviour as using async hooks in Node for the Browser: better parent-child reference for spans, correct hub/scope being used during
getCurrentHubcall. - Possible bundle size impact, have to explore edge cases/unknowns
- Have to think about if this is opt-in or not (can users configure what behaviour they want?)
- Goal: Make
hub.runwork - Demo: Chrome extension can initialize Sentry without interfering with website Sentry
- Demo: Webpack Module Federation Micro Frontend sends errors to correct Sentry instance
- Same behaviour as using async hooks in Node for the Browser: better parent-child reference for spans, correct hub/scope being used during
- [PRE] Out of the box Webpack Module Federation Support [Medium Risk, Medium Reward]
- We automatically wrap modules with
hub.runto isolate them using the Webpack Plugin - Demo: Webpack Module Federation Micro Frontend sends errors to correct Sentry instance without any extra config
- We automatically wrap modules with
- [BREAKING] Rethink Integrations Behaviour + API [High Risk, High Reward]
- How do integrations get registered?
- How do breadcrumbs/spans get routed to a hub? What hub do they go to?
- Managing integrations that monkeypatch vs. integrations that apply event processors?
- [BREAKING] Restructure the hub/scope API [High Risk, Low/Medium Reward]
- Re-evaluate
hub.runvs.withScope - Re-evaluate
pushScopeandpopScope - Re-evaluate
bindClient - Do we need both
ClientsandHubs? - No demo, just better API for users :)
- Re-evaluate
Beta Was this translation helpful? Give feedback.
All reactions
-
👀 4
-
Very excited to see that you're planning a move away from Domains in Node! That should help fix complex issues like #7031.
The "Node SDK improvements" mentions using Async hooks, but the Node docs explicitly recommend migrating away from it. AsyncLocalStorage is almost certainly what you want instead.
Beta Was this translation helpful? Give feedback.
All reactions
-
👍 3
-
Beta Was this translation helpful? Give feedback.
All reactions
-
Making a comment for folks to express interest in official Sentry micro-frontend/microapp support.
Give this a 👍 if you want micro-frontend support to be prioritized!
Per the top-level post:
Isolated exceptions/transactions (micro-frontends/browser extensions/3rd party scripts isolation) #5217
Hub/scopes changes
Parent child relationship with tracing
Establishing proper context propogation
Beta Was this translation helpful? Give feedback.
All reactions
-
👍 38
-
I wrote down #7622 as a preliminary step we should take to make this experience better.
Beta Was this translation helpful? Give feedback.
All reactions
-
❤️ 1
-
Really looking forward for better scope support for http servers. Currently running Apollo and transactions are not relevant / reliable in the current implementation.
Do you guys have an approximative ETA for when this will be released ?
Beta Was this translation helpful? Give feedback.
All reactions
-
@schankam for scope isolation, you can use domains for now. This is not well documented, but see #4947 (comment) for more details.
Beta Was this translation helpful? Give feedback.
All reactions
-
We've also started work on better scope isolation in #7691 - we'll have something you can test with in the next 1-2 weeks!
Beta Was this translation helpful? Give feedback.
All reactions
-
🎉 2
-
Done with https://github.com/getsentry/sentry-javascript/releases/tag/7.48.0 - see our docs on https://docs.sentry.io/platforms/node/configuration/async-context/.
Beta Was this translation helpful? Give feedback.