Open snaumov opened 2 years ago
Hello @snaumov,
We don't allow to use several instances of the SDK on the same page.
However, we are planning to address some use cases related to micro frontend approaches. The general idea would be to have a single instance of the SDK on the page tracking a single application but several services.
We'll keep you posted when we we'll have more details on that.
Any updates on this issue?
I am currently using module federation to build microfrontend. One issue I have is that DD_RUM context gets reloaded and loses its internal context in child app. Similar to the approach above, I will have to set datadog/browser-rum as a singleton in order to get around this issue.
We are still working on improving the sub-app use cases.
One issue I have is that DD_RUM context gets reloaded and loses its internal context in child app
I'm not sure to see why. Care to provide more context on your application? Are you using iframes?
I will have to set datadog/browser-rum as a singleton in order to get around this issue.
DD_RUM should already be a singleton.
We are still working on improving the sub-app use cases.
One issue I have is that DD_RUM context gets reloaded and loses its internal context in child app
I'm not sure to see why. Care to provide more context on your application? Are you using iframes?
I will have to set datadog/browser-rum as a singleton in order to get around this issue.
DD_RUM should already be a singleton.
Hello @BenoitZugmeyer , I use webpack module federation for microfrontend.
This is the minimum reproducible , you can start the code by calling "yarn start" at the root level and then go to http://localhost:3001
.
Link to repo: https://github.com/XiaofengXie16/module-federation
You can see that I initiate datadog in app1's index.js
and then I call datadogRum.setGlobalContext in app2
's button.js.
Now, if I go to the console(chrome devtool) and run DD_RUM.getInternalContext(), I will get an undefined
value.
Let me know if you need any additional info (I am also in the public datadog channel and I am happy to hop on a call if needed)
Note:
Thanks for the project example! Really useful.
So it seems that the Browser SDK is included twice in the resulting bundles
Is this intended? It seems like a lot of unneeded duplicated code.
Because the Browser SDK keeps a module-local state, including it twice on the same page won't work. So now I understand your initial plan of having "to set datadog/browser-rum as a singleton in order to get around this issue." If you have the possibility to do so, it would be a great solution.
Thanks for taking a look, i think that's how module federation works. If you don't mark your dependencies as singleton, it will include its own copy of dependency.
To your point, yes, I can run it as singleton by using the singleton property listed in here : https://webpack.js.org/plugins/module-federation-plugin/#singleton
It will probably be great if this use case is documented in the datadog documentation.
Update: This branch contains the code that illustrates the solution: https://github.com/XiaofengXie16/module-federation/tree/fix-dd-issue
Is there any updates on this, @bcaudan ?
Hi,
No updates on this topic and given the underlying complexity, it is probably not something that we will address soon. Some issues could be solved with this approach if it is one day available but we may have workaround for issues that you are facing.
Please open an issue describing what you are trying to achieve and we would be happy to help there.
I see this issue has been open since 2021. do you have any update for it, please?
No update yet. Loading the SDK code multiple times on the same page would not be practical. If you have a specific use case in mind that is not yet listed in our issues, feel free to open a new one.
One use case is the ability to correlate logs with their services (micro frontends). If a browser client gets initialized only once, only the first micro frontend will initialize it and set the service
(Logger Name) value. This renders the service catalog in datadog less useful for frontend code.
In this view https://app.datadoghq.com/services , the logs get associated with a service only when initial service
tag matches the service name.
I have tried to override the service
tag when sending specific log lines to DD, but that doesn't allow for APM and log correlation. May be the correlation logic could be fixed, to allow correlation by additional tags?
I have a use case: If you build a JS sdk and want to log/track method invocation counts or metrics telemetry style data.
If the host site uses datadog, you can not use data-dog for browser logging in your SDK. I do not understand the need to make this object a global singleton because it prevents this use case.
Comment on "use a Singleton" discussed above: Not a solution, because not always possible. We have a micro frontend setup and each host page pulls in the DD SDK. Depending on the exact page, they pull in different major versions - that means, the version that would be shared with my team's micro frontend included on the host page, could be a diff major version depending on page we're on - and that obviously doesn't work, as the major versions are incompatible with each other!
That, of cause, in addition to the above mentioned limitations when using a Singleton, such as not being able to change certain fields and correlate/trace services e2e which we've been encountering, too.
@BenoitZugmeyer thoughts?
I have a use case: If you build a JS sdk and want to log/track method invocation counts or metrics telemetry style data.
I'm sorry but the SDK is not designed for this use-case, at least for now.
We are still evaluating how to better support MFE use cases. That being said, having multiple SDK instances on a single page presents a few drawbacks and should probably be avoided:
if your applications bundles different copies of the SDK, it will increase your JS bundle size significantly.
because the SDK is designed to monitor a page globally, each instance will instrument and collect data on its own. Each instrumentation can have a performance impact (CPU, memory), and sending duplicated data might clutter the bandwidth, especially when we need to send data quickly on page exit, reducing the data reliability.
Wouldn't both of these drawbacks be the responsibility of the developers to keep in mind and be aware of, not the library sdk?
the multiple versions --> yes, in some cases if a page framework allows for that, devs should be mindful of this case. It's on developers to create a good solution for this infra, not the sdk's. This would be a problem with any JS library bundled in MFE. In our case, we disallow different versions of any library (at infra/bundling level). On top of that use shared chunks for certain commonly needed libraries (resulting in only one library instance on the page).
As for global instrumentation, the limitations and impacts on perf can be communicated via docs, and developers can make decisions on whether one global instance or several instances make sense for their development practices and page frameworks. Not all log collection features make sense for single instance. I can see that console log collection is best for single instance, but not everyone uses that feature. May be few other features make more sense for single vs multiple instance , but leave it up to devs to make the decision on SDK usage.
I think there are two flawed assumptions on behalf of the SDK here.
So for MFE use cases, is it feasible to have a global datadog rum instance but changes the service tag in each micro frontend service with the same instance by using startView
?
So for MFE use cases, is it feasible to have a global datadog rum instance but changes the service tag in each micro frontend service with the same instance by using startView?
If each MFE are running one after the other, yes it's possible (doc)
@BenoitZugmeyer what if we want to use a different application (by changing the applicationId
and clientToken
properties) for each microfrontend?
Logging all events to a single DD application could be problematic for security reasons, as each microfrontend is managed by different teams.
Hi @michalkotas, Currently, for a single SDK instance, the microfrontend ownership is down by service. You can define a service for each view (doc) If you want a different app per microfrontend, you need to have one microfrontend per page load, so you can initialize the SDK with the correct app configuration.
So to be clear, for those of us (in the majority) that have more than 1 microfrontend on the page at a given time... there is no way to set the service for each addError
such that two errors happening at the same time have different service
names right?
Because from what I can tell, setting the service (via what... startView
?) is a global affair which means that we're in a race-condition as to which microfrontend set the view name most recently.
@dgreene1
What we're doing as a workaround is wrapping each addError
call in a function that first does a startView({ service, version })
, then a call to addError
and immediately afterwards datadogRum.startView({})
to reset the service/version.
This way there shouldn't ™️ be any race conditions as this all happens in a single execution loop.
Hi!
We're looking to use
datadog-logs
in a microfrontend application. Is it possible to have a several instances ofdatadog-logs
on a single page (so the logs would be sent to differentapplicationId
s)?UPD: we might be able to get away with a single instance of DD, and contextualize the logging with the application name, so it's logged in a central place, but we can filter out by the application.