Skip to content

feat(sdk): add instrumentations config option to the SDK - #415

Merged
overbalance merged 3 commits into
open-telemetry:mainfrom
manototh:feature/instrumentation
Sep 10, 2026
Merged

feat(sdk): add instrumentations config option to the SDK#415
overbalance merged 3 commits into
open-telemetry:mainfrom
manototh:feature/instrumentation

Conversation

@manototh

@manototh manototh commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Which problem is this PR solving?

If you want third-party instrumentations, you currently have to call registerInstrumentations() yourself after startBrowserSdk(), wire up the providers manually, and remember to deregister them on shutdown. This is easy to get wrong and duplicates logic the SDK could own.

This PR lets you pass instrumentations directly to the SDK.

Short description of the changes

  • Add an instrumentations option to the SDK config. The SDK registers instrumentations once the global providers are set and disables them on shutdown. Instrumentations aren't registered when the SDK is disabled or the export URL is invalid.
  • Add@opentelemetry/instrumentation@^0.221.0 as a dependency of @opentelemetry/browser-sdk.
  • Update docs and migrate the sandbox to pass its instrumentations through the new option instead of calling registerInstrumentations() manually.

Type of change

  • New feature (non-breaking change which adds functionality)
  • This change requires a documentation update

How Has This Been Tested?

  • Unit tests
  • E2E tests
  • Typecheck, ESLint, Biome
  • Build
  • Manual test with sandbox

Checklist:

  • Followed the style guidelines of this project
  • Unit tests have been added
  • Documentation has been updated

@manototh manototh changed the title add register instrumentations feat: instrumentations config option Sep 2, 2026
@manototh manototh mentioned this pull request Sep 2, 2026
8 tasks
@manototh manototh changed the title feat: instrumentations config option feat(sdk): add instrumentations config option to the SDK Sep 2, 2026
@manototh
manototh marked this pull request as ready for review September 2, 2026 12:08
@manototh
manototh requested a review from a team as a code owner September 2, 2026 12:08

@joaquin-diaz joaquin-diaz left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! Thanks for adding this! 🚀

@david-luna

Copy link
Copy Markdown
Contributor

@manototh yesterday we had a discussion about the registering of the instrumentations. Why? because the register function from @opentelemetry/instrumentation package has some hidden logic. Let me explain

Instrumentations have a logic in the base class constructor. The constructor inspects the configuration passed and decides to enable itself or not depending on the enabled property. So the following expression

const instr = new MyInstrumentation({ enabled: false });

gives you an instrumentation instance that is not enabled an therefore not emitting LogRecords or starting Spans.

What happens with registerInstrumentations function?
The function does a couple of things:

  • sets the providers (logger, tracer & meter) to each instrumentation
  • checks for non enabled instrumentations ({enabled: false}) and enables them

I brought it up the the SIG yesterday since I think this might be misleading for devs. They might want to start the SDK with only a subset of instrumentations enabled so they may think the following code prevents the SDK for sending web vitals.

const fetchInstr = new FetchInstrumentation(),
const vitalsInstr = new WebVitalsInstrumentation({ enabled: false }), // <- expecting this to not collect events

startBrowserSdk({
  // other config options
  instrumentations: [ fetchInstr, vitalsInstr ],
});

// to actually not collect data we should do this after starting the SDK
vitalsInstr.disable();

To make thins more complex the enable method is not only responsible to control the state of the instrumentation but also it does the patching of browser APIs if required. Since other scripts in a web page can also patch these APIs we may want to do the patching regardless if the instrumentation is enabled or not. This way the SDK can signal the instrumentation to patch early (before any other script does) and defer the decision to enable (emit data) or not.

We are going to keep the discussion in this PR. As for now there is a initiative to refactor the instrumentation base class in #278

@david-luna

Copy link
Copy Markdown
Contributor

I wasn't part of the project when the instrumentation package was created so I do not know the context then. Here is my 2cts.

I guess the enable call at constructor time (which internally calls init) was necessary to register the require/import hooks as soon as possible. This may be not necessary now that node offers --import CLI option to preload the SDK. In browsers we do not have a CLI option but we have ways to ensure the SDK is the 1st script to load (position in the HTML file, ...).

In this new context (we can ensure SDK is loaded 1st) we can see enable does 2 different things:

  • instrument/patch the targeted technology or API
  • set the instrumentation in a state that allows the creation of Spans & LogRecords

IMHO patching and enabling are 2 different operations. We want to do the 1st as soon as possible (to avoid the possibility of 3rd party scripts tampering the target APIs) while the 2nd can be done much later. If we do this decoupling we have more control on when the instrumentation can send data or not. Why do we want this control? a simple example is to control the volume of data sent by the SDK.

My idea of an instrumentations is an object with:

  • patch method: optional, only the instrumentations that patch APIs have it. This operation is idempotent
  • enable method: sets to true the enabled state of the instrumentation
  • disable method: sets to false the enabled state of the instrumentation

Having this patch/enable separated the SDK can tell all instrumentations to patch at start and only enable the ones where the configuration says so.

Use Case
This is snippet represents a use case where I use a custom instrumentation but not enabling it because I do not want its telemetry for now.

// This could be rendered by a server that reads the flags from a datasource
// so the devs have control on the traffic from their bckend
const enabledInstrs= {
  fetch: true,
  xhr: true,
  'web-vitals': true,
  'my-instr': false,
};

startBrowserSdk({
  instrumentations: [
    new FetchInstrumentation({enabled: enabledInstrs['fetch']}),
    new XhrInstrumentation({enabled: enabledInstrs['xhr']}),
    new WebVitalsInstrumentation({enabled: enabledInstrs['web-vitals']}),
    new MyCustomInstrumentation({enabled: enabledInstrs['my-instr']}),
  ]
})

@wolfgangcodes wolfgangcodes left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This provides a reasonable ergonomic interface for setting up instrumentation.

@overbalance
overbalance enabled auto-merge (squash) September 10, 2026 17:22
@overbalance
overbalance merged commit c0df3d6 into open-telemetry:main Sep 10, 2026
9 checks passed
@otelbot-browser otelbot-browser Bot mentioned this pull request Sep 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants