From 7676112b8faceb0ce35d6efcd494dfa92d9f942b Mon Sep 17 00:00:00 2001 From: Alec Chamberlain Date: Sat, 5 Sep 2026 23:19:29 -0400 Subject: [PATCH 1/9] Add cross-platform local serving commands --- .../6-next/1-rum-session-replay.md | 36 +++++++++++++++++-- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/content/en/conf/2-user-journeys/6-next/1-rum-session-replay.md b/content/en/conf/2-user-journeys/6-next/1-rum-session-replay.md index 582144125b..b18e57dfa7 100644 --- a/content/en/conf/2-user-journeys/6-next/1-rum-session-replay.md +++ b/content/en/conf/2-user-journeys/6-next/1-rum-session-replay.md @@ -21,12 +21,34 @@ Download or copy the {{< rum-example-link >}} and replace the placeholders for ` ## Serve the example over HTTPS -The browser agent should be tested over HTTPS. One simple local approach is to create a trusted development certificate with `mkcert`, then use the Node-based static server: +The browser agent should be tested over HTTPS. Create a trusted development certificate with `mkcert`, then use the Node-based static server. Run the commands from the repository root. + +#### macOS + +```bash +brew install mkcert nss +mkcert -install +mkcert localhost 127.0.0.1 ::1 +npx --yes --registry=https://registry.npmjs.org http-server static -S -C localhost+2.pem -K localhost+2-key.pem -p 8443 +``` + +#### Linux (Debian/Ubuntu) ```bash +sudo apt-get update +sudo apt-get install -y mkcert libnss3-tools +mkcert -install +mkcert localhost 127.0.0.1 ::1 +npx --yes --registry=https://registry.npmjs.org http-server static -S -C localhost+2.pem -K localhost+2-key.pem -p 8443 +``` + +#### Windows PowerShell + +```powershell +winget install FiloSottile.mkcert mkcert -install mkcert localhost 127.0.0.1 ::1 -npx http-server static -S -C localhost+2.pem -K localhost+2-key.pem -p 8443 +npx --yes --registry=https://registry.npmjs.org http-server .\static -S -C .\localhost+2.pem -K .\localhost+2-key.pem -p 8443 ``` Open `https://localhost:8443/examples/rum-session-replay/index.html`. If Chrome warns about the certificate, confirm that `mkcert -install` completed successfully and restart the browser. For a workshop, an instructor-provided HTTPS host is also fine. @@ -35,8 +57,16 @@ Open `https://localhost:8443/examples/rum-session-replay/index.html`. If Chrome For a fast localhost smoke test, you can skip the certificate and serve the files over HTTP: +#### macOS/Linux + ```bash -npx http-server static -p 8080 +npx --yes --registry=https://registry.npmjs.org http-server static -p 8080 +``` + +#### Windows PowerShell + +```powershell +npx --yes --registry=https://registry.npmjs.org http-server .\static -p 8080 ``` Open `http://localhost:8080/examples/rum-session-replay/index.html`. This is acceptable only for a disposable local lab. It does not protect the page or any values typed into it, and browser security policies or Session Replay requirements may prevent it from working. Use the HTTPS option above if RUM or replay data does not appear, and never use this approach for real users or production data. From 53026f4a67c87db569c6ef60d1a3a099ff041b80 Mon Sep 17 00:00:00 2001 From: Alec Chamberlain Date: Sun, 6 Sep 2026 00:31:36 -0400 Subject: [PATCH 2/9] Expand RUM session replay lab instructions --- .../6-next/1-rum-session-replay.md | 164 +++++++++++++----- .../6-next/images/rum-overview.png | Bin 129097 -> 471972 bytes .../6-next/images/rum-session-replay.png | Bin 32327 -> 119152 bytes .../6-next/images/rum-session-search.png | Bin 57405 -> 209654 bytes .../6-next/images/rum-token-step.png | Bin 49082 -> 143107 bytes layouts/shortcodes/rum-example-link.html | 2 +- static/examples/rum-session-replay/index.html | 18 +- 7 files changed, 132 insertions(+), 52 deletions(-) diff --git a/content/en/conf/2-user-journeys/6-next/1-rum-session-replay.md b/content/en/conf/2-user-journeys/6-next/1-rum-session-replay.md index b18e57dfa7..6fa2aaf923 100644 --- a/content/en/conf/2-user-journeys/6-next/1-rum-session-replay.md +++ b/content/en/conf/2-user-journeys/6-next/1-rum-session-replay.md @@ -2,81 +2,160 @@ title: "1. Bonus Bonus Activity: Configure RUM and Session Replay" linkTitle: "1. Configure RUM and Session Replay" weight: 1 -time: 10 minutes +time: 20 minutes --- This activity shows how a front-end developer instruments a small application with **Splunk Real User Monitoring (RUM)** and then adds **Session Replay**. The example is intentionally framework-free so that the configuration is easy to recognize in any application. -Download or copy the {{< rum-example-link >}} and replace the placeholders for `realm`, `rumAccessToken`, and the RUM agent `VERSION`. Serve the file over **HTTPS** in a test environment; the browser agent should load synchronously and as early as possible in the page ``. +Download the {{< rum-example-link >}} and replace the placeholders for `realm` and `rumAccessToken`. The example uses the current `v3` agent path; for production, pin the exact released version you tested. For this lab, start with the easier, certificate-free `http://localhost` path. An optional HTTPS path is also provided. The browser agent should load synchronously and as early as possible in the page ``. ## Prepare the lab -1. In Splunk Observability Cloud, open **Digital Experience** > **Real User Monitoring** > **RUM Configuration** > **Create RUM Integration** > **Browser Instrumentation**. -2. On **Select Token**, choose an organization access token with **Ingest Token** permissions. The RUM token is a public ingestion key that is expected to appear in client-side JavaScript; never use an admin or user API token here. -3. Record your organization’s realm from the Observability Cloud URL or ask the instructor. For example, `app.us1.signalfx.com` uses the `us1` realm. -4. Use the selected token and realm in the example app. Keep the token scoped to this lab and do not commit it to the repository. +1. In Splunk Observability Cloud, select **Settings** > **Access Tokens** > **New Token**. You can also reach this token from the guided **Browser Instrumentation** setup under **Digital Experience** > **Real User Monitoring**. +2. Give the token a name and select the **RUM token** authorization scope. A RUM token is a public ingestion key intended for client-side JavaScript; do not use an **Ingest token**, **API token**, admin token, or user session token here. +3. Find the organization’s realm under **Settings** > your username. For example, `app.us1.observability.splunkcloud.com` uses the `us1` realm. +4. Use the RUM token and realm in the example app. The RUM token will be visible in client-side code, so use a dedicated lab token and never substitute a broader token. Do not commit the workshop token to this repository. - ![Browser Instrumentation Select Token step](../images/rum-token-step.png) -## Serve the example over HTTPS +## Path 1: Run locally over HTTP—recommended for this lab -The browser agent should be tested over HTTPS. Create a trusted development certificate with `mkcert`, then use the Node-based static server. Run the commands from the repository root. +This path is intentionally insecure but requires the least setup. Use it only on your own device with dummy lab data. Do not bind the server to an external network interface. -#### macOS +Complete these steps on your own device: -```bash -brew install mkcert nss -mkcert -install -mkcert localhost 127.0.0.1 ::1 -npx --yes --registry=https://registry.npmjs.org http-server static -S -C localhost+2.pem -K localhost+2-key.pem -p 8443 -``` +1. Create a folder named `rum-session-replay-lab` under your home directory: + + #### macOS/Linux + + ```bash + mkdir -p "$HOME/rum-session-replay-lab" + ``` + + #### Windows PowerShell + + ```powershell + New-Item -ItemType Directory -Force "$env:USERPROFILE\rum-session-replay-lab" | Out-Null + ``` + +2. Click the downloadable `index.html` link above and save the file as `index.html` in that folder: + + * macOS/Linux: `$HOME/rum-session-replay-lab/index.html` + * Windows: `$env:USERPROFILE\rum-session-replay-lab\index.html` + + If the browser opens the file instead of downloading it, use **Save Link As** and keep the filename `index.html`. +3. Open `index.html` in a text editor and replace: + + * `us0` with your realm, such as `us1`. + * `` with your RUM token. It appears twice when Session Replay is enabled. + +4. Choose **one** of the following options. The commands include the full path to the lab folder, so they can be run from any directory. Do not open the file directly with a `file://` URL; using a local web server gives the browser a consistent origin for session tracking. + +### Option 1: Python -#### Linux (Debian/Ubuntu) +Python includes a small web server and is often already installed. + +#### macOS/Linux ```bash -sudo apt-get update -sudo apt-get install -y mkcert libnss3-tools -mkcert -install -mkcert localhost 127.0.0.1 ::1 -npx --yes --registry=https://registry.npmjs.org http-server static -S -C localhost+2.pem -K localhost+2-key.pem -p 8443 +python3 -m http.server 8080 --directory "$HOME/rum-session-replay-lab" ``` #### Windows PowerShell ```powershell -winget install FiloSottile.mkcert -mkcert -install -mkcert localhost 127.0.0.1 ::1 -npx --yes --registry=https://registry.npmjs.org http-server .\static -S -C .\localhost+2.pem -K .\localhost+2-key.pem -p 8443 +py -m http.server 8080 --directory "$env:USERPROFILE\rum-session-replay-lab" ``` -Open `https://localhost:8443/examples/rum-session-replay/index.html`. If Chrome warns about the certificate, confirm that `mkcert -install` completed successfully and restart the browser. For a workshop, an instructor-provided HTTPS host is also fine. +### Option 2: Node.js -### Quick HTTP-only option (insecure) +If Node.js is installed, the same command works in macOS, Linux, and Windows PowerShell: -For a fast localhost smoke test, you can skip the certificate and serve the files over HTTP: +```bash +npx --yes http-server "$HOME/rum-session-replay-lab" -p 8080 +``` + +### Option 3: Docker + +If Docker Desktop or Docker Engine is installed, Nginx can serve the folder without installing Python or Node.js. #### macOS/Linux ```bash -npx --yes --registry=https://registry.npmjs.org http-server static -p 8080 +docker run --rm --name rum-session-replay-lab \ + -p 8080:80 \ + -v "$HOME/rum-session-replay-lab:/usr/share/nginx/html:ro" \ + nginx:alpine ``` #### Windows PowerShell ```powershell -npx --yes --registry=https://registry.npmjs.org http-server .\static -p 8080 +docker run --rm --name rum-session-replay-lab ` + -p 8080:80 ` + -v "${env:USERPROFILE}\rum-session-replay-lab:/usr/share/nginx/html:ro" ` + nginx:alpine +``` + +On the first run, Docker downloads the Nginx image. `-p 8080:80` exposes Nginx on local port `8080`, the `-v` option mounts the lab folder, and `:ro` prevents the container from changing your file. Docker Desktop might prompt for permission to share the folder. + +Open `http://localhost:8080/index.html`. Keep the terminal open while testing and press `Ctrl+C` to stop the server. If port `8080` is already in use, use `8081` in the command and URL instead. + +This certificate-free setup is intended only for the local workshop. Use dummy names, email addresses, and card digits. Do not expose the server to the local network or use this setup for production data. + +If data does not appear, open the browser developer tools and check: + +* **Console** for messages beginning with `SplunkRum:`. +* **Network** for requests to `rum-ingest..observability.splunkcloud.com`. +* That the realm and active RUM token belong to the same organization. +* Whether an ad blocker or privacy extension blocked the CDN or ingest request. + +## Path 2: Run locally over HTTPS—optional + +Use this path if your browser or organization policy requires HTTPS, or if you want a more production-like test. It requires Node.js and a locally trusted development certificate from `mkcert`. The commands below use the same `rum-session-replay-lab` folder created above. + +### macOS + +```bash +cd "$HOME/rum-session-replay-lab" +brew install mkcert nss +mkcert -install +mkcert localhost 127.0.0.1 ::1 +npx --yes http-server . -S -C localhost+2.pem -K localhost+2-key.pem -p 8443 +``` + +### Linux (Debian/Ubuntu) + +```bash +cd "$HOME/rum-session-replay-lab" +sudo apt-get update +sudo apt-get install -y mkcert libnss3-tools +mkcert -install +mkcert localhost 127.0.0.1 ::1 +npx --yes http-server . -S -C localhost+2.pem -K localhost+2-key.pem -p 8443 +``` + +### Windows PowerShell + +```powershell +Set-Location "$env:USERPROFILE\rum-session-replay-lab" +winget install FiloSottile.mkcert +mkcert -install +mkcert localhost 127.0.0.1 ::1 +npx --yes http-server . -S ` + -C .\localhost+2.pem -K .\localhost+2-key.pem -p 8443 ``` -Open `http://localhost:8080/examples/rum-session-replay/index.html`. This is acceptable only for a disposable local lab. It does not protect the page or any values typed into it, and browser security policies or Session Replay requirements may prevent it from working. Use the HTTPS option above if RUM or replay data does not appear, and never use this approach for real users or production data. +Open `https://localhost:8443/index.html`. The certificate command normally creates `localhost+2.pem` and `localhost+2-key.pem`; if it reports different filenames, use those names in the server command. If Chrome still shows a certificate warning after `mkcert -install`, restart Chrome. + +The `*-key.pem` file is a private key. Do not commit or share either certificate file; remove both files from the lab folder when the workshop is complete. ## Basic RUM Basic RUM needs the browser agent and a call to `SplunkRum.init`. This captures front-end telemetry such as page loads, resource and network requests, interactions, errors, and web vitals. ```html - + - + + + - + ``` -Rules are evaluated in order, so put general rules first and specific overrides later. The available actions are: +The result keeps the replay understandable without exposing the learner's sample data: + +| App content | Selector | Replay behavior | Why it remains useful | +| --- | --- | --- | --- | +| Header, product, buttons, and status | `.replay-safe` | Visible | Shows the page, product, and successful cart action | +| Email input | `.customer-email` | Masked | Shows that the learner typed without recording the value | +| Card-entry block | `#payment-details` | Excluded | Hides the sensitive field while leaving the checkout action and result visible | + +The app includes the same privacy map above the product card, so learners can compare the intended policy with the rendered replay. Rules are evaluated in order, so put general rules first and specific overrides later. The available actions are: * `mask` replaces content with black bars. * `unmask` reveals a previously masked element. @@ -236,7 +249,7 @@ Use stable CSS classes or IDs for data classifications rather than brittle selec ### RUM span data is a separate concern -Replay masking does not sanitize attributes already collected by RUM. If the application puts a secret in a URL or custom attribute, redact it before export with `exporter.onAttributesSerializing`: +Replay masking does not sanitize attributes already collected by RUM. If the application puts PII or a secret in a URL attribute, redact only the sensitive query values before export and keep useful routing or campaign context: ```js SplunkRum.init({ @@ -245,22 +258,22 @@ SplunkRum.init({ onAttributesSerializing: (attributes) => ({ ...attributes, "http.url": typeof attributes["http.url"] === "string" - ? attributes["http.url"].replace(/([?&]token=)[^&]+(&|$)/g, "$1$2") + ? attributes["http.url"].replace(/([?&](?:email|token)=)[^&]*/gi, "$1") : attributes["http.url"] }) } }); ``` -The safest design is to avoid placing PII in URLs, DOM identifiers, custom attributes, or user metadata in the first place. RUM does not automatically capture a named user identity, but current agents can create a persistent anonymous user ID for session and journey correlation. If that is not appropriate, explicitly set `user: { trackingMode: "noTracking" }`; only add approved user identifiers when there is a clear operational need. +For example, `/checkout?campaign=workshop&email=learner@example.invalid` retains `campaign=workshop` but exports the email value as ``. The safest design is still to avoid placing PII in URLs, DOM identifiers, custom attributes, or user metadata in the first place. RUM does not automatically capture a named user identity, but current agents can create a persistent anonymous user ID for session and journey correlation. If that is not appropriate, explicitly set `user: { trackingMode: "noTracking" }`; only add approved user identifiers when there is a clear operational need. {{% notice title="Exercise" style="green" icon="running" %}} 1. Open the example `index.html`, replace the placeholders, and confirm that **Basic RUM** is already enabled. Use your browser's developer tools to confirm the agent loads before the application script. 2. Serve the example on `http://localhost`, open it in a private browser window, click **Add to cart**, enter a sample email and dummy card digits, and select **Place order**. 3. Enable the Session Replay script and initialization, repeat the journey, and open the session in Splunk RUM. -4. Confirm that product names are visible, the email is masked, and the payment form is excluded from the replay. -5. Add a sample `?token=do-not-ship-this` query parameter and verify the RUM attribute sanitizer would redact it before export. +4. Compare the replay with the privacy map in the app. Confirm that the page and product context are visible, the email value is masked, and the card-entry block is replaced by an excluded area. The **Place demo order** action and result should remain visible. +5. Add `?campaign=workshop&email=learner@example.invalid&token=do-not-ship-this` to the local URL. In the exported `http.url`, confirm that `campaign=workshop` remains useful while the `email` and `token` values become ``. {{% /notice %}} diff --git a/static/examples/rum-session-replay/index.html b/static/examples/rum-session-replay/index.html index 444f1ecc2d..3c2cb9d5e3 100644 --- a/static/examples/rum-session-replay/index.html +++ b/static/examples/rum-session-replay/index.html @@ -17,11 +17,11 @@ version: "1.0.0", deploymentEnvironment: "workshop", exporter: { - // Redact secrets if they ever appear in a URL attribute. + // Preserve useful URL context while removing sensitive query values. onAttributesSerializing: (attributes) => ({ ...attributes, "http.url": typeof attributes["http.url"] === "string" - ? attributes["http.url"].replace(/([?&]token=)[^&]+(&|$)/g, "$1$2") + ? attributes["http.url"].replace(/([?&](?:email|token)=)[^&]*/gi, "$1") : attributes["http.url"] }) } @@ -38,9 +38,9 @@ maskAllInputs: true, maskAllText: true, sensitivityRules: [ - { rule: "unmask", selector: ".product-name" }, + { rule: "unmask", selector: ".replay-safe" }, { rule: "mask", selector: ".customer-email" }, - { rule: "exclude", selector: "#payment-form" } + { rule: "exclude", selector: "#payment-details" } ] }); @@ -119,6 +119,34 @@ .intro { max-width: 42rem; margin-bottom: 2rem; } + .privacy-guide { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: .75rem; + margin: 0 0 1.25rem; + padding: .85rem; + border: 1px solid rgb(73 103 88 / 18%); + border-radius: 1rem; + background: rgb(255 253 248 / 68%); + } + + .privacy-item { display: flex; align-items: center; gap: .65rem; min-width: 0; } + + .privacy-badge { + flex: 0 0 auto; + padding: .2rem .5rem; + border-radius: 999px; + font-size: .67rem; + font-weight: 850; + letter-spacing: .06em; + text-transform: uppercase; + } + + .privacy-badge.visible { color: #345143; background: #dce9df; } + .privacy-badge.masked { color: #664411; background: #f7e5bc; } + .privacy-badge.excluded { color: #6e3030; background: #f3dcdc; } + .privacy-item span:last-child { overflow: hidden; color: var(--muted); font-size: .78rem; text-overflow: ellipsis; white-space: nowrap; } + .eyebrow { margin: 0 0 .55rem; color: var(--sunrise); @@ -253,6 +281,8 @@ @media (max-width: 760px) { main { margin-top: 1.5rem; } + .privacy-guide { grid-template-columns: 1fr; } + .privacy-item span:last-child { white-space: normal; } .shop-grid { grid-template-columns: 1fr; } .product { grid-template-columns: 1fr; } .product-art { min-height: 18rem; } @@ -265,21 +295,36 @@ -