Type to search.

Configure EDOT Browser

Serverless Observability

Elastic Cloud Serverless projects are autoscaled environments, fully managed by Elastic and available on Elastic Cloud.

Availability

  • Generally available

    This functionality is generally available and ready for production usage.

Stack

The Elastic Stack includes Elastic's core products such as Elasticsearch, Kibana, Logstash, and Beats.

Availability

  • Generally available

    This functionality is generally available and ready for production usage.

Unless stated otherwise on the page, this functionality is available when your Elastic Stack is deployed on Elastic Cloud Hosted, Elastic Cloud Enterprise, Elastic Cloud on Kubernetes, and self-managed environments.

This documentation corresponds to the latest patch available for each minor version. If you're not using the latest patch, check the release notes for changes.

EDOT Browser Preview

The Elastic Distribution of OpenTelemetry (EDOT) Browser SDK (RUM) collects performance metrics, traces, and logs from web applications in OpenTelemetry format, and sends them to Elastic Observability.

Availability

  • Preview

    This functionality is in technical preview and is ready for evaluation. Use with caution in production; it is not recommended for mission-critical workloads. Elastic will work to fix any issues, but features in technical preview are not subject to the support SLA of official GA features. Specific Support terms apply.

This documentation corresponds to the latest patch available for each minor version. If you're not using the latest patch, check the release notes for changes.

This page explains how to configure EDOT Browser, which settings are supported, and what's required to start exporting browser telemetry.

EDOT Browser follows OpenTelemetry configuration conventions where possible. Like the upstream OpenTelemetry Browser SDK, it uses explicit configuration at initialization rather than environment variables, which are not available in the browser.

Important

In 0.4 and later, several configuration keys changed to align with the upstream OpenTelemetry Browser SDK. For example, otlpEndpoint and exportHeaders moved to exportConfig.url and exportConfig.headers, the top-level sampleRate option moved to session.sampleRate, and instrumentation keys use short names such as fetch and user-action. If you're upgrading, refer to EDOT Browser breaking changes for the full list of changes and migration steps.

EDOT Browser runs in your users' browsers. Configuration passed to EDOT Browser is accessible to end users, since browser source code and runtime values are visible. This is why you shouldn't embed secrets such as API keys in browser configuration.

Environment variables exist at build time only: a bundler replaces process.env.* with values when bundling, but these values are not available at runtime in the browser. You can provide configuration at build time (bundler-defined constants) or at runtime (options passed to the initialization function).

EDOT Browser does not read OTEL_* variables directly. Instead, it accepts configuration values passed explicitly during initialization.

Typical configuration patterns include:

  • Passing configuration from a server-rendered page.
  • Loading configuration from a global object populated at runtime.

The best approach depends on your application architecture and build tooling.

At a minimum, EDOT Browser requires:

  • A service name to identify the frontend application.
  • An export endpoint that points to a reverse proxy.

You can also set a log level, which is recommended during setup.

JavaScript
import { startBrowserSdk } from '@elastic/opentelemetry-browser';

startBrowserSdk({
  serviceName: 'my-web-app',
  logLevel: 'info',
  exportConfig: {
    url: 'https://telemetry.example.com',
  }
});
  • serviceName identifies the browser application in Elastic Observability.
  • exportConfig.url points to a reverse proxy, not directly to Elastic Observability.
  • logLevel controls diagnostic output in the browser console.

Configuration is passed as an object to startBrowserSdk. The following options are supported:

Option Type Description
serviceName string Logical name of the frontend service. Defaults to unknown_service:web if not set.
serviceVersion string Version of the application. Optional.
logLevel "none" \| "error" \| "warn" \| "info" \| "debug" \| "verbose" \| "all" Diagnostic log level for the SDK internal logger. Defaults to info. Values are lowercase; the SDK accepts them case-insensitively.
resourceAttributes Record<string, any> Optional resource attributes to attach to telemetry. For example: { 'deployment.environment.name': 'production' }.
disabled boolean If true, the SDK does not start.
instrumentations Record<string, Object> Not recommended. Advanced per-instrumentation config passed through to upstream OpenTelemetry Browser instrumentations. EDOT Browser logs a warning when this option is set. Refer to instrumentations details.
disableInstrumentations string[] Optional list of instrumentation keys to turn off. Values must match the keys in instrumentations details. Refer to disableInstrumentations details.
session { sampleRate?: number; inactivityTimeout?: number; maxDuration?: number } Session tracking and session-level sampling. Refer to session details for more information.
ignoreFetchUrls (string \| RegExp)[] URLs to exclude from fetch, XMLHttpRequest, and resource timing instrumentation. OTLP export URLs are always ignored. Refer to ignoreFetchUrls details. Optional; defaults to [].
exportConfig { url?: string; tracesUrl?: string; logsUrl?: string; metricsUrl?: string; headers?: Record<string, string>} Configuration for exporters of the different signals.
exportConfig.url string Base URL of the OTLP export endpoint (reverse proxy). Do not include signal paths such as /v1/traces. Defaults to http://localhost:4318.
exportConfig.tracesUrl, exportConfig.logsUrl, exportConfig.metricsUrl string Full URL for one signal, used as is without appending /v1/<signal>. Overrides exportConfig.url for that signal only. Optional. Refer to Export endpoint configuration.
exportConfig.headers Record<string, string> Headers to send with export requests. Defaults to {}. The reverse proxy typically injects Authorization; do not put API keys here in browser code.

Configure exportConfig.url to point to a server that accepts OTLP traffic. Use the base URL of the server only: do not include signal paths such as /v1/traces, /v1/metrics, or /v1/logs. The SDK appends these paths when exporting each signal.

If your server routes OTLP traffic on paths other than /v1/traces, /v1/logs and /v1/metrics, set exportConfig.tracesUrl, exportConfig.logsUrl or exportConfig.metricsUrl. Each one is a full URL and is used exactly as written. A signal without its own URL still uses exportConfig.url plus the default path, and you can omit exportConfig.url when all three are set.

JavaScript
import { startBrowserSdk } from '@elastic/opentelemetry-browser';

startBrowserSdk({
  serviceName: 'my-web-app',
  exportConfig: {
    tracesUrl: 'https://telemetry.example.com/otlp/t',
    logsUrl: 'https://telemetry.example.com/otlp/l',
    metricsUrl: 'https://telemetry.example.com/otlp/m',
  },
});

For security reasons, Elastic recommends configuring a reverse proxy that forwards OTLP traffic to Elastic Observability. Refer to Proxy and CORS configuration for more details.

Use a service name that identifies your frontend application and doesn't contain special characters, so that data is correctly categorized in Elastic Observability.

For details on reverse proxy and authorization, refer to OpenTelemetry for Real User Monitoring (RUM).

EDOT Browser uses the OpenTelemetry diagnostic logger.

To troubleshoot setup issues, increase the log level when calling startBrowserSdk:

JavaScript
import { startBrowserSdk } from '@elastic/opentelemetry-browser';

startBrowserSdk({
  serviceName: 'my-web-app',
  logLevel: 'debug',
  exportConfig: {
    url: 'https://telemetry.example.com',
  }
});

Diagnostic logs are written to the browser console. For more information on using debug logging to troubleshoot issues, refer to Enable debug logging for EDOT SDKs and Enable debug logging (Collector).

This section provides additional details about configuration settings that require further explanation or behave differently in EDOT Browser compared to OpenTelemetry JS.

Warning

Using instrumentations is not recommended for most applications. EDOT Browser aims to provide a stable configuration surface, but the upstream OpenTelemetry Browser instrumentations are still in active development and their configuration can change in ways that break your initialization options on upgrade.

If you set instrumentations, EDOT Browser prints a warning in the browser console to remind you that this option is unstable and that future EDOT or instrumentation updates may require changes on your side. For advanced use only, review the @opentelemetry/browser-instrumentation version bundled with your EDOT Browser release when you upgrade. Stable, EDOT-specific options for common instrumentation settings are planned separately from this passthrough. For background, refer to elastic-otel-rum-js#152.

An object whose keys are the configuration keys of the available instrumentations in EDOT and whose values are the corresponding configuration objects. The scope name is the instrumentation identifier attached to exported telemetry.

The following keys are supported:

Instrumentation Key Scope Configuration
Navigation timing navigation-timing @opentelemetry/browser-instrumentation/navigation-timing Reference
Resource timing resource-timing @opentelemetry/browser-instrumentation/resource-timing Reference
Fetch fetch @opentelemetry/browser-instrumentation/fetch Reference
User action user-action @opentelemetry/browser-instrumentation/user-action Reference
XMLHttpRequest xhr @opentelemetry/browser-instrumentation/xhr Reference
Errors errors @opentelemetry/browser-instrumentation/errors Reference
Web vitals web-vitals @opentelemetry/browser-instrumentation/web-vitals Reference
Navigation navigation @opentelemetry/browser-instrumentation/navigation Reference

Pass an array of instrumentation keys (the same strings as the Key column in the table above) to turn off specific instrumentations without using the instrumentations object. This option is intended for simple cases such as disabling one or two defaults.

  • The value must be an array of strings. Other shapes log a warning in the browser console and are ignored.
  • If a string is not a known instrumentation key, EDOT Browser logs a warning and skips that entry.
  • If you set both disableInstrumentations and instrumentations for the same key, disableInstrumentations takes precedence. For example, disableInstrumentations: ['resource-timing'] keeps resource timing disabled even when instrumentations['resource-timing'] sets enabled: true.
JavaScript
import { startBrowserSdk } from '@elastic/opentelemetry-browser';

startBrowserSdk({
  serviceName: 'my-web-app',
  exportConfig: {
    url: 'https://telemetry.example.com',
  },
  disableInstrumentations: ['web-vitals', 'resource-timing'],
});

EDOT Browser adds session.id, session.previous_id (after a session rotates), session.sampling_rate, and browser.tab.id attributes to spans and log records for sampled sessions. Refer to Sessions for details.

Option Type Description
sampleRate number Fraction of sessions to record, in the range 0–1. Defaults to 1 (100%). The decision is made when a session starts and stays fixed until the session rotates. Invalid values log a warning and fall back to the default; out-of-range values are clamped. Values are truncated to four decimal places (minimum step 0.0001). At 0, automatic RUM instrumentations are disabled for that session and the session.start log record is not emitted.
inactivityTimeout number Seconds without telemetry after which the session ends. Defaults to 1800 (30 minutes). Must be between 300 (5 minutes) and maxDuration.
maxDuration number Maximum session length in seconds, regardless of activity. Defaults to 14400 (4 hours). Must be between 1800 (30 minutes) and 86400 (24 hours).

Incorrect values for inactivityTimeout and maxDuration fall back to the default and out-of-range values are clamped to the closest limit. In both cases EDOT Browser logs a warning.

Session sampling controls whether EDOT Browser exports automatic RUM telemetry (instrumentation spans and log records) for a given user session. The sampling rate is configured with session.sampleRate, not a top-level sampleRate option.

When a session is sampled in, all configured instrumentations run for that session until it ends or rotates. When a session is sampled out, EDOT Browser disables automatic instrumentations for that session so the browser does not collect spans or log records that would be dropped anyway.

When an active session is available, traces and logs use that session's sampling decision. If the session manager cannot return an active session—for example after a session expires and before user activity starts a new one—there is no per-session decision to apply. When session.sampleRate is 1 (the default), the trace sampler still samples spans in and automatic log records continue to be exported. For any rate below 1, spans are sampled out until a new session starts.

To stop automatic RUM export while keeping session machinery active, set session.sampleRate to 0. With sampleRate: 0, session state still exists client-side but automatic export is suppressed.

Metrics your application emits through the OpenTelemetry API are not gated by session sampling today. Refer to Sessions for signal-specific behavior.

ignoreFetchUrls lists URLs that EDOT Browser should not instrument. The SDK always ignores OTLP export URLs (traces, logs, and metrics) to prevent self-instrumentation. When you set instrumentations, per-instrumentation ignoreUrls values are merged with this list for fetch, XMLHttpRequest, and resource timing.

Matching rules

  • Strings must exactly match the full absolute request URL, including scheme, host, path, and query string. A path-only value such as /api/health does not match.
  • RegExp values are partial matches against the URL, consistent with upstream fetch and XHR ignoreUrls.

What is suppressed

  • Fetch and XHR: ignored requests produce no spans and do not receive a traceparent header, so trace context is not propagated to those endpoints and downstream services are not linked from the browser trace.
  • Resource timing: ignored URLs are filtered from resource timing log records for every resource type (scripts, stylesheets, images, fonts, and others), not only fetch and XHR. For example, ignoring a URL pattern that matches analytics.js also omits resource timing telemetry for that script load.
JavaScript
import { startBrowserSdk } from '@elastic/opentelemetry-browser';

startBrowserSdk({
  serviceName: 'my-web-app',
  exportConfig: {
    url: 'https://telemetry.example.com',
  },
  ignoreFetchUrls: [
    // Exact match on the full URL
    'https://api.example.com/v1/internal/health?key=abc',
    // Partial match (RegExp)
    /https:\/\/analytics\.example\.net\//,
  ],
});