Skip to content

Commit 1c9f09f

Browse files
committed
keep most recent trace id, use the current trace id if no transaction event
1 parent ffc6cd9 commit 1c9f09f

File tree

5 files changed

+32
-12
lines changed

5 files changed

+32
-12
lines changed

dev-packages/browser-integration-tests/utils/replayEventTemplates.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@ const DEFAULT_REPLAY_EVENT = {
77
type: 'replay_event',
88
timestamp: expect.any(Number),
99
error_ids: [],
10-
trace_ids: [],
11-
traces_by_timestamp: [],
10+
trace_ids: [expect.any(String)],
11+
traces_by_timestamp: [
12+
[expect.any(Number), expect.any(String)],
13+
],
1214
urls: [expect.stringContaining('/index.html')],
1315
replay_id: expect.stringMatching(/\w{32}/),
1416
replay_start_timestamp: expect.any(Number),

packages/replay-internal/src/coreHandlers/handleAfterSendEvent.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ function handleTransactionEvent(replay: ReplayContainer, event: TransactionEvent
3737
// Collect traceIds in _context regardless of `recordingMode`
3838
// In error mode, _context gets cleared on every checkout
3939
// We limit to max. 100 transactions linked
40-
if (event.contexts?.trace?.trace_id && event.timestamp && replayContext.traceIds.size < 100) {
41-
replayContext.traceIds.add([event.timestamp, event.contexts.trace.trace_id]);
40+
if (event.contexts?.trace?.trace_id && event.start_timestamp && replayContext.traceIds.length < 100) {
41+
replayContext.traceIds.push([event.start_timestamp, event.contexts.trace.trace_id]);
4242
}
4343
}
4444

packages/replay-internal/src/replay.ts

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
/* eslint-disable max-lines */ // TODO: We might want to split this file up
22
import type { ReplayRecordingMode, Span } from '@sentry/core';
3-
import { getActiveSpan, getClient, getRootSpan, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, spanToJSON } from '@sentry/core';
3+
import {
4+
getActiveSpan,
5+
getClient,
6+
getCurrentScope,
7+
getRootSpan,
8+
SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,
9+
spanToJSON,
10+
} from '@sentry/core';
411
import { EventType, record } from '@sentry-internal/rrweb';
512
import {
613
BUFFER_CHECKOUT_TIME,
@@ -192,7 +199,7 @@ export class ReplayContainer implements ReplayContainerInterface {
192199
this._hasInitializedCoreListeners = false;
193200
this._context = {
194201
errorIds: new Set(),
195-
traceIds: new Set(),
202+
traceIds: [],
196203
urls: [],
197204
initialTimestamp: Date.now(),
198205
initialUrl: '',
@@ -1097,7 +1104,11 @@ export class ReplayContainer implements ReplayContainerInterface {
10971104
private _clearContext(): void {
10981105
// XXX: `initialTimestamp` and `initialUrl` do not get cleared
10991106
this._context.errorIds.clear();
1100-
this._context.traceIds.clear();
1107+
// We want to preserve the most recent trace id for the next replay segment.
1108+
// This is so that we can associate replay events w/ the trace.
1109+
if (this._context.traceIds.length > 1) {
1110+
this._context.traceIds = this._context.traceIds.slice(-1);
1111+
}
11011112
this._context.urls = [];
11021113
}
11031114

@@ -1125,11 +1136,17 @@ export class ReplayContainer implements ReplayContainerInterface {
11251136
* Return and clear _context
11261137
*/
11271138
private _popEventContext(): PopEventContext {
1139+
if (this._context.traceIds.length === 0) {
1140+
const currentTraceId = getCurrentScope().getPropagationContext().traceId;
1141+
if (currentTraceId) {
1142+
this._context.traceIds.push([-1, currentTraceId]);
1143+
}
1144+
}
11281145
const _context = {
11291146
initialTimestamp: this._context.initialTimestamp,
11301147
initialUrl: this._context.initialUrl,
11311148
errorIds: Array.from(this._context.errorIds),
1132-
traceIds: Array.from(this._context.traceIds),
1149+
traceIds: this._context.traceIds,
11331150
urls: this._context.urls,
11341151
};
11351152

packages/replay-internal/src/types/replay.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -348,9 +348,9 @@ export interface InternalEventContext extends CommonEventContext {
348348
errorIds: Set<string>;
349349

350350
/**
351-
* Set of [timestamp, trace_id] tuples for Sentry traces that have occurred during a replay segment
351+
* List of <timestamp, trace_id> for Sentry traces that have occurred during a replay segment
352352
*/
353-
traceIds: Set<[number, string]>;
353+
traceIds: Array<[number, string]>;
354354
}
355355

356356
export type Sampled = false | 'session' | 'buffer';

packages/replay-internal/src/util/sendReplayRequest.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,14 @@ export async function sendReplayRequest({
3737
return Promise.resolve({});
3838
}
3939

40+
const uniqueTraceIds = Array.from(new Set(traceIds.map(([_ts, traceId]) => traceId)));
4041
const baseEvent: ReplayEvent = {
4142
type: REPLAY_EVENT_NAME,
4243
replay_start_timestamp: initialTimestamp / 1000,
4344
timestamp: timestamp / 1000,
4445
error_ids: errorIds,
45-
trace_ids: traceIds.map(([_ts, traceId]) => traceId),
46-
traces_by_timestamp: traceIds.map(([ts, traceId]) => [ts, traceId]),
46+
trace_ids: uniqueTraceIds,
47+
traces_by_timestamp: traceIds.filter(([_ts, traceId]) => uniqueTraceIds.includes(traceId)).map(([ts, traceId]) => [ts, traceId]),
4748
urls,
4849
replay_id: replayId,
4950
segment_id,

0 commit comments

Comments
 (0)