diff --git a/packages/honeycomb-opentelemetry-web/README.md b/packages/honeycomb-opentelemetry-web/README.md
index 64d2253..b4b2dd8 100644
--- a/packages/honeycomb-opentelemetry-web/README.md
+++ b/packages/honeycomb-opentelemetry-web/README.md
@@ -76,48 +76,49 @@ Refer to our [Honeycomb documentation](https://docs.honeycomb.io/get-started/sta
Pass these options to the HoneycombWebSDK:
-| name | required? | type | default value | description |
-| --------------------- | ------------------------------------------------ | ------- | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| apiKey | required[*](#send-to-an-opentelemetry-collector) | string | | [Honeycomb API Key](https://docs.honeycomb.io/working-with-your-data/settings/api-keys/) for sending traces directly to Honeycomb. |
-| serviceName | optional | string | unknown_service | The name of this browser application. Your telemetry will go to a Honeycomb dataset with this name. |
-| localVisualizations | optional | boolean | false | For each trace created, print a link to the console so that you can find it in Honeycomb. Super useful in development! Do not use in production. |
-| sampleRate | optional | number | 1 | If you want to send a random fraction of traces, then make this a whole number greater than 1. Only 1 in `sampleRate` traces will be sent, and the rest never be created. |
-| tracesEndpoint | optional | string | `${endpoint}/v1/traces` | Populate this to send traces to a route other than /v1/traces. |
-| debug | optional | boolean | false | Enable additional logging. |
-| dataset | optional | string | | Populate this only if your Honeycomb environment is still [Classic](https://docs.honeycomb.io/honeycomb-classic/#am-i-using-honeycomb-classic). |
-| skipOptionsValidation | optional | boolean | false | Do not require any fields.[*](#send-to-an-opentelemetry-collector) Use with OpenTelemetry Collector. |
-| spanProcessors | optional | SpanProcessor[] | | Array of [span processors](https://opentelemetry.io/docs/languages/java/instrumentation/#span-processor) to apply to all generated spans. |
-| traceExporters | optional | SpanExporter[] | | Array of [span exporters](https://opentelemetry.io/docs/languages/js/exporters) | optional |
-| disableDefaultTraceExporter | optional | boolean | false | Disable default honeycomb trace exporter. You can provide additional exporters via `traceExporters` config option. |
-| webVitalsInstrumentationConfig|optional|WebVitalsInstrumentationConfig| `{ enabled: true }` | See [WebVitalsInstrumentationConfig](####WebVitalsInstrumentationConfig). |
-| globalErrorsInstrumentationConfig |optional| GlobalErrorsInstrumentationConfig| `{ enabled: true }` | See [GlobalErrorsInstrumentationConfig](####GlobalErrorsInstrumentationConfig).
-| logLevel | optional | DiagLogLevel | DiagLogLevel.DEBUG | Controls the verbosity of logs printed to the console. |
+| name | required? | type | default value | description |
+| --------------------------------- | ------------------------------------------------ | --------------------------------- | ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| apiKey | required[*](#send-to-an-opentelemetry-collector) | string | | [Honeycomb API Key](https://docs.honeycomb.io/working-with-your-data/settings/api-keys/) for sending traces directly to Honeycomb. |
+| serviceName | optional | string | unknown_service | The name of this browser application. Your telemetry will go to a Honeycomb dataset with this name. |
+| localVisualizations | optional | boolean | false | For each trace created, print a link to the console so that you can find it in Honeycomb. Super useful in development! Do not use in production. |
+| sampleRate | optional | number | 1 | If you want to send a random fraction of traces, then make this a whole number greater than 1. Only 1 in `sampleRate` traces will be sent, and the rest never be created. |
+| tracesEndpoint | optional | string | `${endpoint}/v1/traces` | Populate this to send traces to a route other than /v1/traces. |
+| debug | optional | boolean | false | Enable additional logging. |
+| dataset | optional | string | | Populate this only if your Honeycomb environment is still [Classic](https://docs.honeycomb.io/honeycomb-classic/#am-i-using-honeycomb-classic). |
+| skipOptionsValidation | optional | boolean | false | Do not require any fields.[*](#send-to-an-opentelemetry-collector) Use with OpenTelemetry Collector. |
+| spanProcessors | optional | SpanProcessor[] | | Array of [span processors](https://opentelemetry.io/docs/languages/java/instrumentation/#span-processor) to apply to all generated spans. |
+| traceExporters | optional | SpanExporter[] | | Array of [span exporters](https://opentelemetry.io/docs/languages/js/exporters) |
+| disableDefaultTraceExporter | optional | boolean | false | Disable default honeycomb trace exporter. You can provide additional exporters via `traceExporters` config option. |
+| webVitalsInstrumentationConfig | optional | WebVitalsInstrumentationConfig | `{ enabled: true }` | See [WebVitalsInstrumentationConfig](####WebVitalsInstrumentationConfig). |
+| globalErrorsInstrumentationConfig | optional | GlobalErrorsInstrumentationConfig | `{ enabled: true }` | See [GlobalErrorsInstrumentationConfig](####GlobalErrorsInstrumentationConfig). |
+| logLevel | optional | DiagLogLevel | DiagLogLevel.DEBUG | Controls the verbosity of logs printed to the console. |
+| contextManager | optional | ContextManager | | Sets a [Context Manager](https://opentelemetry.io/docs/languages/js/context/#context-manager) for managing global span context. See [Context Management](#context-management) for more details. |
`*` Note: the `apiKey` field is required because this SDK really wants to help you send data directly to Honeycomb.
#### WebVitalsInstrumentationConfig
-| name | required? | type | default value | description |
-| ---- | --------- | ---- | ------------- | ----------- |
-| enabled | optional | boolean | `true` | Where or not to enable this auto instrumentation. |
-| lcp| optional| VitalOpts | `undefined` | Pass-through config options for web-vitals. See [ReportOpts](https://github.com/GoogleChrome/web-vitals?tab=readme-ov-file#reportopts).
-| lcp.applyCustomAttributes| optional| function | `undefined` | A function for adding custom attributes to core web vitals spans.
-| lcp.dataAttributes| optional| `string[]` | `undefined` | An array of attribute names to filter reported as `lcp.element.data.someAttr`
`undefined` will send all `data-*` attribute-value pairs. `[]` will send none `['myAttr']` will send the value of `data-my-attr` or `''` if it's not supplied. Note: An attribute that's defined, but that has no specified value such as `` will be sent as `{`lcp.element.data.myAttr`: '' }` which is inline with the [dataset API]( https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/dataset).
-| cls| optional| VitalOpts | `undefined` | Pass-through config options for web-vitals. See [ReportOpts](https://github.com/GoogleChrome/web-vitals?tab=readme-ov-file#reportopts).
-| cls.applyCustomAttributes| optional| function | `undefined` | A function for adding custom attributes to core web vitals spans.
-| inp| optional| VitalOptsWithTimings | `undefined` | Pass-through config options for web-vitals. See [ReportOpts](https://github.com/GoogleChrome/web-vitals?tab=readme-ov-file#reportopts).
-| inp.applyCustomAttributes| optional| function | `undefined` | A function for adding custom attributes to core web vitals spans.
-| inp.includeTimingsAsSpans| optional| boolean | `false` | When true will emit `PerformanceLongAnimationFrameTiming` and `PerformanceScriptTiming` as spans.
-| fid| optional| VitalOpts | `undefined` | Pass-through config options for web-vitals. See [ReportOpts](https://github.com/GoogleChrome/web-vitals?tab=readme-ov-file#reportopts).
-| fid.applyCustomAttributes| optional| function | `undefined` | A function for adding custom attributes to core web vitals spans.
-| fcp| optional| VitalOpts | `undefined` | Pass-through config options for web-vitals. See [ReportOpts](https://github.com/GoogleChrome/web-vitals?tab=readme-ov-file#reportopts).
-| fcp.applyCustomAttributes| optional| function | `undefined` | A function for adding custom attributes to core web vitals spans.
-| ttf| optional| VitalOpts | `undefined` | Pass-through config options for web-vitals. See [ReportOpts](https://github.com/GoogleChrome/web-vitals?tab=readme-ov-file#reportopts).
-| ttf.applyCustomAttributes| optional| function | `undefined` | A function for adding custom attributes to core web vitals spans.
+| name | required? | type | default value | description |
+|---------------------------|-----------|----------------------|---------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| enabled | optional | boolean | `true` | Where or not to enable this auto instrumentation. |
+| lcp | optional | VitalOpts | `undefined` | Pass-through config options for web-vitals. See [ReportOpts](https://github.com/GoogleChrome/web-vitals?tab=readme-ov-file#reportopts). |
+| lcp.applyCustomAttributes | optional | function | `undefined` | A function for adding custom attributes to core web vitals spans. |
+| lcp.dataAttributes | optional | `string[]` | `undefined` | An array of attribute names to filter reported as `lcp.element.data.someAttr`
`undefined` will send all `data-*` attribute-value pairs. `[]` will send none `['myAttr']` will send the value of `data-my-attr` or `''` if it's not supplied. Note: An attribute that's defined, but that has no specified value such as `` will be sent as `{`lcp.element.data.myAttr`: '' }` which is inline with the [dataset API]( https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/dataset). |
+| cls | optional | VitalOpts | `undefined` | Pass-through config options for web-vitals. See [ReportOpts](https://github.com/GoogleChrome/web-vitals?tab=readme-ov-file#reportopts). |
+| cls.applyCustomAttributes | optional | function | `undefined` | A function for adding custom attributes to core web vitals spans. |
+| inp | optional | VitalOptsWithTimings | `undefined` | Pass-through config options for web-vitals. See [ReportOpts](https://github.com/GoogleChrome/web-vitals?tab=readme-ov-file#reportopts). |
+| inp.applyCustomAttributes | optional | function | `undefined` | A function for adding custom attributes to core web vitals spans. |
+| inp.includeTimingsAsSpans | optional | boolean | `false` | When true will emit `PerformanceLongAnimationFrameTiming` and `PerformanceScriptTiming` as spans. |
+| fid | optional | VitalOpts | `undefined` | Pass-through config options for web-vitals. See [ReportOpts](https://github.com/GoogleChrome/web-vitals?tab=readme-ov-file#reportopts). |
+| fid.applyCustomAttributes | optional | function | `undefined` | A function for adding custom attributes to core web vitals spans. |
+| fcp | optional | VitalOpts | `undefined` | Pass-through config options for web-vitals. See [ReportOpts](https://github.com/GoogleChrome/web-vitals?tab=readme-ov-file#reportopts). |
+| fcp.applyCustomAttributes | optional | function | `undefined` | A function for adding custom attributes to core web vitals spans. |
+| ttf | optional | VitalOpts | `undefined` | Pass-through config options for web-vitals. See [ReportOpts](https://github.com/GoogleChrome/web-vitals?tab=readme-ov-file#reportopts). |
+| ttf.applyCustomAttributes | optional | function | `undefined` | A function for adding custom attributes to core web vitals spans. |
#### GlobalErrorsInstrumentationConfig
-| name | required? | type | default value | description |
-| ---- | --------- | ---- | ------------- | ----------- |
-| enabled | optional | boolean | `true` | Where or not to enable this auto instrumentation. |
+| name | required? | type | default value | description |
+|---------|-----------|---------|---------------|---------------------------------------------------|
+| enabled | optional | boolean | `true` | Where or not to enable this auto instrumentation. |
### Send to an OpenTelemetry Collector
@@ -133,6 +134,23 @@ Your OpenTelemetry Collector can send the traces on to Honeycomb, and your API k
}
```
+### Context Management
+OpenTelemetry uses the concept of a [Context Manager](https://opentelemetry.io/docs/languages/js/context/#context-manager) to store propagate global span context through your system. OpenTelemetry provides a context manager for browser instrumentation based on the [Zone.js](https://github.com/angular/angular/tree/main/packages/zone.js) library to track global context across asynchronous execution threads. This context manager can be plugged into this instrumentation like so:
+
+```js
+import { ZoneContextManager } from '@opentelemetry/context-zone';
+
+const sdk = new HoneycombWebSDK({
+ // other config options omitted...
+ contextManager: new ZoneContextManager()
+});
+sdk.start();
+```
+
+Zone.js has known limitations with async/await code, and [requires](https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-context-zone-peer-dep#installation) your code to be transpiled down to ES2015. It also may carry a performance penalty.
+
+For these reasons, we do not enable ZoneContextManager by default.
+
## Auto-instrumentation
Here is a list of what gets instrumented automatically by including `getWebAutoInstrumentations` and `WebVitalsInstrumentation` in the list of instrumentations while initializing the SDK:
@@ -147,36 +165,37 @@ Here is a list of what gets instrumented automatically by including `getWebAutoI
The SDK adds these fields to all telemetry:
-| name | status | static? | description | example |
-|------|--------|---------|-------------|---------|
-| `user_agent.original` | [stable](https://github.com/scheler/opentelemetry-specification/blob/browser-events/specification/resource/semantic_conventions/browser.md) | static | window.user_agent | `Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36` |
-| `browser.height` | planned | per-span | [window.innerHeight](https://developer.mozilla.org/en-US/docs/Web/API/Window/innerHeight), the height of the layout viewport in pixels | 287 |
-| `browser.width` | planned | per-span | [window.innerWidth](https://developer.mozilla.org/en-US/docs/Web/API/Window/innerWidth), the height of the layout viewport in pixels | 1720 |
-| `browser.brands` | stable | static | [NavigatorUAData: brands](https://developer.mozilla.org/en-US/docs/Web/API/NavigatorUAData/brands) | ["Not_A Brand 8", "Chromium 120", "Google Chrome 120"] |
-| `browser.name` | custom | static | Best guess of browser type | "Chrome", "Chromium", "Firefox", "Safari", etc. |
-| `browser.version` | custom | static | Version of browser | `109.1` |
-| `browser.platform` | stable | static | [NavigatorUAData: platform](https://developer.mozilla.org/en-US/docs/Web/API/NavigatorUAData/platform) | "Windows" |
-| `browser.mobile` | stable | static | [NavigatorUAData: mobile](https://developer.mozilla.org/en-US/docs/Web/API/NavigatorUAData/mobile) | true |
-| `browser.language` | stable | static | [Navigator: language](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/language) | "fr-FR" |
-| `browser.touch_screen_enabled` | stable | static | [Navigator: maxTouchPoints](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/maxTouchPoints) | true |
-| `device.type` | custom | static | Best guess of device type | "desktop", "mobile", "tablet", etc. |
-| `network.effectiveType` | custom | static | [NetworkInformation: effectiveType](https://developer.mozilla.org/en-US/docs/Web/API/NetworkInformation/effectiveType). Best guess of user's "effective network type", which is based on their overall network speed. Only available on Chromium devices, and only computed once when the SDK is initialized. | "slow-2g", "2g", "3g", "4g" |
-| `page.url` | custom | per-span | | `https://docs.honeycomb.io/getting-data-in/data-best-practices/#datasets-group-data-together?page=2` |
-| `page.route` | custom | per-span | | `/getting-data-in/data-best-practices/` |
-| `page.search` | custom | per-span | | `?page=2` |
-| `page.hash` | custom | per-span | | `#datasets-group-data-together` |
-| `page.hostname` | custom | per-span | | `docs.honeycomb.io` |
-| `screen.width` | custom | static | Total available screen width in pixels. | `780` |
-| `screen.height` | custom | static | Total available screen height in pixels | `1000` |
-| `screen.size` | custom | static | `small` (less than 768px), `medium` (769px - 1024px) or `large` (greater than 1024px), `unknown` if the size is missing. |
-| `honeycomb.distro.version` | stable | static | package version | "1.2.3" |
-| `honeycomb.distro.runtime_version` | stable | static | | "browser" |
-| `entry_page.url` | custom | static | | `https://docs.honeycomb.io/getting-data-in/data-best-practices/#datasets-group-data-together?page=2` |
-| `entry_page.path` | custom | static | | `/getting-data-in/data-best-practices/` |
-| `entry_page.search` | custom | static | | `?page=2` |
-| `entry_page.hash` | custom | static | | `#datasets-group-data-together` |
-| `entry_page.hostname` | custom | static | | `docs.honeycomb.io` |
-| `entry_page.referrer` | custom | static | [Document: referrer](https://developer.mozilla.org/en-US/docs/Web/API/Document/referrer) | `https://honeycomb.io` |
+| name | status | static? | description | example |
+|------------------------------------|---------------------------|----------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------|
+| `user_agent.original` | [stable][browser-semconv] | static | window.user_agent | `Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36` |
+| `browser.height` | planned | per-span | [window.innerHeight](https://developer.mozilla.org/en-US/docs/Web/API/Window/innerHeight), the height of the layout viewport in pixels | 287 |
+| `browser.width` | planned | per-span | [window.innerWidth](https://developer.mozilla.org/en-US/docs/Web/API/Window/innerWidth), the height of the layout viewport in pixels | 1720 |
+| `browser.brands` | stable | static | [NavigatorUAData: brands](https://developer.mozilla.org/en-US/docs/Web/API/NavigatorUAData/brands) | ["Not_A Brand 8", "Chromium 120", "Google Chrome 120"] |
+| `browser.name` | custom | static | Best guess of browser type | "Chrome", "Chromium", "Firefox", "Safari", etc. |
+| `browser.version` | custom | static | Version of browser | `109.1` |
+| `browser.platform` | stable | static | [NavigatorUAData: platform](https://developer.mozilla.org/en-US/docs/Web/API/NavigatorUAData/platform) | "Windows" |
+| `browser.mobile` | stable | static | [NavigatorUAData: mobile](https://developer.mozilla.org/en-US/docs/Web/API/NavigatorUAData/mobile) | true |
+| `browser.language` | stable | static | [Navigator: language](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/language) | "fr-FR" |
+| `browser.touch_screen_enabled` | stable | static | [Navigator: maxTouchPoints](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/maxTouchPoints) | true |
+| `device.type` | custom | static | Best guess of device type | "desktop", "mobile", "tablet", etc. |
+| `network.effectiveType` | custom | static | [NetworkInformation: effectiveType](https://developer.mozilla.org/en-US/docs/Web/API/NetworkInformation/effectiveType). Best guess of user's "effective network type", which is based on their overall network speed. Only available on Chromium devices, and only computed once when the SDK is initialized. | "slow-2g", "2g", "3g", "4g" |
+| `page.url` | custom | per-span | | `https://docs.honeycomb.io/getting-data-in/data-best-practices/#datasets-group-data-together?page=2` |
+| `page.route` | custom | per-span | | `/getting-data-in/data-best-practices/` |
+| `page.search` | custom | per-span | | `?page=2` |
+| `page.hash` | custom | per-span | | `#datasets-group-data-together` |
+| `page.hostname` | custom | per-span | | `docs.honeycomb.io` |
+| `screen.width` | custom | static | Total available screen width in pixels. | `780` |
+| `screen.height` | custom | static | Total available screen height in pixels | `1000` |
+| `screen.size` | custom | static | `small` (less than 768px), `medium` (769px - 1024px) or `large` (greater than 1024px), `unknown` if the size is missing. | |
+| `honeycomb.distro.version` | stable | static | package version | "1.2.3" |
+| `honeycomb.distro.runtime_version` | stable | static | | "browser" |
+| `entry_page.url` | custom | static | | `https://docs.honeycomb.io/getting-data-in/data-best-practices/#datasets-group-data-together?page=2` |
+| `entry_page.path` | custom | static | | `/getting-data-in/data-best-practices/` |
+| `entry_page.search` | custom | static | | `?page=2` |
+| `entry_page.hash` | custom | static | | `#datasets-group-data-together` |
+| `entry_page.hostname` | custom | static | | `docs.honeycomb.io` |
+| `entry_page.referrer` | custom | static | [Document: referrer](https://developer.mozilla.org/en-US/docs/Web/API/Document/referrer) | `https://honeycomb.io` |
+
Static fields are added to the [Resource](https://opentelemetry.io/docs/concepts/resources/), so they are same for every span emitted for the loaded page.
@@ -237,3 +256,5 @@ See [SUPPORT.md](./SUPPORT.md)
## Code of Conduct
See [CODE_OF_CONDUCT.md](./CODE_OF_CONDUCT.md)
+
+[browser-semconv]: https://github.com/scheler/opentelemetry-specification/blob/browser-events/specification/resource/semantic_conventions/browser.md
\ No newline at end of file