I want to start adding auto instrumentation for WebTracer and as first thing would be simply the document load. But together with this I'm thinking of the architecture and how to structure things.
NodeTracer (TracerSDK) does this by creating a PluginLoader which is kind of cool and I thought that maybe thats the way to go. Then the first plugin for web tracer would be something like document-load. But then I was also thinking where it should be located. Probably some of the plugins can be shared between node and browser but not all of them. Now we have just opentelemetry-plugin-* and I wonder if that will be appropriate place or we should rather have a separate namespace and then even if some plugins can be shared we can simply reference them. I think that would be a cleaner solution so it will look like:
opentelemetry-plugin-web-* ?
and for the first plugin it would be something like :
opentelemetry-plugin-web-document-load
Any thoughts , objections, suggestions :) ?
The plugins then would be lazy loaded so they won't be bundled together with WebTracer. The Plugin Loader would be responsible for that
Would we then have opentelemetry-plugin-node-* for things that are specific to node?
As it is possible to have some of the plugins shared between node and browser, I would suggest to follow opentelemetry-plugin-* pattern.
We will have more and more plugins in a future and it might be misleading which one is supported in browser only and which one in node only or both. Just looking at repo now we already have 3 plugins for http, are they going be all supported in browser too ?
The 3 that exist are for the Nodejs standard library modules and afaik browser support for them is N/A
Maybe the plugins could be folder organized based on their supported environments: nodejs/opentelemetry-plugin-mongodb, web/opentelemetry-plugin-document-load, js/opentelemetry-plugin-purejslibrary
My main suggestion here is that we don't rely on plugins as runtime objects or any kind of require function usage, since I think that could put limits on how people bundle their code. E.g. webpack, Rollup, Closure, etc. all support ES6 modules but may collapse them down into a flattened code bundle rather than having them as runtime objects.
What if the plugin model looked something like this:
const opentelemetry = require('@opentelemetry/core');
const { WebTracer } = require('@opentelemetry/web');
const { DocumentLoadPlugin } = require('@opentelemetry/web-document-load');
const { UserInteractionPlugin } = require('@opentelemetry/web-interaction');
const { XhrPlugin } = require('@opentelemetry/web-xhr');
const { ReactPlugin } = require('@opentelemetry/web-react');
const tracer = new WebTracer({
plugins: [
new DocumentLoadPlugin(),
new UserInteractionPlugin,
new XhrPlugin({ hostRegex: '.*' })
]
});
opentelemetry.initGlobalTracer(tracer);
This way we are just using the normal import system and passing the plugins to the tracer as objects rather than trying to hook into the module system, which I think is good for Node, but feels hacky in the browser to me.
Most helpful comment
My main suggestion here is that we don't rely on plugins as runtime objects or any kind of
requirefunction usage, since I think that could put limits on how people bundle their code. E.g. webpack, Rollup, Closure, etc. all support ES6 modules but may collapse them down into a flattened code bundle rather than having them as runtime objects.What if the plugin model looked something like this:
This way we are just using the normal import system and passing the plugins to the tracer as objects rather than trying to hook into the module system, which I think is good for Node, but feels hacky in the browser to me.