Skip to content

Commit fbe054e

Browse files
authored
feat: expose getSessionId + stopSessionRecorder + resumeSessionRecorder methods (#173)
1. expose `getSessionId` + `stopSessionRecorder` + `resumeSessionRecorder` methods 2. add `recordCanvas` + `sampling` options
1 parent b429708 commit fbe054e

File tree

3 files changed

+141
-20
lines changed

3 files changed

+141
-20
lines changed

.changeset/eighty-kiwis-press.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@hyperdx/browser': patch
3+
---
4+
5+
feat: expose `getSessionId` + `stopSessionRecorder` + `resumeSessionRecorder` methods, add `recordCanvas` + `sampling` options

packages/browser/README.md

Lines changed: 101 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,24 +20,71 @@ HyperDX.init({
2020
});
2121
```
2222

23-
### (Optional) Attach User Information or Metadata
24-
25-
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.
26-
27-
`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.
23+
#### Options
24+
25+
- `apiKey` - Your HyperDX Ingestion API Key.
26+
- `service` - The service name events will show up as in HyperDX.
27+
- `tracePropagationTargets` - A list of regex patterns to match against HTTP
28+
requests to link frontend and backend traces, it will add an additional
29+
`traceparent` header to all requests matching any of the patterns. This should
30+
be set to your backend API domain (ex. `api.yoursite.com`).
31+
- `consoleCapture` - (Optional) Capture all console logs (default `false`).
32+
- `advancedNetworkCapture` - (Optional) Capture full request/response headers
33+
and bodies (default false).
34+
- `url` - (Optional) The OpenTelemetry collector URL, only needed for
35+
self-hosted instances.
36+
- `maskAllInputs` - (Optional) Whether to mask all input fields in session
37+
replay (default `false`).
38+
- `maskAllText` - (Optional) Whether to mask all text in session replay (default
39+
`false`).
40+
- `disableIntercom` - (Optional) Whether to disable Intercom integration (default `false`)
41+
- `disableReplay` - (Optional) Whether to disable session replay (default `false`)
42+
- `recordCanvas` - (Optional) Whether to record canvas elements (default `false`)
43+
- `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
44+
45+
## Additional Configuration
46+
47+
### Attach User Information or Metadata
48+
49+
Attaching user information will allow you to search/filter sessions and events
50+
in HyperDX. This can be called at any point during the client session. The
51+
current client session and all events sent after the call will be associated
52+
with the user information.
53+
54+
`userEmail`, `userName`, and `teamName` will populate the sessions UI with the
55+
corresponding values, but can be omitted. Any other additional values can be
56+
specified and used to search for events.
2857

2958
```js
3059
HyperDX.setGlobalAttributes({
60+
userId: user.id,
3161
userEmail: user.email,
3262
userName: user.name,
3363
teamName: user.team.name,
3464
// Other custom properties...
3565
});
3666
```
3767

38-
### (Optional) Send Custom Actions
68+
### Auto Capture React Error Boundary Errors
69+
70+
If you're using React, you can automatically capture errors that occur within
71+
React error boundaries by passing your error boundary component
72+
into the `attachToReactErrorBoundary` function.
3973

40-
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.
74+
```js
75+
// Import your ErrorBoundary (we're using react-error-boundary as an example)
76+
import { ErrorBoundary } from 'react-error-boundary';
77+
78+
// This will hook into the ErrorBoundary component and capture any errors that occur
79+
// within any instance of it.
80+
HyperDX.attachToReactErrorBoundary(ErrorBoundary);
81+
```
82+
83+
### Send Custom Actions
84+
85+
To explicitly track a specific application event (ex. sign up, submission,
86+
etc.), you can call the `addAction` function with an event name and optional
87+
event metadata.
4188

4289
Example:
4390

@@ -49,20 +96,61 @@ HyperDX.addAction('Form-Completed', {
4996
});
5097
```
5198

52-
### (Optional) Enable Network Capture Dynamically
99+
### Enable Network Capture Dynamically
53100

54-
To enable or disable network capture dynamically, simply invoke the `enableAdvancedNetworkCapture` or `disableAdvancedNetworkCapture` function as needed.
101+
To enable or disable network capture dynamically, simply invoke the
102+
`enableAdvancedNetworkCapture` or `disableAdvancedNetworkCapture` function as
103+
needed.
55104

56105
```js
57106
HyperDX.enableAdvancedNetworkCapture();
58107
```
59108

60-
### (Optional) React ErrorBoundary Integration
109+
### Stop/Resume Session Recorder Dynamically
61110

62-
To enable automatic error tracking with ErrorBoundary, simply attach the HyperDX error handler to the ErrorBoundary component.
111+
To stop or resume session recording dynamically, simply invoke the
112+
`resumeSessionRecorder` or `stopSessionRecorder` function as needed.
63113

64114
```js
65-
import ErrorBoundary from 'react-error-boundary';
115+
HyperDX.resumeSessionRecorder();
116+
```
66117

67-
HyperDX.attachToReactErrorBoundary(ErrorBoundary);
118+
### Enable Resource Timing for CORS Requests
119+
120+
If your frontend application makes API requests to a different domain, you can
121+
optionally enable the `Timing-Allow-Origin`
122+
[header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Timing-Allow-Origin)
123+
to be sent with the request. This will allow HyperDX to capture fine-grained
124+
resource timing information for the request such as DNS lookup, response
125+
download, etc. via
126+
[PerformanceResourceTiming](https://developer.mozilla.org/en-US/docs/Web/API/PerformanceResourceTiming).
127+
128+
If you're using `express` with `cors` packages, you can use the following
129+
snippet to enable the header:
130+
131+
```js
132+
var cors = require('cors');
133+
var onHeaders = require('on-headers');
134+
135+
// ... all your stuff
136+
137+
app.use(function (req, res, next) {
138+
onHeaders(res, function () {
139+
var allowOrigin = res.getHeader('Access-Control-Allow-Origin');
140+
if (allowOrigin) {
141+
res.setHeader('Timing-Allow-Origin', allowOrigin);
142+
}
143+
});
144+
next();
145+
});
146+
app.use(cors());
68147
```
148+
149+
### Retrieve Session ID
150+
151+
To retrieve the current session ID, you can call the `getSessionId` function.
152+
153+
```js
154+
const sessionId = HyperDX.getSessionId();
155+
```
156+

packages/browser/src/index.ts

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import type { RumOtelWebConfig } from '@hyperdx/otel-web';
22
import Rum from '@hyperdx/otel-web';
3-
import SessionRecorder from '@hyperdx/otel-web-session-recorder';
3+
import SessionRecorder, {
4+
RumRecorderConfig,
5+
} from '@hyperdx/otel-web-session-recorder';
46
import opentelemetry, { Attributes } from '@opentelemetry/api';
57

68
import { resolveAsyncGlobal } from './utils';
@@ -20,11 +22,13 @@ type BrowserSDKConfig = {
2022
disableIntercom?: boolean;
2123
disableReplay?: boolean;
2224
ignoreClass?: string;
23-
instrumentations?: Instrumentations;
2425
ignoreUrls?: IgnoreUrls;
26+
instrumentations?: Instrumentations;
2527
maskAllInputs?: boolean;
2628
maskAllText?: boolean;
2729
maskClass?: string;
30+
recordCanvas?: boolean;
31+
sampling?: RumRecorderConfig['sampling'];
2832
service: string;
2933
tracePropagationTargets?: (string | RegExp)[];
3034
url?: string;
@@ -50,11 +54,13 @@ class Browser {
5054
disableIntercom = false,
5155
disableReplay = false,
5256
ignoreClass,
53-
instrumentations = {},
5457
ignoreUrls,
58+
instrumentations = {},
5559
maskAllInputs = true,
5660
maskAllText = false,
5761
maskClass,
62+
recordCanvas = false,
63+
sampling,
5864
service,
5965
tracePropagationTargets,
6066
url,
@@ -111,14 +117,16 @@ class Browser {
111117

112118
if (disableReplay !== true) {
113119
SessionRecorder.init({
114-
debug,
115-
url: `${urlBase}/v1/logs`,
116120
apiKey,
117-
maskTextSelector: maskAllText ? '*' : undefined,
118-
maskAllInputs: maskAllInputs,
119121
blockClass,
122+
debug,
120123
ignoreClass,
124+
maskAllInputs: maskAllInputs,
121125
maskTextClass: maskClass,
126+
maskTextSelector: maskAllText ? '*' : undefined,
127+
recordCanvas,
128+
sampling,
129+
url: `${urlBase}/v1/logs`,
122130
});
123131
}
124132

@@ -154,6 +162,22 @@ class Browser {
154162
}
155163
}
156164

165+
stopSessionRecorder(): void {
166+
if (!hasWindow()) {
167+
return;
168+
}
169+
170+
SessionRecorder.stop();
171+
}
172+
173+
resumeSessionRecorder(): void {
174+
if (!hasWindow()) {
175+
return;
176+
}
177+
178+
SessionRecorder.resume();
179+
}
180+
157181
addAction(name: string, attributes?: Attributes): void {
158182
if (!hasWindow()) {
159183
return;
@@ -191,6 +215,10 @@ class Browser {
191215
Rum.setGlobalAttributes(attributes);
192216
}
193217

218+
getSessionId(): string | undefined {
219+
return Rum.getSessionId();
220+
}
221+
194222
getSessionUrl(): string | undefined {
195223
const now = Date.now();
196224
// A session can only last 4 hours, so we just need to give a time hint of

0 commit comments

Comments
 (0)