Skip to content

feat: add @opentelemetry/browser package#224

Draft
david-luna wants to merge 26 commits intoopen-telemetry:mainfrom
david-luna:otel-browser
Draft

feat: add @opentelemetry/browser package#224
david-luna wants to merge 26 commits intoopen-telemetry:mainfrom
david-luna:otel-browser

Conversation

@david-luna
Copy link
Copy Markdown
Contributor

@david-luna david-luna commented Mar 31, 2026

Which problem is this PR solving?

Add a new package named @opentelemetry/browser which hold the setup of the different signals separately and a bulder to compose them together into an SDK interface with start and stop methods.

This approach has taken into consideration that configuring all signals into a single SDK class presents challenges when it comes to tree shaking and bundlers cannot anticipate which modules are going to be used. So the configuration has been split by signal and needs to be imported explicitly by the consumer making easier for bundlers to analyse the code and remove unused modules.

You could start an SDK in isolation:

import {startLogsSdk} from '@opentelemetry/browser/logs';

const logsSdk = startLogsSdk({
  // configuration for logs
});

// then you can shutdown
await logsSdk.shutdown();

O combine more than one SDK

import {startLogsSdk} from '@opentelemetry/browser/logs';
import {startTracesSdk} from '@opentelemetry/browser/traces';

// Combine the functions into one
const startMySdk = combineSdks({
  logs: startLogsSdk,
  traces: startTracesSdk
});

// Use it to start
const mySdk = startMySdk({
  // It accepts global config options
  otlpEndpoint: 'http://my.collector.com'
  // And signal specific ones
  logs: {
    otlpLogsHeaders: { foo: 'bar' }
  }
});

// then you can shutdown
await mySdk.shutdown();

Some bundlers are smart enough to tree shake even if the SDKs are exported from a barrel file but explicit export paths has been added to be in sync with the approach done for instrumentations.

Refs #131

Short description of the changes

Type of change

Please delete options that are not relevant.

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

How Has This Been Tested?

Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration

  • Unit test for the package
  • Bundler tests to verify tree shaking is working

Checklist:

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

@martinkuba
Copy link
Copy Markdown
Contributor

A couple of initial comments -

  1. The builder pattern is not as common in JS, and also I think we want to minimize the use of classes as much as possible. Here are a couple of PRs for reference
  1. I think we should exclude metrics for now until we have a good reason to add them.

There are a few reasons

  • if we model sessions as entities, it would add a lot of complexity to managing meter providers
  • most browser metrics I can think of are aggregated from many client instances, where it makes sense to generate metrics from events in the backend (should be part of the prototype we are working on)
  • we want to minimize the bundle size, and should (imo) steer users to using events whenever possible

@david-luna
Copy link
Copy Markdown
Contributor Author

@martinkuba

Thanks for the early feedback :)

Agree on avoiding the builer pattern. I can refactor it to a previous draft I had which uses function composition.

The current Implementation merges the configuration types so the user has a single place to add the configuration. I could keep it in the refactor. What's your opinion? Should we have separe config objects (one per signal) or a single one?

@martinkuba
Copy link
Copy Markdown
Contributor

Should we have separate config objects (one per signal) or a single one?

We want to keep it simple AND flexible (classic trade off) 😅

For users who want to minimize their bundle size, it should be possible to only include the log SDK. This is tricky because an instrumentation could generate both events and spans. I think this is something we need to explore.

@david-luna david-luna self-assigned this Apr 7, 2026
@david-luna
Copy link
Copy Markdown
Contributor Author

@martinkuba

I've changed to functions and removed the metrics. Still I have implemented a function to let the user combine logs & traces SDKs into one function. We can discuss all together the design in the next SIG

Comment thread packages/browser/src/types.ts Outdated
Comment thread packages/browser/src/logs.ts Outdated
Comment thread packages/browser/src/traces.ts Outdated
Comment thread packages/browser/src/sdk.ts Outdated
Comment thread packages/browser/src/sdk.ts Outdated
Comment thread packages/browser/src/sdk.ts Outdated
Comment thread packages/browser/src/sdk.ts Outdated
david-luna and others added 11 commits April 15, 2026 20:30
Co-authored-by: Jared Freeze <overbalance@users.noreply.github.com>
Co-authored-by: Jared Freeze <overbalance@users.noreply.github.com>
Co-authored-by: Jared Freeze <overbalance@users.noreply.github.com>
Co-authored-by: Jared Freeze <overbalance@users.noreply.github.com>
Co-authored-by: Jared Freeze <overbalance@users.noreply.github.com>
Co-authored-by: Jared Freeze <overbalance@users.noreply.github.com>
@david-luna david-luna requested a review from overbalance April 20, 2026 08:39
Comment thread packages/browser/src/types.ts Outdated
// Resource & Entities related
resource?: Resource;
// Processor
blrpScheduleDelay?: number;
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.

Would it make sense to have an object grouping these options? Something like

...
batchLogRecordProcessorConfig: {
  scheduleDelay?: number;
  ..etc,
}

Same with traces config

Copy link
Copy Markdown
Contributor Author

@david-luna david-luna Apr 29, 2026

Choose a reason for hiding this comment

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

I think it does. Even we can do the same with the export config

exportConfig: {
  endpoint?: string;
  headers?: Record<string, string>;
}

but maybe there is no need to use such a long name. If used directly with the logs SDK the name of the method already gives the context

startLogsSdk({
  // other config...
  processorConfig: {
    scheduleDelay: 5000,
  }
});

and if used with the compose API is nested in the the logs key

// Combine the functions into one
const startMySdk = combineSdks({
  logs: startLogsSdk,
  traces: startTracesSdk
});

startMySdk({
  // other config...
  logs: {
    processorConfig: {
      scheduleDelay: 5000,
    }
  }
});

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.

Yeah, looks good

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.

4 participants