Skip to content

Commit a92b382

Browse files
authored
Use trigger config for pre/post duration and recorder config (#1362)
* use trigger config for pre/post duration and recorder config * prettier
1 parent 91c75eb commit a92b382

11 files changed

+128
-85
lines changed

src/browser/core.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ class Rollbar {
126126
);
127127

128128
this.tracing?.configure(this.options);
129-
this.replayManager?.recorder?.configure(this.options);
129+
this.replayManager?.configure(this.options);
130130
this.client.configure(this.options, payloadData);
131131
this.instrumenter?.configure(this.options);
132132
this.setupUnhandledCapture();

src/browser/replay/defaults.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@
55
export default {
66
enabled: false, // Whether recording is enabled
77
autoStart: true, // Start recording automatically when Rollbar initializes
8-
maxSeconds: 300, // Maximum recording duration in seconds
9-
postDuration: 5, // Duration of events to include after a post is triggered, in seconds
108

119
// defaults used by triggers that don't specify them
1210
triggerDefaults: {

src/browser/replay/recorder.js

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,7 @@ export default class Recorder {
5656
// Rollbar options
5757
enabled,
5858
autoStart,
59-
maxSeconds,
60-
postDuration,
61-
triggers,
59+
maxPreDuration,
6260
debug,
6361

6462
// disallowed rrweb options
@@ -72,9 +70,7 @@ export default class Recorder {
7270
this._options = {
7371
enabled,
7472
autoStart,
75-
maxSeconds,
76-
postDuration,
77-
triggers,
73+
maxPreDuration,
7874
debug,
7975
};
8076

@@ -89,12 +85,12 @@ export default class Recorder {
8985
* Calculates the checkout interval in milliseconds.
9086
*
9187
* Recording may span up to two checkout intervals, so the interval is set
92-
* to half of maxSeconds to ensure coverage.
88+
* to half of maxPreDuration to ensure coverage.
9389
*
9490
* @returns {number} Checkout interval in milliseconds
9591
*/
9692
checkoutEveryNms() {
97-
return ((this.options.maxSeconds || 10) * 1000) / 2;
93+
return ((this.options.maxPreDuration || 10) * 1000) / 2;
9894
}
9995

10096
/**

src/browser/replay/replayManager.js

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,14 @@ export default class ReplayManager {
4545
}
4646

4747
this._map = new Map();
48-
this._recorder = new Recorder(options);
48+
this._predicates = new ReplayPredicates(options);
49+
this._recorder = new Recorder({
50+
...options,
51+
maxPreDuration: this._predicates.maxPreDuration,
52+
});
4953
this._tracing = tracing;
5054
this._telemeter = telemeter;
5155
this._trailingStatus = new Map();
52-
this._predicates = new ReplayPredicates(options);
5356
this._scheduledCapture = new ScheduledCapture({
5457
recorder: this._recorder,
5558
tracing: this._tracing,
@@ -85,6 +88,14 @@ export default class ReplayManager {
8588
return status === TrailingStatus.SENT || status === TrailingStatus.SKIPPED;
8689
}
8790

91+
configure(options) {
92+
this._predicates.configure(options);
93+
this._recorder.configure({
94+
...options,
95+
maxPreDuration: this._predicates.maxPreDuration,
96+
});
97+
}
98+
8899
/**
89100
* Exports recording and telemetry spans, then stores the tracing payload in the map.
90101
*
@@ -123,7 +134,7 @@ export default class ReplayManager {
123134
const payload = this._tracing.exporter.toPayload();
124135
this._map.set(replayId, payload);
125136

126-
const leadingSeconds = this._recorder.options?.postDuration || 0;
137+
const leadingSeconds = trigger?.postDuration || 0;
127138
if (leadingSeconds > 0) {
128139
this._scheduledCapture.schedule(replayId, occurrenceUuid, leadingSeconds);
129140
this._trailingStatus.set(replayId, TrailingStatus.PENDING);
@@ -149,6 +160,11 @@ export default class ReplayManager {
149160

150161
replayId = replayId || id.gen(8);
151162

163+
/*
164+
* trigger.preDuration and trigger.postDuration are the requested capture
165+
* durations for the trigger. The recorder buffers have been configured to
166+
* handle the max preDuration across all triggers.
167+
*/
152168
const trigger = this._predicates.shouldCaptureForTriggerContext({
153169
...triggerContext,
154170
replayId,

src/browser/replay/replayPredicates.js

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@ export default class ReplayPredicates {
1111
* @param {Object} config - Configuration object containing replay settings.
1212
*/
1313
constructor(config) {
14-
this.config = config || {};
15-
this.triggers = this._triggersWithDefaults(config);
14+
this.configure(config);
1615

1716
this.predicates = {
1817
occurrence: [this.isLevelMatching.bind(this), this.isSampled.bind(this)],
@@ -21,11 +20,23 @@ export default class ReplayPredicates {
2120
};
2221
}
2322

23+
configure(config) {
24+
this.config = config || {};
25+
this.triggers = this._triggersWithDefaults(config);
26+
this.maxPreDuration = this._maxPreDuration();
27+
}
28+
2429
_triggersWithDefaults(config) {
2530
const triggers = config?.triggers || [];
2631
return triggers.map((t) => ({ ...config.triggerDefaults, ...t }));
2732
}
2833

34+
_maxPreDuration() {
35+
if (!this.triggers) return 0;
36+
37+
return Math.max(...this.triggers.map((t) => t.preDuration || 0), 0);
38+
}
39+
2940
/**
3041
* shouldCaptureForTriggerContext - Checks if replay is enabled for a given trigger type.
3142
* Applies all predicates for that trigger type and returns true if all predicates pass

test/browser.replay.recorder.test.js

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,7 @@ describe('Recorder', function () {
4545
expect(recorder.options).to.deep.equal({
4646
enabled: undefined,
4747
autoStart: undefined,
48-
maxSeconds: undefined,
49-
postDuration: undefined,
50-
triggers: undefined,
48+
maxPreDuration: undefined,
5149
debug: undefined,
5250
});
5351
});
@@ -59,9 +57,7 @@ describe('Recorder', function () {
5957
expect(recorder.options).to.deep.equal({
6058
enabled: true,
6159
autoStart: undefined,
62-
maxSeconds: undefined,
63-
postDuration: undefined,
64-
triggers: undefined,
60+
maxPreDuration: undefined,
6561
debug: undefined,
6662
});
6763
});
@@ -419,29 +415,25 @@ describe('Recorder', function () {
419415
it('should update options', function () {
420416
const recorder = new Recorder({ enabled: true, recordFn: recordFnStub });
421417

422-
recorder.configure({ enabled: false, maxSeconds: 20 });
418+
recorder.configure({ enabled: false, maxPreDuration: 20 });
423419

424420
expect(recorder.options).to.deep.equal({
425421
enabled: false,
426422
autoStart: undefined,
427-
maxSeconds: 20,
428-
postDuration: undefined,
429-
triggers: undefined,
423+
maxPreDuration: 20,
430424
debug: undefined,
431425
});
432426
});
433427

434428
it('should set correct checkoutEveryNms', function () {
435429
const recorder = new Recorder({ enabled: false });
436430

437-
recorder.configure({ enabled: true, maxSeconds: 15 });
431+
recorder.configure({ enabled: true, maxPreDuration: 15 });
438432

439433
expect(recorder.options).to.deep.equal({
440434
enabled: true,
441435
autoStart: undefined,
442-
maxSeconds: 15,
443-
postDuration: undefined,
444-
triggers: undefined,
436+
maxPreDuration: 15,
445437
debug: undefined,
446438
});
447439

test/replay/integration/e2e.test.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,13 @@ describe('Session Replay E2E', function () {
234234
it('should handle trailing and leading replay flow', function (done) {
235235
this.timeout(10000);
236236

237-
recorder.configure({ ...recorder.options, postDuration: 0.1 });
237+
replayManager.configure({
238+
...options.replay,
239+
triggerDefaults: {
240+
preDuration: 300,
241+
postDuration: 0.1,
242+
},
243+
});
238244
recorder.start();
239245

240246
setTimeout(() => {

0 commit comments

Comments
 (0)