Loading

Metrics, traces, and logs

EDOT Browser can export all three OpenTelemetry signals (metrics, traces, and logs) to Elastic Observability using OTLP.

EDOT Browser configures the OpenTelemetry MeterProvider and exports metrics over OTLP to the /v1/metrics path. Your application can create meters and instruments (counters, histograms, and so on) using the OpenTelemetry Metrics API. EDOT Browser exports those metrics along with any SDK-provided ones.

Ensure your reverse proxy and OTLP endpoint accept the /v1/metrics path.

  • Metrics are collected in the user’s browser and represent a single session or page. There is no server-side aggregation, each export batch reflects one client’s view.
  • Browsers have limited resources. High-cardinality or high-frequency metrics can affect performance and export payload size. Use caution with unbounded attributes (for example user IDs, dynamic URLs) on metrics.
  • Metrics are only sent when the SDK exports (for example on an interval or when the page is unloaded). Temporary or single-page sessions might produce few data points.
  • Browser environments vary (device, network, extensions). Metric values might be noisier or less consistent than server-side metrics.

In certain scenarios, a trace might occur asynchronously. For instance, a user interaction that initiates an HTTP request to a downstream service and subsequently updates the User Interface with the service response. To maintain context across these asynchronous functions, EDOT incorporates a ContextManager that patches several asynchronous browser APIs, including:

  • setTimeout and setImmediate
  • Promise methods: then, catch, and finally
  • XMLHttpRequest event handlers

This mechanism ensures that when these asynchronous operations execute, they do so within the same context that was active at the time of their scheduling. Consequently, distributed tracing and context values (such as trace IDs and spans) are accurately preserved across asynchronous boundaries in web applications.

EDOT Browser initializes tracing and registers instrumentations that produce spans:

  • Spans for the initial document load and related navigation timing (document load instrumentation is turned on by default).
  • Each outgoing request using fetch or XMLHttpRequest is captured as an external.http span with attributes such as URL, HTTP method, and status code. These spans represent the client-side portion of the request.
  • Spans for user actions such as "click" and "submit". These interaction spans group the subsequent work (for example external.http requests) so you can attribute frontend and backend activity to a specific user action in Elastic Observability.
  • Spans for task executions that take longer than 50ms and might impact the user experience. For more information, refer to PerformanceLongTaskTiming.

When your backend is instrumented with OpenTelemetry and trace context (trace ID, span ID) is propagated in HTTP headers, the browser’s external.http span and the backend spans appear in the same trace, giving you end-to-end visibility in Discover and Service Maps. Refer to What to expect in Kibana for how these traces appear in the Observability app.

  • Frontend-to-backend trace continuity depends on your backend and HTTP client propagating the W3C Trace Context headers. If propagation is not configured, browser and backend spans appear as separate traces.
  • Only requests that go through the instrumented fetch and XMLHttpRequest APIs are captured. Requests made by other mechanisms (for example some third-party scripts, WebSockets, or non-instrumented clients) do not produce spans unless you add custom instrumentation.
  • Sampling is applied in the browser. High traffic can lead to large trace volume, so configure sampling or export options appropriately.
  • Traces are tied to the page. Cross-tab or cross-origin flows might not form a single trace unless you implement custom context propagation.

Also current limitation of the Context Manager, and other implementations, is the unavailability of AsyncContext in browsers, which prevents the preservation of context when utilizing the async/await syntax. Should this situation arise, developers may use tools such as Babel to down-compile their code, transforming it into Promise-based code.

Note

Full feature parity with classic Elastic APM RUM agents for tracing (for example, certain automatic instrumentations or span types) is not available.

EDOT Browser supports the OpenTelemetry Logs API. When the LoggerProvider is configured and logs are exported using OTLP:

  • Application logs: Your application code can obtain a logger from the OpenTelemetry API and emit log records (severity, body, attributes). EDOT Browser exports these records to your configured endpoint on the /v1/logs path.
  • Resource and context: Log records are associated with the same resource (for example service name) and can optionally be linked to the active trace context, so you can correlate logs with traces in Elastic Observability.

There is no requirement to use logs. If you do not create log records or do not configure log export, no log data is sent.

  • Logs are buffered in the browser and sent on the export cycle. High log volume can increase memory use and export payload size, and might affect page performance. Prefer sampling or severity filtering for noisy logs.
  • As with metrics, logs reflect a single client session. You do not get centralized log aggregation in the browser, that happens in Elastic Observability after export.
  • Logs that are not exported before the user navigates away or closes the tab might be lost unless the SDK supports a reliable flush (for example on beforeunload). Be aware that some log data might not reach the backend in edge cases.
Note

Automatic capture of console methods (for example console.log, console.error) is not provided by EDOT Browser. To send logs to Elastic Observability, you must use the OpenTelemetry Logs API from your application code. Automatic console instrumentation might be considered in the future.