@splunk/otel-web-session-recorder
v2.1.0
Published
Session recorder for Splunk Observability
Readme
@splunk/otel-web-session-recorder
For complete instructions for how to get started with the Splunk distribution of OpenTelemetry JavaScript for Web, see Install the Browser RUM agent for Splunk RUM, Instrument browser-based web applications for Splunk RUM and Record browser sessions.
Privacy-aware visual session replay for web applications. The Splunk Session Recorder extends @splunk/otel-web with comprehensive session recording capabilities, correlating visual user interactions with OpenTelemetry telemetry for enhanced debugging and user experience analysis.
🚀 Installation & Setup
Package Manager Installation
1. Install the Packages
# Install both core RUM and session recorder
npm install @splunk/otel-web @splunk/otel-web-session-recorder
# or
pnpm add @splunk/otel-web @splunk/otel-web-session-recorder
# or
yarn add @splunk/otel-web @splunk/otel-web-session-recorder2. Initialize RUM and Session Recorder
import { SplunkRum } from '@splunk/otel-web'
import SplunkSessionRecorder from '@splunk/otel-web-session-recorder'
// Initialize core RUM first
SplunkRum.init({
realm: 'us1',
rumAccessToken: 'YOUR_RUM_ACCESS_TOKEN',
applicationName: 'my-web-app',
deploymentEnvironment: 'production',
})
// Then initialize session recorder
SplunkSessionRecorder.init({
realm: 'us1',
rumAccessToken: 'YOUR_RUM_ACCESS_TOKEN',
})CDN Installation
1. Load the Scripts
Choose a versioning strategy based on your needs:
Major Version Lock (Recommended)
<!-- Locks to v2.x.x - gets latest minor and patch updates -->
<script src="https://cdn.signalfx.com/o11y-gdi-rum/v2/splunk-otel-web.js" crossorigin="anonymous"></script>
<script
src="https://cdn.signalfx.com/o11y-gdi-rum/v2/splunk-otel-web-session-recorder.js"
crossorigin="anonymous"
></script>Minor Version Lock
<!-- Locks to v2.1.x - gets latest patch updates only -->
<script src="https://cdn.signalfx.com/o11y-gdi-rum/v2.1/splunk-otel-web.js" crossorigin="anonymous"></script>
<script
src="https://cdn.signalfx.com/o11y-gdi-rum/v2.1/splunk-otel-web-session-recorder.js"
crossorigin="anonymous"
></script>Exact Version Lock
<!-- Locks to exact version v2.1.0 - no automatic updates -->
<script
src="https://cdn.signalfx.com/o11y-gdi-rum/v2.1.0/splunk-otel-web.js"
crossorigin="anonymous"
integrity="sha384-<integrity>"
></script>
<script
src="https://cdn.signalfx.com/o11y-gdi-rum/v2.1.0/splunk-otel-web-session-recorder.js"
crossorigin="anonymous"
integrity="sha384-<integrity>"
></script>Latest Version (Not Recommended)
<!-- Always pulls the latest released version -->
<script src="https://cdn.signalfx.com/o11y-gdi-rum/latest/splunk-otel-web.js" crossorigin="anonymous"></script>
<script
src="https://cdn.signalfx.com/o11y-gdi-rum/latest/splunk-otel-web-session-recorder.js"
crossorigin="anonymous"
></script>⚠️ Warning: Using
latestautomatically pulls the newest released version of the RUM agent and session recorder, which may introduce breaking changes without notice. This can cause unexpected behavior in production. Use a version lock strategy instead.
📖 For version numbers and integrity hashes, see GitHub Releases.
📚 For detailed CDN setup instructions, see the official documentation.
2. Initialize RUM and Session Recorder
<script>
// Initialize core RUM first
SplunkRum.init({
realm: 'us1',
rumAccessToken: 'YOUR_RUM_ACCESS_TOKEN',
applicationName: 'my-web-app',
deploymentEnvironment: 'production',
})
// Then initialize session recorder
SplunkSessionRecorder.init({
realm: 'us1',
rumAccessToken: 'YOUR_RUM_ACCESS_TOKEN',
})
</script>Complete CDN Example
<!DOCTYPE html>
<html>
<head>
<title>My Web App with Session Recording</title>
<!-- Load Splunk RUM (using major version lock) -->
<script src="https://cdn.signalfx.com/o11y-gdi-rum/v1/splunk-otel-web.js" crossorigin="anonymous"></script>
<!-- Load Session Recorder (using major version lock) -->
<script
src="https://cdn.signalfx.com/o11y-gdi-rum/v1/splunk-otel-web-session-recorder.js"
crossorigin="anonymous"
></script>
<script>
// Initialize RUM first
SplunkRum.init({
realm: 'us1',
rumAccessToken: 'YOUR_RUM_ACCESS_TOKEN',
applicationName: 'my-web-app',
deploymentEnvironment: 'production',
})
// Then initialize session recorder
SplunkSessionRecorder.init({
realm: 'us1',
rumAccessToken: 'YOUR_RUM_ACCESS_TOKEN',
debug: false, // Set to true for development
})
</script>
</head>
<body>
<!-- Your app content -->
</body>
</html>⚠️ Important: Always call
SplunkRum.init()beforeSplunkSessionRecorder.init().
⚙️ Configuration Options
| Option | Type | Required | Default | Description |
| ---------------------------- | ---------------------------------------- | -------- | -------- | ---------------------------------------------------------- |
| realm | string | ✅ | - | Splunk realm (us0, us1, eu0, etc.) |
| rumAccessToken | string | ✅ | - | RUM access token for authentication |
| beaconEndpoint | string | ❌ | - | Custom destination URL for captured data (overrides realm) |
| debug | boolean | ❌ | false | Enable debug logging |
| persistFailedReplayData | boolean | ❌ | true | Store failed uploads in localStorage for retry |
| maskAllInputs | boolean | ❌ | true | Mask all form input values |
| maskAllText | boolean | ❌ | false | Mask all text content |
| sensitivityRules | SensitivityRule[] | ❌ | [] | Custom rules for masking, unmasking, or excluding elements |
| features.backgroundService | string \| boolean | ❌ | false | Custom URL for background service worker |
| features.canvas | boolean | ❌ | false | Record canvas elements |
| features.iframes | boolean | ❌ | false | Record iframe content |
| features.video | boolean | ❌ | false | Record video elements |
| features.cacheAssets | boolean | ❌ | true | Cache assets for replay |
| features.packAssets | boolean \| PackAssetsConfig | ❌ | true | Pack assets to reduce payload size |
| maxExportIntervalMs | number | ❌ | 5000 | Maximum interval between data exports (milliseconds) |
| logLevel | 'debug' \| 'info' \| 'warn' \| 'error' | ❌ | 'warn' | Logging level for session recorder |
Sensitivity Rules Configuration
interface SensitivityRule {
rule: 'mask' | 'unmask' | 'exclude'
selector: string // CSS selector
}
// Example usage
SplunkSessionRecorder.init({
realm: 'us1',
rumAccessToken: 'YOUR_RUM_ACCESS_TOKEN',
sensitivityRules: [
{ rule: 'mask', selector: '.sensitive-data' },
{ rule: 'exclude', selector: '.payment-form' },
{ rule: 'unmask', selector: '.public-content' },
],
})Background Service Configuration
The background service is used to offload session replay processing to a 3rd party iframe (separate thread), improving performance by preventing the session replay logic from blocking the main thread. It is required for image compression - the background service handles compressing captured images to reduce payload size during session replay.
When to customize:
- Self-hosting the session recorder files
- Using a custom Content Security Policy (CSP)
- Deploying behind a firewall that blocks CDN access
// Example: Self-hosted background service - ensure the domain is different from the main domain to ensure the background service is loaded in a separate thread.
SplunkSessionRecorder.init({
realm: 'us1',
rumAccessToken: 'YOUR_RUM_ACCESS_TOKEN',
features: {
backgroundService: 'https://my-other-domain.com/assets/background-service.html',
},
})
// Example: spunk domain
// It will load an 3rd party iframe (background service) from this domain 'https://cdn.signalfx.com/o11y-gdi-rum/<version>/background-service.html'
// Ensure you have this domain whitelisted in your CSP config
SplunkSessionRecorder.init({
realm: 'us1',
rumAccessToken: 'YOUR_RUM_ACCESS_TOKEN',
features: {
backgroundService: true,
},
})💡 Default behavior: If not specified, asset processing is not offloaded and is handled on the main page thread.
📁 File location: When using npm installation, find
background-service.htmlinnode_modules/@splunk/otel-web-session-recorder/dist/artifactsto copy to your static assets or usetrueand load it from CDN.
Asset Packing Configuration
interface PackAssetsConfig {
fonts?: boolean // Pack font assets
styles?: boolean // Pack CSS styles
images?:
| boolean
| {
onlyViewportImages?: boolean // Only pack visible images
pack?: boolean // Enable image packing
quality?: number // JPEG quality (0-1). Only available when backgroundService is set, otherwise silently ignored
}
}
// Example usage
SplunkSessionRecorder.init({
realm: 'us1',
rumAccessToken: 'YOUR_RUM_ACCESS_TOKEN',
features: {
packAssets: {
fonts: true,
styles: true,
images: {
onlyViewportImages: true,
pack: true,
quality: 0.8,
},
},
},
})Complete Configuration Example
import SplunkSessionRecorder from '@splunk/otel-web-session-recorder'
SplunkSessionRecorder.init({
// Required settings
realm: 'us1',
rumAccessToken: 'YOUR_RUM_ACCESS_TOKEN',
// Optional: Custom endpoint (overrides realm)
beaconEndpoint: 'https://custom-endpoint.com/v1/rumreplay',
// Privacy & Security
maskAllInputs: true,
maskAllText: false,
sensitivityRules: [
{ rule: 'exclude', selector: '.payment-form' },
{ rule: 'mask', selector: '.sensitive-data' },
{ rule: 'unmask', selector: '.public-info' },
],
// Feature Control
features: {
backgroundService: true,,
canvas: false, // Skip canvas recording for privacy
iframes: false, // Skip iframe content
video: false, // Skip video elements
cacheAssets: true, // Cache assets for better replay
packAssets: {
// Optimize asset packing
fonts: true,
styles: true,
images: {
onlyViewportImages: true,
pack: true,
quality: 0.7,
},
},
},
// Performance
maxExportIntervalMs: 5000, // Export data every 5 seconds
logLevel: 'warn', // Log warnings and errors only
// Advanced
debug: false, // Disable debug logging
persistFailedReplayData: true, // Store failed uploads for retry
})🛠️ Troubleshooting
For troubleshooting issues with the Splunk Session Recorder, see Troubleshoot browser instrumentation for Splunk Observability Cloud in the official documentation.
📚 API Reference
SplunkSessionRecorder Class
Static Methods
| Method | Parameters | Returns | Description |
| -------------- | ----------------------- | ------- | ------------------------------- |
| init(config) | SessionRecorderConfig | void | Initialize session recorder |
| start() | - | void | Start recording current session |
| stop() | - | void | Stop recording current session |
interface SessionRecorderConfig {
// Required
realm: string
rumAccessToken: string
// Privacy
maskAllInputs?: boolean
maskAllText?: boolean
sensitivityRules?: SensitivityRule[]
// Feature Control
features?: {
backgroundService?: string | boolean
canvas?: boolean
iframes?: boolean
video?: boolean
cacheAssets?: boolean
packAssets?: boolean | PackAssetsConfig
}
// Performance
maxExportIntervalMs?: number
logLevel?: 'debug' | 'info' | 'warn' | 'error'
// Advanced
debug?: boolean
beaconEndpoint?: string
persistFailedReplayData?: boolean
}
interface SensitivityRule {
rule: 'mask' | 'unmask' | 'exclude'
selector: string
}
interface UserInfo {
id?: string
email?: string
attributes?: Record<string, string>
}License
Licensed under the Apache License, Version 2.0. See LICENSE for the full license text.
ℹ️ SignalFx was acquired by Splunk in October 2019. See Splunk SignalFx for more information.
