-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(core): Add multiplexed transport #7926
feat(core): Add multiplexed transport #7926
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Approach makes a lot of sense to me
Tim another thing we need to make sure works is the use case in #7622 (comment), where matches can be added on demand. Is this easiest way to do this to add to just make them enforce a global they mutate? Or should we think about exposing a separate API? |
IMHO it should be good enough to do this via some closure state that can be mutated, like: const myDsns = [
{ dsn: 'https://...', tag: 'my-tag' },
{ dsn: 'https://...', tag: 'other-tag' },
];
function dsnFromTag({ getEvent }) {
const event = getEvent();
const opt = myDsns.find(({tag} => event?.tags?.includes(tag));
return opt ? [opt.dsn] : [];
}
init({
dsn: '__FALLBACK_DSN__',
transport: makeMultiplexedTransport(makeFetchTransport, dsnFromTag)
});
// later, just modify myDsns ? |
Yeah I think thats fair, we just have to make sure we have good docs then! |
Yes I think so. When I started coding this it was much more complex with an array of matcher functions but then I started thinking about match order and decided to simplify the API and leave more complex/niche scenarios up to users. |
@mydea question about this implementation vs. the flex-micro approach in https://github.com/sentry-demos/sentry-micro-frontend. With this multiplex approach, can each component bring its own @AbhiPrasad, my comment in #7622 (comment) was for supporting micro-frontends in a federated environment. This seems to be one of the more popular, if not "the" requirement for micro-frontends #5217. The tag delegation/multiplex approach does not look like it will work with those looking for federated micro-frontends. Each of my micro-frontends is developed by their teams with their own call to Sentry.init. The host(s)/document should mostly be unaware of Sentry for micro-frontends displayed. The only thing I can think of is creating an internal |
@amccloud There should only be a single
This seems like a good strategy to me. The way this would work then is that the host app would consume a function that calls We are putting the onus on the implementors to define how global state should be stored, as it gets complicated if the SDK does this. I can add this as a note to the dcs. Another things to think about is to use the stacktrace to determine what module you are in. See @timfish's example in https://github.com/timfish/sentry-module-federation
Unfortunately the way the browser works is that we can't isolate breadcrumbs/scope to a specific part of the web app. So if that micro-frontend throws an error, it bubbles up to the global error handler. In addition, we can't differentiate between breadcrumbs created (for ex. by a fetch request) by that micro-frontend vs. another one. |
@AbhiPrasad thanks for the reply.
I have a fork of flex-micro with most plugins working in isolation across 2 components and a host. All of which bring their own Sentry module through module federation when necessary. I think breadcrumb isolation could be accomplished with an approach like zone.js. This was next and last on my list to explore. To your point, this can all be done in another lib and doesn't need to be supported by this lib. Instead of electing a leader like with flex-micro, I see the more explicit route forward here where if a host adopts Sentry we can pass their instance of Sentry to micro-frontends to modify and register their multiplex preference. Maybe just as a global or through an interface of their choice. Ideally, hosts and micro-frontends consume the same hypothetical What is not clear is who owns plugins, performance data, and event quotas? I wouldn't want to multiplex navigate/pageload events unless the duplication is deduped/free or isolated for each micro-frontend. |
We are going to explore this ourselves, but to most users it's not feasible due to the bundle size impact and runtime performance costs. Angular themselves are switching away from Zone and change detection to use signals.
Yeah we're struggling with this as well. Another issue here is that re: breadcrumb isolation, many folks actually told us they don't want it to be isolated, and seeing dom event/http request breadcrumbs from other micro frontends help with debugging. |
Thanks for this change 🙂 Had a q around this message from @AbhiPrasad earlier in the thread, happy to post this elsewhere if need be:
Our MFEs each have their own Sentry project and upload their own sourcemaps to those projects. We set a If we use this multiplex approach we can drop the custom client/hub for each MFE, but does that mean we'll have to explicitly set |
Yes, the release will need to be overridden, but not necessarily manually at the capture point, it could occur for example in an integration. There's no official code to support this yet but as Abhi mentions above, I've been looking into routing to specific dsn/release via inspecting the filenames on the stack trace. |
Closes #5185
Adds
makeMultiplexedTransport
which can be used to create a Transport that sends envelopes to different, even multiple DSNs depending on the content of the envelope.It takes two parameters:
Currently, the DSN passed to init is used as a fallback if the match callback returns zero DSNs. I'm not 100% happy with this as in the example below, the DSN passed to init will never be used but is required for the client to send events.
Send everything to two DSNs
Override DSN from capture point
Different DSNs for different features