Closed rramaa closed 5 months ago
Ahhh yes here it is! As the creator of module federation, this is a biiiig area of opportunity to support
We have the same issue here in our company. We moved our product to full site federation with ModuleFederation. (thank @ScriptedAlchemy for that! Really awesome!)
Looking to bump this.. is it possible to update the DSN or have a part of the react tree point to another sentry DSN. Since my components are loaded from different teams, I want sentry to report back to the various DSNs that represent the workstreams
For example:
I have a product
page hosted by one application. It can run "standalone" and SSr itself.
I have another app with checkout
.
instead of reinstalling a npm package or something to distribute the code, creating drifting duplicates. Im able to use module federation to import the checkout-modal
from checkout
and render it inside product
page. Now id an error is thrown in the checkout modal, the checkout team likely needs to be paged because the consuming team just places the <Modal>
So when a team-owned component fails, I need to report to the owning team that its errored and where.
Hello there!
Is there any progress or official statement from the Sentry team on giving support to Module Federation any time soon?
Maybe any workaround allowing us to use multiple DSNs within the same app?
Cheers!
Also looking for an update on this.
We haven't look into this yet, so there's nothing I can say tbh.
Looking to bump this.. is it possible to update the DSN or have a part of the react tree point to another sentry DSN. Since my components are loaded from different teams, I want sentry to report back to the various DSNs that represent the workstreams
This would currently require multiple clients, as detailed here: https://docs.sentry.io/platforms/javascript/troubleshooting/#using-a-client-directly It won't play nicely with propagating breadcrumbs throughout all those clients. This is something that we are working on, and there's currently no easy workaround for this.
Solved this problem. https://scriptedalchemy.medium.com/distributed-logging-in-federated-applications-with-sentry-f4249aa66e20
We use a similar approach of binding hubs to error boundaries on the micro-frontend level. Does your approach work with breadcrumbs? We managed to send them via integrations
and building a custom integration to catch breadcrumbs in hubs instead of the global scope, but it's a lot of custom code. Would be really nice to get such functionality from the library itself.
Is there any news here? Is this being worked on?
@devbucket there are ways on how to go about this. Check out this blog post - https://scriptedalchemy.medium.com/distributed-logging-in-federated-applications-with-sentry-f4249aa66e20
@vladanpaunovic Thanks. I know about this. But this is not really a solution but a rather complex workaround. It would be great to have an official solution to this problem.
Agreed. It's a workaround. However if someone reviewed my implementation - it likely could be simplified. I just wrote something that worked in a single pass and moved on to other problems.
Still a solution would be nice. Something like a way to register who owns a file even based on document.currentScript.src or at least a even bus so I can throw errors to the singleton with metadata attached and reroute them to the right DSN with a single handler instead of registering multiple clients and doin it at the function level.
I just have one question :) Is the Sentry development team looking into the issue already? or is this issue only in the backlog?
@AndreiSoroka I am not part of the Sentry team, but I messed around here https://github.com/getsentry/sentry-javascript/pull/5420 to figure out how to make it work in Sentry.
I left a question there for me to continue moving forward.
@yordis Yes, I read your thread. Cool! I'm more to the fact that the issue was opened in 2021. But I didn't see any response/reaction from the Sentry developers [¯_(ツ)_/¯]
@AndreiSoroka, a few of us are looking into this one actually :)
We don't have an ETA at the moment as we are focused on resolving other issues. As soon as we know more about this one, we will notify folks here.
@vladanpaunovic would love to see if we can collaborate on this. Lululemon is a paying customer of sentry and I am the author of Module Federation. I'd be interested to engage with the sentry team and help solve or provide internal knowledge on how we can manipulate MFP if need be. Also have a $40bn company that I'm willing to test this against. In production. 🧑🔧
May I be of assistance? How could we connect?
@ScriptedAlchemy, sounds amazing!
Can you reach out to me on Sentry discord?
@vladanpaunovic @ScriptedAlchemy Hi! Have you contacted each other? Do you have a forecast solution?
I reached out on discord but no response yet. @vladanpaunovic whats your handle? Maybe I'm Dming someone else lol
I strongly consider this feature a MUST that the Sentry product should adopt in the short-term. Every days more companies such as mine are adopting Microfrontends and the observability by scope is absolutely necessary. Please, if the Sentry could encourage to start work together with @ScriptedAlchemy in an integrated solution we will be very grateful. Thanks! We'll stay tuned
Hey folks, I didn't post an update as I had some distractions and frankly, there is nothing to update just yet.
Currently, our team is having various discussions on how to proceed with this topic. Microfrontends are important to us and definitely something we want to better support in the future. However, doing that properly comes with challenges from within our own codebase which we are trying to figure out these days.
@ScriptedAlchemy, yes, the handle is correct. I will get back to you. 😄
Much love. I'll keep an eye out.
Agree here - this is not something that should be rushed. Distributed logging and observability in 1) MFE and 2) federated applications each present architectural challenges.
Polylith log distribution is not something a tool like sentry has needed to really offer as such capabilities were virtually impossible till recently.
With federation fully supported in node runtimes, the need for observability becomes more apparent.
I think there's Two tracks we can take here. Depending on sentry teams capacity, im more than happy to put my resources behind the efforts.
1: we could document and create a reference repo showcasing how to accomplish distributed logging within the existing constraints of sentry today. I wrote a article a while ago which was just a hour or two of tinkering. That likely can be refined; but it does work and still powers my prod apps. We can overcome alot of setup with a little help from a webpack plugin - allowing a lower barrier to entry for a solution that'll tie us over till sentry core can be adjusted. This would be low effort but would alleviate alot of struggles the community is facing right now.
2: perhaps we could get a working group or collaboration together to talk about the direction or challenges we need deal with in sentry core.
I've got skin in the game & heavily entrenched in sentry ecosystem - no plans to move away so if there's anything i can offer to help... I'm in.
I mostly work on the webpack core. We can make a powerful integration with federated applications BUT whatever we put forward needs to be agnostic. I'm working on bundler agnostic Federation & beyond my tech - there's others like single spa that we would want to ensure elegant solutions for.
From a webpack standpoint though, I can likely build out a great integration which would be a cherry on top of a solid core implementation that's not coupled to a compiler
I would be very interested in this reference repo that you mentioned @ScriptedAlchemy if it's ever come to life :) As I'm looking for a better integration than our current Datadog solution which doesn't seems to consider microfrontend yet. Thanks !
@ScriptedAlchemy hey, have anything of what you described in the last message been done?
Thanks for your article btw 🙂
For the backend, we've recently added runWithAsyncContext
to @sentry/node
which gives full scope isolation across async contexts via AsyncLocalStorage
in Node >= v14. While the primary use case for this is to isolate Sentry scope between requests, It could probably be used to isolate scope between components during SSR too.
If the tc39 async context proposal makes it into browsers we'll be able to support the same runWithAsyncContext
API there too...
I don't think it's made it into a release yet, but we've just added a means to route events to different DSNs depending on your own custom logic. It's pretty bare-bones for now and not tailored to any specific use case but with some code it could for example allow you to route events from different error boundaries to different DSNs without creating multiple clients.
For uncaught errors, and errors not caught by error boundaries, @ScriptedAlchemy highlighted docuement.currentScript.src
and I managed to put a basic PoC together which links uncaught errors to the module they came from via script URLs.
With the following shared code:
import { EventProcessor, Exception, Integration } from "@sentry/types";
declare global {
interface Window {
__SMF_MODULES__?: Record<string, string>;
}
}
export function registerModule(moduleName: string, moduleUrl: string) {
if (!window.__SMF_MODULES__) {
window.__SMF_MODULES__ = {};
}
window.__SMF_MODULES__[moduleUrl] = moduleName;
}
function getFirstModuleFromException(exception: Exception): string | undefined {
// Sentry frames have the top of the stack at the end of the array
const reverseFrames = exception.stacktrace?.frames.reverse();
for (const frame of reverseFrames) {
const mod = window.__SMF_MODULES__[frame.filename];
if (mod) {
return mod;
}
}
}
export class ModuleFederationIntegration implements Integration {
public static id: string = "ModuleFederationIntegration";
public name: string = ModuleFederationIntegration.id;
public setupOnce(
addGlobalEventProcessor: (callback: EventProcessor) => void
) {
addGlobalEventProcessor((event) => {
if (event.exception?.values[0]) {
const mod = getFirstModuleFromException(event.exception?.values[0]);
if (mod) {
event.tags = {...event.tags, module: mod};
}
}
return event;
});
}
}
Add the integration in your root app:
Sentry.init({
dsn: '__DSN__',
integrations: [ new ModuleFederationIntegration() ]
});
In the top of every exposed module, register the module name and script src URL:
registerModule('component-1', document.currentScript.src);
Then once an uncaught error comes through the Sentry event pipeline, the ModuleFederationIntegration
inspects the stack frames and adds a module
tag for the first registered module found.
If you then want to route these to different DSNs, the newly added multiplexed transport could convert tags to DSNs.
Hi all,
We have been taking some steps in recent months to investigate how we can provide better support not just through our SDK but also looking at webpack and module federation. Please see the work here and we'd love to hear your thoughts!
https://github.com/getsentry/sentry-javascript-bundler-plugins/issues/323
This is now documented with https://docs.sentry.io/platforms/javascript/best-practices/micro-frontends/
If you have any questions - please open a new issue! Things have changed a lot since this was originally created so a new issue will be easier for us to track and triage accordingly.
could I leave you a small comment: guys, you are awesome!
Webpack recently released module federation. Using this plugin, one can deploy multiple web apps(which may or may not be related framework wise) in a single webpage seamlessly.
Though this is great, it is now not possible to track JS errors as errors may occur in any part of the code. Sentry intercepts errors at a global level. That error is tagged with a release version and the sourcemaps related to that release is used for displaying the real source.
But now since error source can be any part of the code and that part can have different release versions, how can I communicate the release version to sentry so that my error can get successfuly decoded by the sourcemap.
Currently is there any way to tackle this problem?
Issue in webpack's repository https://github.com/webpack/webpack/issues/12706