Real User Monitoring for Electron applications.
Alpha (v0.X.X) — This SDK is in early development. APIs may change between releases.
- Electron 39+
yarn add @datadog/electron-sdk
# or
npm install @datadog/electron-sdkThe Electron SDK uses dd-trace under the hood to monitor the main process and relies on the browser SDK to monitor renderer processes.
graph TB
subgraph Electron Application
subgraph Renderer Process
BP[Browser SDK]
end
subgraph Main Process
DDT[dd-trace]
SDK[Electron SDK]
end
end
DD[(Datadog)]
BP --> SDK
DDT --> SDK
SDK --> DD
%% Styling
classDef sdk fill:#fce8e6,stroke:#d93025
classDef trace fill:#e6f4ea,stroke:#137333
classDef browser fill:#fef7e0,stroke:#e37400
classDef ext fill:#f3e8fd,stroke:#7627bb
class BP browser
class DDT trace
class SDK sdk
class DD ext
Import the instrumentation entry point before electron in your main process:
// src/main.ts
import '@datadog/electron-sdk/instrument';
import { app, BrowserWindow } from 'electron';This instruments the needed Electron APIs. dd-trace is initialized with the resolved configuration when init()
is called.
Then initialize the Electron SDK, awaiting init before creating any browser windows:
import { init } from '@datadog/electron-sdk';
await init({
clientToken: '<CLIENT_TOKEN>',
applicationId: '<APPLICATION_ID>',
service: 'my-electron-app',
site: 'datadoghq.com',
allowedRendererHosts: ['*'], // required: restrict to specific hostnames in production
});Deferred init caveat: windows opened before
init()resolves are not tracked until they are reloaded. To wait for the end user's consent, callinit()at startup withtrackingConsent: 'pending'rather than deferring it (see Tracking Consent).
In order to monitor the renderer process, you must set up the Browser SDK in pages loaded by the renderer.
Logs assembled by the Browser Logs SDK are forwarded through the Electron bridge and uploaded by the main process. Install the Browser Logs SDK in your renderer bundle:
yarn add @datadog/browser-logs
# or
npm install @datadog/browser-logsInitialize it in each renderer page where you want to collect logs:
import { datadogLogs } from '@datadog/browser-logs';
datadogLogs.init({
clientToken: '<CLIENT_TOKEN>',
site: 'datadoghq.com',
service: 'my-electron-app',
forwardErrorsToLogs: true,
});The Browser Logs SDK detects the bridge exposed by the Electron SDK and sends its logs to the main process instead of uploading them directly. See the Browser Logs setup guide for additional renderer configuration options.
Configure renderer-log sampling on the Electron SDK in the main process:
await init({
clientToken: '<CLIENT_TOKEN>',
applicationId: '<APPLICATION_ID>',
service: 'my-electron-app',
site: 'datadoghq.com',
allowedRendererHosts: ['*'],
logsSampleRate: 25, // forwards 25% of renderer logs
});logsSampleRate defaults to 100 and is applied independently to each bridged log. It is separate
from RUM sessionSampleRate. The Browser Logs SDK does not apply its own sessionSampleRate in bridge
mode, so the Electron setting is authoritative.
The SDK instruments Electron as it is loaded, which requires correct module loading order. The SDK provides bundler plugins to ensure this works in all environments.
Each plugin accepts copyRuntimeDependencies, which controls whether it copies the SDK, dd-trace,
and their runtime dependencies into the build output. It defaults to false: the application
packager must include those dependencies in the packaged app. Set copyRuntimeDependencies: true
only as a best-effort compatibility fallback when the packager cannot stage them.
Keep @datadog/electron-sdk in the application's production dependencies; it brings dd-trace
as a runtime dependency. Applications already using copyRuntimeDependencies: false with working
packager staging need no configuration change.
When using Forge's Vite or Webpack plugin, keep copyRuntimeDependencies disabled and configure
Forge to package root node_modules alongside its bundler output so Electron Packager can stage
production dependencies normally.
Forge Vite: add an ignore function to packagerConfig in forge.config.ts:
packagerConfig: {
ignore: (file) => {
if (!file) return false;
return !/^[/\\](?:\.vite|node_modules)(?:[/\\]|$)/.test(file);
},
},Forge Webpack: use the same configuration with .webpack instead of .vite:
packagerConfig: {
ignore: (file) => {
if (!file) return false;
return !/^[/\\](?:\.webpack|node_modules)(?:[/\\]|$)/.test(file);
},
},Use datadogVitePlugin() or new DatadogWebpackPlugin() without the copy option. See the
complete Electron Forge setup guide for full examples and package
manager requirements.
copyRuntimeDependencies defaults to false for every Datadog bundler plugin. Keep the default and
configure the application packager to stage production dependencies. electron-builder and plain
Forge already do this by default when packaging the application source; preserve that behavior in
custom packaging configurations.
Add the corresponding Datadog plugin to the main-process bundler configuration.
Vite (including electron-vite and standalone Vite):
// vite config
import { defineConfig } from 'vite';
import { datadogVitePlugin } from '@datadog/electron-sdk/vite-plugin';
export default defineConfig({
plugins: [datadogVitePlugin()],
});Webpack:
// webpack config
const { DatadogWebpackPlugin } = require('@datadog/electron-sdk/webpack-plugin');
module.exports = {
plugins: [new DatadogWebpackPlugin()],
};esbuild:
// esbuild config
import { datadogEsbuildPlugin } from '@datadog/electron-sdk/esbuild-plugin';
await esbuild.build({
plugins: [datadogEsbuildPlugin()],
});- Sessions — Session-based event grouping
- RUM Views — One view per main process instance
- RUM Errors — Capture Node errors and crashes in main process
- RUM Resources — Capture RUM resources from main process network calls
- Traces — Capture traces for network calls, command execution on main process
- Renderer Events — Capture RUM events from renderer processes via the browser SDK
- Custom Duration Vitals — Measure user-defined durations in the main process
- Renderer Profiling — Collect JS Self-Profiling data from renderer pages and correlate it with RUM
- Session Replay — Record renderer UI sessions in the main process and correlate them with RUM views
- Global Context — Attach custom attributes to RUM events from the main process
- User & Account Info — Attach user and account identity to all RUM events and traces
- Operation Monitoring (experimental) — Track start / succeed / fail steps of critical user-facing workflows
- Event Filtering and Scrubbing — Modify or discard RUM events with
beforeSendRum - Tracking Consent — Collect and send data according to the end user's consent
- Source Maps — Resolve main process and renderer stack traces to your original source code
Use beforeSendRum to inspect fully assembled main-process and renderer RUM events before they are sent to Datadog:
await init({
// ...
beforeSendRum: (event, { source }) => {
if (event.type === 'error') {
event.error.message = event.error.message.replace(/token=[^&\s]+/g, 'token=[REDACTED]');
event.error.stack = event.error.stack?.replace(/token=[^&\s]+/g, 'token=[REDACTED]');
}
if (source === 'main' && event.context?.internal === true) {
return false;
}
return true;
},
});Only returning false discards the event. View, execution context, and native crash events cannot be discarded. The
editable fields are:
- All events:
context,service,version,view.name,view.url,view.referrer, andexecution_context.name - Views:
view.performance.lcp.resource_url - Errors:
error.message,error.stack,error.handling_stack,error.resource.url,error.fingerprint, and_dd.debug_ids - Resources:
resource.url, GraphQL variables, request/response headers, and WebSocket close reasons and protocols - Actions:
action.target.name - Long tasks: script source URLs, invokers, and
_dd.debug_ids
Event identity, session, application, and other fields remain unchanged. Callback errors are logged and the event is
still sent. Editable string fields must remain strings; use an empty string to clear one because deleting it or assigning
null or undefined is ignored. The callback is synchronous and should remain fast. It does not automatically detect PII.
Renderer events may first pass through the Browser SDK's beforeSend, then through Electron's beforeSendRum after
main-process enrichment. Filtering them at this stage prevents upload but does not undo Browser counters, lifecycle
effects, or Electron session activity that already occurred. Spans are not passed to this callback.
To help you comply with regulations such as GDPR and CCPA, the SDK collects and sends data according to the end user's tracking consent:
| Value | Behavior |
|---|---|
'granted' (default) |
Data is collected and sent. |
'pending' |
Data is collected and kept on disk, then sent if consent is granted or deleted if it is refused. |
'not-granted' |
New data is neither kept nor sent. Data stored earlier with consent is still sent. |
Initialize the SDK with the consent known at startup, and update it when the end user answers:
import { init, setTrackingConsent } from '@datadog/electron-sdk';
await init({
// ...
trackingConsent: 'pending',
});
// Once the end user has answered the consent prompt:
setTrackingConsent(accepted ? 'granted' : 'not-granted');- Refusing consent ends the session, and the next
'pending'or'granted'starts a new one. Moving between'pending'and'granted'keeps the session. - RUM events, logs, spans, profiles and session replay recordings that start while consent is refused, or pending then refused, are not sent, even when they are reported after consent is granted again.
- Main-process requests carry trace headers while consent is pending, as when it is granted, so that their traces link to the data sent if consent is granted. They carry none while consent is refused.
- The SDK does not restore the consent at the next launch: pass it at each launch. Data kept while consent is pending is deleted at the next launch if no decision was made.
- Call
setTrackingConsent()onceinit()has resolved: an earlier call can be ignored. - An invalid
trackingConsentabortsinit(), and an invalid value passed tosetTrackingConsent()is handled as'not-granted'. - The SDK starts Electron's crash reporter, which writes native crash dumps locally regardless of consent. At the next launch, a crash is judged like other data by the consent at the time it happened, then sent, kept or dropped according to the consent of that launch; its dump is deleted either way.
Set the consent in the main process: data from renderers allowed by allowedRendererHosts reaches Datadog through
the main process, while other renderers run the Browser SDK standalone, under its own trackingConsent. In bridged
renderers, the Browser SDK is not informed of the consent and keeps collecting, so:
- Requests it traces (
allowedTracingUrls) carry trace headers whatever the consent. - When consent is granted after a refusal, an open page's view moves to the new session with its next update, so that the session shows up in Datadog. As an exception to the rule above, that view is sent even if it started while consent was refused, or pending then refused, with what it measured since it started. The previous session no longer lists it. In the new session, the page's session replay can only be played back from its next view.
Record an already-known duration, or measure one between a start and stop call:
import { addDurationVital, startDurationVital, stopDurationVital } from '@datadog/electron-sdk';
addDurationVital('database.migration', {
startTime: Date.now() - 1_500,
duration: 1_500,
context: { database: 'documents' },
});
startDurationVital('document.open', {
vitalKey: 'document-42',
context: { source: 'recent-files' },
});
await openDocument();
stopDurationVital('document.open', {
vitalKey: 'document-42',
context: { result: 'success' },
});Times passed to the API are in milliseconds. Use vitalKey to measure overlapping durations with the same name; it identifies the measurement but is not included in the event. A measurement must be started and stopped in the same process. In renderer processes, use the equivalent @datadog/browser-rum APIs directly.
Attach custom attributes from the main process to all subsequent RUM events, including renderer events.
import {
setGlobalContext,
setGlobalContextProperty,
removeGlobalContextProperty,
clearGlobalContext,
} from '@datadog/electron-sdk';
setGlobalContext({ team: 'checkout', build: '1.2.3' });
// Update one attribute, leaving the others untouched
setGlobalContextProperty('feature_flag', 'new-cart');
removeGlobalContextProperty('feature_flag');
clearGlobalContext();Attributes are sent in the event's context field. setGlobalContext replaces the whole context; use setGlobalContextProperty to change a single attribute. Setting an attribute to null removes it, as with addUserExtraInfo.
Renderer processes keep their own global context, set through the Browser SDK's datadogRum.setGlobalContext. Both are merged on renderer events, and the renderer's value wins on a conflicting key.
Attach user and account identity to all subsequent RUM events and traces from the main process. The SDK propagates context to spans and renderer RUM events automatically.
import { setUserInfo, clearUserInfo, addUserExtraInfo } from '@datadog/electron-sdk';
import { setAccountInfo, clearAccountInfo, addAccountExtraInfo } from '@datadog/electron-sdk';
// On login
setUserInfo({ id: 'user-123', name: 'Alice', email: 'alice@example.com' });
setAccountInfo({ id: 'account-456', name: 'Acme Corp' });
// Enrich with custom attributes
addUserExtraInfo({ plan: 'premium', role: 'admin' });
addAccountExtraInfo({ tier: 'enterprise', region: 'us' });
// Remove a custom attribute
addUserExtraInfo({ role: null });
// On logout
clearUserInfo();
clearAccountInfo();Operation Monitoring lets you track the lifecycle of critical user-facing workflows (login, checkout, file upload, video playback, …) by emitting paired start / end steps. The backend correlates the steps by name (and optional operationKey) and exposes them as a single Operation in the RUM UI.
⚗️ This API is in preview and the signatures may change before stable release.
import { startOperation, succeedOperation, failOperation } from '@datadog/electron-sdk';
// Simple operation
startOperation('checkout');
try {
await runCheckout();
succeedOperation('checkout');
} catch (error) {
failOperation('checkout', 'error');
}
// Parallel operations sharing a name — distinguished by `operationKey`
startOperation('upload', { operationKey: 'profile_pic' });
startOperation('upload', { operationKey: 'cover_photo' });
succeedOperation('upload', { operationKey: 'profile_pic' });
failOperation('upload', 'abandoned', { operationKey: 'cover_photo' });The renderer process keeps using @datadog/browser-rum directly (with the feature_operation_vital experimental flag enabled on its init). API signatures match exactly, so you can start an operation in one process and complete it in the other — the backend correlates steps by name + operationKey.
The Browser SDK can collect code-level performance data (via the JS Self-Profiling API) for renderer pages and correlate it with RUM views and long tasks.
1. Enable profiling from the main process. Set profilingSampleRate on the Electron SDK init():
await init({
clientToken: '<CLIENT_TOKEN>',
applicationId: '<APPLICATION_ID>',
site: 'datadoghq.com',
service: 'my-electron-app',
allowedRendererHosts: ['*'],
profilingSampleRate: 100, // percentage of sampled sessions that are profiled (0–100)
});The Electron SDK owns the profiling sampling decision; setting profilingSampleRate in the renderer's datadogRum.init has no effect.
2. Serve the renderer with the js-profiling Document Policy.
The JS Self-Profiling API is only available when the page is delivered with the Document-Policy: js-profiling HTTP response header. Because response headers cannot be attached to the file:// protocol, serve the renderer over a protocol that can set headers instead:
- a custom protocol via
protocol.handle - a local HTTP server (
http://localhost:<port>)
If you use a custom protocol, it must also be registered as privileged (standard and secure) before the app is ready — otherwise the JS Self-Profiling API stays unavailable even with the header, because the scheme is not treated as a secure context:
import { protocol } from 'electron';
protocol.registerSchemesAsPrivileged([
{ scheme: 'app', privileges: { standard: true, secure: true, supportFetchAPI: true } },
]);The Browser SDK records renderer UI (Session Replay) and streams the records to the main process, which buffers, compresses, and uploads them — correlated with your RUM views.
1. Enable session replay from the main process. Set sessionReplaySampleRate on the Electron SDK init():
await init({
clientToken: '<CLIENT_TOKEN>',
applicationId: '<APPLICATION_ID>',
site: 'datadoghq.com',
service: 'my-electron-app',
allowedRendererHosts: ['*'],
sessionReplaySampleRate: 100, // percentage of sampled sessions that record replay (0–100)
defaultPrivacyLevel: 'mask', // 'mask' | 'allow' | 'mask-user-input'
});The Electron SDK owns the replay sampling decision and performs the upload. sessionReplaySampleRate is applied as a child of sessionSampleRate, so with sessionSampleRate: 0 no session records replay. The defaultPrivacyLevel set here is propagated to the renderer recorder through the bridge, so masking is enforced end-to-end.
2. Enable session replay in the renderer's Browser SDK. In the pages loaded by the renderer, initialize @datadog/browser-rum with session replay turned on:
import { datadogRum } from '@datadog/browser-rum';
datadogRum.init({
clientToken: '<CLIENT_TOKEN>',
applicationId: '<APPLICATION_ID>',
site: 'datadoghq.com',
service: 'my-electron-app',
});The Electron SDK advertises a records capability over the bridge, so the Browser SDK streams replay records to the main process instead of uploading them itself — no startSessionReplayRecording() call is required. See Renderer process setup for general Browser SDK configuration.
Stack traces and URLs collected in an Electron app contain the app's install path, for example /Users/alice/Applications/MyApp.app/Contents/Resources/app.asar/dist/main/index.js in the main process, or file:///Users/alice/…/app.asar/dist/renderer/index.js in a renderer. These paths change with each installation, so they never match source maps uploaded at build time, and they expose the user's install directory.
The SDK rewrites the app path (as returned by app.getAppPath()) to / in every event before it leaves the machine: the frames above become /dist/main/index.js and /dist/renderer/index.js. Only the app path is rewritten: other local paths, such as files in the user data folder or outside the app, are sent as is. URLs of renderers loaded from a custom protocol or http(s):// contain no install path and are left unchanged.
1. Generate source maps with their sources. Configure your bundler to emit source maps that embed the original code (sourcesContent), as described in the Browser source maps guide. If the main process is compiled by tsc without a bundler, set both sourceMap: true and inlineSources: true, otherwise stack traces resolve but show no code snippets.
2. Use a different service for the main process and the renderers. Once the app path is rewritten, the main process and a renderer can both report the same path, for example /dist/index.js when both are built to dist/. Datadog looks up source maps by service, version, and path, so separate services keep them apart: the main process reports under the service passed to the Electron SDK init(), and renderers under the service passed to the Browser SDK init(). Set a version in both the Electron SDK and the Browser SDK init(): it is not set by default, and the upload's --release-version must match it.
3. Upload the source maps with datadog-ci, installed as described in its installation guide (dev dependency, global install or standalone binary). The --service and --release-version must match the SDK configuration, and --minified-path-prefix must be the path at which the uploaded files appear in stack traces. Run datadog-ci from your git working tree: it sends the repository URL and the commit of the uploaded sources, so Error Tracking links stack frames to your code. The examples below assume an app packaged with its dist/ folder.
Main process, built to dist/main/:
datadog-ci sourcemaps upload ./dist/main \
--service my-electron-app-main \
--release-version "$VERSION" \
--minified-path-prefix /dist/main/Renderer loaded from file://, built to dist/renderer/:
datadog-ci sourcemaps upload ./dist/renderer \
--service my-electron-app-renderer \
--release-version "$VERSION" \
--minified-path-prefix /dist/renderer/Renderer loaded from a custom protocol (requires Browser SDK >= 7.9.0), for example app://app/ serving the files of dist/renderer/:
datadog-ci sourcemaps upload ./dist/renderer \
--service my-electron-app-renderer \
--release-version "$VERSION" \
--minified-path-prefix app://app/Renderer loaded from http(s)://, for example a local server serving the files of dist/renderer/ at its root:
datadog-ci sourcemaps upload ./dist/renderer \
--service my-electron-app-renderer \
--release-version "$VERSION" \
--minified-path-prefix /Initialize the SDK. Call it once per launch and await it before calling any other API. Returns true on success, false if the configuration is invalid.
Set the end user's tracking consent: 'granted', 'pending' or 'not-granted'. See Tracking Consent.
Replace the global context attached to all subsequent RUM events.
Return a copy of the current global context, or {} if none is set.
Set a single global context attribute, leaving the others untouched.
Remove a single global context attribute.
Remove all global context attributes from subsequent events.
Set the user identity. The user is attached to all subsequent RUM events and spans. An id is required; calls without one are ignored with a warning.
interface UserInfo {
id?: string;
name?: string;
email?: string;
extraInfo?: Record<string, unknown>;
}Return a copy of the current user, or undefined if none is set.
Remove the user from all subsequent events.
Merge custom attributes into the user's extraInfo. Set a key to null to remove it. Works even before setUserInfo is called — useful when the user id is derived elsewhere (e.g. from anonymous_id). Standard fields (id, name, email) are ignored here.
Set the account identity. An id is required.
interface AccountInfo {
id: string;
name?: string;
extraInfo?: Record<string, unknown>;
}Return a copy of the current account, or undefined if none is set.
Remove the account from all subsequent events.
Merge custom attributes into the account's extraInfo. Set a key to null to remove it. Requires setAccountInfo to have been called first. Standard fields (id, name) are ignored here.
Report a manually handled error.
import { addError } from '@datadog/electron-sdk';
try {
riskyOperation();
} catch (error) {
addError(error, { context: { component: 'sync' } });
}Record a custom duration vital with an explicit start time and duration, in milliseconds.
Start measuring a custom duration vital. Starting another vital with the same name and vitalKey replaces the pending measurement.
Stop and record a pending custom duration vital. Options from the start and stop calls are deeply merged, with stop values taking precedence. Stopping an unknown vital has no effect.
interface DurationVitalOptions {
/** Distinguishes parallel measurements sharing the same `name`. */
vitalKey?: string;
/** Free-form attributes attached to the event. */
context?: Record<string, unknown>;
/** Free-form description attached to `vital.description`. */
description?: string;
}
interface AddDurationVitalOptions extends DurationVitalOptions {
/** Unix timestamp in milliseconds. */
startTime: number;
/** Duration in milliseconds. */
duration: number;
}Start a RUM Operation step. Pair every startOperation with exactly one succeedOperation or failOperation. Use options.operationKey to distinguish parallel operations sharing the same name.
Note:
nameis required and should only contain letters, digits,_,.,@,$,-.
Record the successful completion of a RUM Operation. Pass the same name (and operationKey, if any) used to start it.
Record the failure of a RUM Operation. failureReason must be one of 'error' | 'abandoned' | 'other'.
type FailureReason = 'error' | 'abandoned' | 'other';
interface FeatureOperationOptions {
/** Distinguishes parallel operations sharing the same `name`. */
operationKey?: string;
/** Free-form attributes merged into the event's `context`. */
context?: Record<string, unknown>;
/** Free-form description attached to `vital.description`. */
description?: string;
}Deprecated aliases. The early-preview names
startFeatureOperation/succeedFeatureOperation/failFeatureOperationare kept as deprecated aliases for backwards compatibility. They forward to the un-prefixed names above and emit a one-time runtime warning. They will be removed in the next major release — migrate tostartOperation/succeedOperation/failOperation.
| Option | Type | Required | Default | Description |
|---|---|---|---|---|
clientToken |
string |
Yes | — | Datadog client token |
applicationId |
string |
Yes | — | RUM application ID |
site |
string |
Yes | — | Datadog site (e.g. datadoghq.com, datadoghq.eu, us3.datadoghq.com, us5.datadoghq.com, ap1.datadoghq.com, ddog-gov.com) |
service |
string |
Yes | — | Service name |
env |
string |
No | — | Application environment |
version |
string |
No | — | Application version |
sessionSampleRate |
number |
No | 100 |
Percentage of sessions to collect (0–100). 0 collects no sessions; 100 collects all sessions. |
trackingConsent |
'granted' | 'pending' | 'not-granted' |
No | 'granted' |
Initial tracking consent of the end user. See Tracking Consent. |
logsSampleRate |
number |
No | 100 |
Percentage of bridged renderer logs to forward (0–100), sampled independently per log. In bridge mode this replaces the Browser Logs sessionSampleRate. |
traceSampleRate |
number |
No | 100 |
Percentage of main-process traces to keep when no traceSamplingRules rule matches (0–100). |
traceSamplingRules |
TraceSamplingRule[] |
No | [] |
Ordered sampling rules for main-process traces. The first matching rule determines the percentage of traces to keep; unmatched traces use traceSampleRate. |
sessionReplaySampleRate |
number |
No | 0 |
Percentage of sampled sessions that record session replay (0–100). 0 disables renderer session replay. Applied as a child of sessionSampleRate. |
profilingSampleRate |
number |
No | 0 |
Percentage of sampled sessions that are profiled (0–100). 0 disables renderer profiling. Applied as a child of sessionSampleRate. See Renderer Profiling. |
batchSize |
'SMALL' | 'MEDIUM' | 'LARGE' |
No | 'MEDIUM' |
Byte threshold that rotates a batch file early: SMALL 16 KiB, MEDIUM 512 KiB, LARGE 4 MiB |
uploadFrequency |
'RARE' | 'NORMAL' | 'FREQUENT' |
No | 'NORMAL' |
How often pending batches are uploaded, and the window over which events accumulate: RARE 30s, NORMAL 10s, FREQUENT 5s |
defaultPrivacyLevel |
'mask' | 'allow' | 'mask-user-input' |
No | 'mask' |
Default privacy level for renderer session replay |
allowedRendererHosts |
string[] |
Yes | — | Hostnames allowed for the renderer bridge (required; see table below) |
beforeSendRum |
RumBeforeSend |
No | — | Modify or discard fully assembled main-process and renderer RUM events |
Rules are evaluated in order when a root trace starts. The first matching rule determines the percentage of traces
to keep; unmatched traces use traceSampleRate. Within a sampled RUM session, each root trace is sampled independently,
so the session can contain both kept and rejected traces. Patterns are case-insensitive globs, child spans inherit the
root decision, and trace context is never propagated from an unsampled RUM session. For rejected traces in a sampled
session, Electron net requests omit trace headers, while global fetch and node:http propagate the rejected sampling
decision so downstream spans inherit it. A rejected HTTP trace still produces an unlinked RUM Resource.
| Key | Required | Purpose |
|---|---|---|
sampleRate |
Yes | Percentage of matching traces to keep, from 0 to 100 |
name |
No | Matches the root span operation name, such as http.request |
resource |
No | Matches the root span resource, such as an HTTP method |
tags |
No | Matches root span tags by name and value; every configured tag must match |
await init({
// ...
traceSamplingRules: [{ tags: { 'http.url': '*/health' }, sampleRate: 0 }],
});Required list of renderer origins that may use the DatadogEventBridge. Controls which renderer processes send their events through the main process; the Browser SDK of other renderers runs standalone.
| Value | Allows |
|---|---|
['example.com'] |
Renderers on example.com and any subdomain |
['*.example.com'] |
Only subdomains of example.com |
['myapp'] |
Custom-protocol renderers with hostname myapp (e.g. app://myapp/index.html) |
['file://'] |
All file:// renderers (path-level filtering is not possible for file://) |
['*'] |
All renderers including file:// |
[] |
No renderer can bridge |
Custom protocols: For custom protocols like
app://oryour-scheme://, use the hostname component (the part between://and the first/). For example,app://myapp/index.htmlmatches the hostmyapp.