From bc3be3641d67aaa7cbcd9e31a7fb14c42b92c318 Mon Sep 17 00:00:00 2001 From: Warren <5959690+wrn14897@users.noreply.github.com> Date: Wed, 28 Aug 2024 04:05:08 -0700 Subject: [PATCH 1/9] feat: expose deinit + getSessionId methods --- packages/browser/src/index.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/packages/browser/src/index.ts b/packages/browser/src/index.ts index c8e5a20..87da8a3 100644 --- a/packages/browser/src/index.ts +++ b/packages/browser/src/index.ts @@ -154,6 +154,14 @@ class Browser { } } + deinit(): void { + if (!hasWindow()) { + return; + } + + Rum.deinit(); + } + addAction(name: string, attributes?: Attributes): void { if (!hasWindow()) { return; @@ -191,6 +199,10 @@ class Browser { Rum.setGlobalAttributes(attributes); } + getSessionId(): string | undefined { + return Rum.getSessionId(); + } + getSessionUrl(): string | undefined { const now = Date.now(); // A session can only last 4 hours, so we just need to give a time hint of From e60434f513219929b35f2cdb46fca74e74833a8b Mon Sep 17 00:00:00 2001 From: Warren <5959690+wrn14897@users.noreply.github.com> Date: Wed, 28 Aug 2024 04:06:50 -0700 Subject: [PATCH 2/9] docs: add changeset --- .changeset/eighty-kiwis-press.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/eighty-kiwis-press.md diff --git a/.changeset/eighty-kiwis-press.md b/.changeset/eighty-kiwis-press.md new file mode 100644 index 0000000..c2350b4 --- /dev/null +++ b/.changeset/eighty-kiwis-press.md @@ -0,0 +1,5 @@ +--- +'@hyperdx/browser': patch +--- + +feat: expose `deinit` + `getSessionId` methods From b03ee67151bc9367fe7e59f23c268a370e3ec6b2 Mon Sep 17 00:00:00 2001 From: Warren <5959690+wrn14897@users.noreply.github.com> Date: Thu, 29 Aug 2024 09:42:35 -0700 Subject: [PATCH 3/9] feat: expose recordCanvas + mousemove + stop/resume recorder methods --- packages/browser/src/index.ts | 36 +++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/packages/browser/src/index.ts b/packages/browser/src/index.ts index 87da8a3..1a3ae8f 100644 --- a/packages/browser/src/index.ts +++ b/packages/browser/src/index.ts @@ -20,11 +20,13 @@ type BrowserSDKConfig = { disableIntercom?: boolean; disableReplay?: boolean; ignoreClass?: string; - instrumentations?: Instrumentations; ignoreUrls?: IgnoreUrls; + instrumentations?: Instrumentations; maskAllInputs?: boolean; maskAllText?: boolean; maskClass?: string; + mousemove?: boolean; + recordCanvas?: boolean; service: string; tracePropagationTargets?: (string | RegExp)[]; url?: string; @@ -50,11 +52,13 @@ class Browser { disableIntercom = false, disableReplay = false, ignoreClass, - instrumentations = {}, ignoreUrls, + instrumentations = {}, maskAllInputs = true, maskAllText = false, maskClass, + recordCanvas = false, + mousemove = true, service, tracePropagationTargets, url, @@ -111,14 +115,18 @@ class Browser { if (disableReplay !== true) { SessionRecorder.init({ - debug, - url: `${urlBase}/v1/logs`, apiKey, - maskTextSelector: maskAllText ? '*' : undefined, - maskAllInputs: maskAllInputs, blockClass, + debug, ignoreClass, + maskAllInputs: maskAllInputs, maskTextClass: maskClass, + maskTextSelector: maskAllText ? '*' : undefined, + recordCanvas, + sampling: { + mousemove, + }, + url: `${urlBase}/v1/logs`, }); } @@ -162,6 +170,22 @@ class Browser { Rum.deinit(); } + stopSessionRecorder(): void { + if (!hasWindow()) { + return; + } + + SessionRecorder.stop(); + } + + resumeSessionRecorder(): void { + if (!hasWindow()) { + return; + } + + SessionRecorder.resume(); + } + addAction(name: string, attributes?: Attributes): void { if (!hasWindow()) { return; From d000a5ffb7453b92d64f558539b66af2fd34a5d9 Mon Sep 17 00:00:00 2001 From: Warren <5959690+wrn14897@users.noreply.github.com> Date: Thu, 29 Aug 2024 09:46:43 -0700 Subject: [PATCH 4/9] docs: update changeset --- .changeset/eighty-kiwis-press.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/eighty-kiwis-press.md b/.changeset/eighty-kiwis-press.md index c2350b4..07629e4 100644 --- a/.changeset/eighty-kiwis-press.md +++ b/.changeset/eighty-kiwis-press.md @@ -2,4 +2,4 @@ '@hyperdx/browser': patch --- -feat: expose `deinit` + `getSessionId` methods +feat: expose `deinit` + `getSessionId` + `stopSessionRecorder` + `resumeSessionRecorder` methods, add `recordCanvas` + `mousemove` options From cd58042a44025bcb1ed8833071416061a89b80f1 Mon Sep 17 00:00:00 2001 From: Warren <5959690+wrn14897@users.noreply.github.com> Date: Thu, 29 Aug 2024 09:55:08 -0700 Subject: [PATCH 5/9] feat: expose sampling option --- .changeset/eighty-kiwis-press.md | 2 +- packages/browser/src/index.ts | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.changeset/eighty-kiwis-press.md b/.changeset/eighty-kiwis-press.md index 07629e4..8e04600 100644 --- a/.changeset/eighty-kiwis-press.md +++ b/.changeset/eighty-kiwis-press.md @@ -2,4 +2,4 @@ '@hyperdx/browser': patch --- -feat: expose `deinit` + `getSessionId` + `stopSessionRecorder` + `resumeSessionRecorder` methods, add `recordCanvas` + `mousemove` options +feat: expose `deinit` + `getSessionId` + `stopSessionRecorder` + `resumeSessionRecorder` methods, add `recordCanvas` + `sampling` options diff --git a/packages/browser/src/index.ts b/packages/browser/src/index.ts index 1a3ae8f..e2c27e7 100644 --- a/packages/browser/src/index.ts +++ b/packages/browser/src/index.ts @@ -1,6 +1,8 @@ import type { RumOtelWebConfig } from '@hyperdx/otel-web'; import Rum from '@hyperdx/otel-web'; -import SessionRecorder from '@hyperdx/otel-web-session-recorder'; +import SessionRecorder, { + RumRecorderConfig, +} from '@hyperdx/otel-web-session-recorder'; import opentelemetry, { Attributes } from '@opentelemetry/api'; import { resolveAsyncGlobal } from './utils'; @@ -25,8 +27,8 @@ type BrowserSDKConfig = { maskAllInputs?: boolean; maskAllText?: boolean; maskClass?: string; - mousemove?: boolean; recordCanvas?: boolean; + sampling?: RumRecorderConfig['sampling']; service: string; tracePropagationTargets?: (string | RegExp)[]; url?: string; @@ -58,7 +60,7 @@ class Browser { maskAllText = false, maskClass, recordCanvas = false, - mousemove = true, + sampling, service, tracePropagationTargets, url, @@ -123,9 +125,7 @@ class Browser { maskTextClass: maskClass, maskTextSelector: maskAllText ? '*' : undefined, recordCanvas, - sampling: { - mousemove, - }, + sampling, url: `${urlBase}/v1/logs`, }); } From 86a0c5bacdd271810130b58ff43f1065ed451820 Mon Sep 17 00:00:00 2001 From: Warren <5959690+wrn14897@users.noreply.github.com> Date: Thu, 5 Sep 2024 13:54:13 -0700 Subject: [PATCH 6/9] rollback: deinit method --- .changeset/eighty-kiwis-press.md | 2 +- packages/browser/src/index.ts | 8 -------- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/.changeset/eighty-kiwis-press.md b/.changeset/eighty-kiwis-press.md index 8e04600..00a1f3a 100644 --- a/.changeset/eighty-kiwis-press.md +++ b/.changeset/eighty-kiwis-press.md @@ -2,4 +2,4 @@ '@hyperdx/browser': patch --- -feat: expose `deinit` + `getSessionId` + `stopSessionRecorder` + `resumeSessionRecorder` methods, add `recordCanvas` + `sampling` options +feat: expose `getSessionId` + `stopSessionRecorder` + `resumeSessionRecorder` methods, add `recordCanvas` + `sampling` options diff --git a/packages/browser/src/index.ts b/packages/browser/src/index.ts index e2c27e7..7ddc80d 100644 --- a/packages/browser/src/index.ts +++ b/packages/browser/src/index.ts @@ -162,14 +162,6 @@ class Browser { } } - deinit(): void { - if (!hasWindow()) { - return; - } - - Rum.deinit(); - } - stopSessionRecorder(): void { if (!hasWindow()) { return; From 3d4f12d8c3a7cdf7cc57ab89a619005891ce2da7 Mon Sep 17 00:00:00 2001 From: Warren <5959690+wrn14897@users.noreply.github.com> Date: Thu, 5 Sep 2024 19:23:56 -0700 Subject: [PATCH 7/9] docs: update doc --- packages/browser/README.md | 105 ++++++++++++++++++++++++++++++++----- 1 file changed, 92 insertions(+), 13 deletions(-) diff --git a/packages/browser/README.md b/packages/browser/README.md index 425ea00..35efa8f 100644 --- a/packages/browser/README.md +++ b/packages/browser/README.md @@ -20,14 +20,44 @@ HyperDX.init({ }); ``` -### (Optional) Attach User Information or Metadata - -Attaching user information will allow you to search/filter sessions and events in HyperDX. This can be called at any point during the client session. The current client session and all events sent after the call will be associated with the user information. - -`userEmail`, `userName`, and `teamName` will populate the sessions UI with the corresponding values, but can be omitted. Any other additional values can be specified and used to search for events. +#### Options + +- `apiKey` - Your HyperDX Ingestion API Key. +- `service` - The service name events will show up as in HyperDX. +- `tracePropagationTargets` - A list of regex patterns to match against HTTP + requests to link frontend and backend traces, it will add an additional + `traceparent` header to all requests matching any of the patterns. This should + be set to your backend API domain (ex. `api.yoursite.com`). +- `consoleCapture` - (Optional) Capture all console logs (default `false`). +- `advancedNetworkCapture` - (Optional) Capture full request/response headers + and bodies (default false). +- `url` - (Optional) The OpenTelemetry collector URL, only needed for + self-hosted instances. +- `maskAllInputs` - (Optional) Whether to mask all input fields in session + replay (default `false`). +- `maskAllText` - (Optional) Whether to mask all text in session replay (default + `false`). +- `disableIntercom` - (Optional) Whether to disable Intercom integration (default `false`) +- `disableReplay` - (Optional) Whether to disable session replay (default `false`) +- `recordCanvas` - (Optional) Whether to record canvas elements (default `false`) +- `sampling` - (Optional) The sampling [config](https://github.com/rrweb-io/rrweb/blob/5fbb904edb653f3da17e6775ee438d81ef0bba83/docs/recipes/optimize-storage.md?plain=1#L22) in the recording + +## Additional Configuration + +### Attach User Information or Metadata + +Attaching user information will allow you to search/filter sessions and events +in HyperDX. This can be called at any point during the client session. The +current client session and all events sent after the call will be associated +with the user information. + +`userEmail`, `userName`, and `teamName` will populate the sessions UI with the +corresponding values, but can be omitted. Any other additional values can be +specified and used to search for events. ```js HyperDX.setGlobalAttributes({ + userId: user.id, userEmail: user.email, userName: user.name, teamName: user.team.name, @@ -35,9 +65,26 @@ HyperDX.setGlobalAttributes({ }); ``` -### (Optional) Send Custom Actions +### Auto Capture React Error Boundary Errors + +If you're using React, you can automatically capture errors that occur within +React error boundaries by passing your error boundary component +into the `attachToReactErrorBoundary` function. + +```js +// Import your ErrorBoundary (we're using react-error-boundary as an example) +import { ErrorBoundary } from 'react-error-boundary'; + +// This will hook into the ErrorBoundary component and capture any errors that occur +// within any instance of it. +HyperDX.attachToReactErrorBoundary(ErrorBoundary); +``` + +### Send Custom Actions -To explicitly track a specific application event (ex. sign up, submission, etc.), you can call the `addAction` function with an event name and optional event metadata. +To explicitly track a specific application event (ex. sign up, submission, +etc.), you can call the `addAction` function with an event name and optional +event metadata. Example: @@ -49,20 +96,52 @@ HyperDX.addAction('Form-Completed', { }); ``` -### (Optional) Enable Network Capture Dynamically +### Enable Network Capture Dynamically -To enable or disable network capture dynamically, simply invoke the `enableAdvancedNetworkCapture` or `disableAdvancedNetworkCapture` function as needed. +To enable or disable network capture dynamically, simply invoke the +`enableAdvancedNetworkCapture` or `disableAdvancedNetworkCapture` function as +needed. ```js HyperDX.enableAdvancedNetworkCapture(); ``` -### (Optional) React ErrorBoundary Integration +### Stop/Resume Session Recorder Dynamically -To enable automatic error tracking with ErrorBoundary, simply attach the HyperDX error handler to the ErrorBoundary component. +To stop or resume session recording dynamically, simply invoke the +`resumeSessionRecorder` or `stopSessionRecorder` function as needed. ```js -import ErrorBoundary from 'react-error-boundary'; +HyperDX.resumeSessionRecorder(); +``` -HyperDX.attachToReactErrorBoundary(ErrorBoundary); +### Enable Resource Timing for CORS Requests + +If your frontend application makes API requests to a different domain, you can +optionally enable the `Timing-Allow-Origin` +[header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Timing-Allow-Origin) +to be sent with the request. This will allow HyperDX to capture fine-grained +resource timing information for the request such as DNS lookup, response +download, etc. via +[PerformanceResourceTiming](https://developer.mozilla.org/en-US/docs/Web/API/PerformanceResourceTiming). + +If you're using `express` with `cors` packages, you can use the following +snippet to enable the header: + +```js +var cors = require('cors'); +var onHeaders = require('on-headers'); + +// ... all your stuff + +app.use(function (req, res, next) { + onHeaders(res, function () { + var allowOrigin = res.getHeader('Access-Control-Allow-Origin'); + if (allowOrigin) { + res.setHeader('Timing-Allow-Origin', allowOrigin); + } + }); + next(); +}); +app.use(cors()); ``` From 0f873e338f4f5285c3166da5ed8df984bd2d07b3 Mon Sep 17 00:00:00 2001 From: Warren <5959690+wrn14897@users.noreply.github.com> Date: Thu, 5 Sep 2024 19:24:53 -0700 Subject: [PATCH 8/9] docs: one more --- packages/browser/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/browser/README.md b/packages/browser/README.md index 35efa8f..d895804 100644 --- a/packages/browser/README.md +++ b/packages/browser/README.md @@ -40,7 +40,7 @@ HyperDX.init({ - `disableIntercom` - (Optional) Whether to disable Intercom integration (default `false`) - `disableReplay` - (Optional) Whether to disable session replay (default `false`) - `recordCanvas` - (Optional) Whether to record canvas elements (default `false`) -- `sampling` - (Optional) The sampling [config](https://github.com/rrweb-io/rrweb/blob/5fbb904edb653f3da17e6775ee438d81ef0bba83/docs/recipes/optimize-storage.md?plain=1#L22) in the recording +- `sampling` - (Optional) The sampling [config](https://github.com/rrweb-io/rrweb/blob/5fbb904edb653f3da17e6775ee438d81ef0bba83/docs/recipes/optimize-storage.md?plain=1#L22) in the session recording ## Additional Configuration From 4dd199a34037080e5249e41b9e282b93c2a01320 Mon Sep 17 00:00:00 2001 From: Warren <5959690+wrn14897@users.noreply.github.com> Date: Fri, 6 Sep 2024 12:01:23 -0700 Subject: [PATCH 9/9] docs: add getSessionId --- packages/browser/README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/packages/browser/README.md b/packages/browser/README.md index d895804..77f954e 100644 --- a/packages/browser/README.md +++ b/packages/browser/README.md @@ -145,3 +145,12 @@ app.use(function (req, res, next) { }); app.use(cors()); ``` + +### Retrieve Session ID + +To retrieve the current session ID, you can call the `getSessionId` function. + +```js +const sessionId = HyperDX.getSessionId(); +``` +