-
-
Notifications
You must be signed in to change notification settings - Fork 4.4k
ref(replays): Hydrate Replay Frame* types for a more typesafe ui #50707
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
b937961
to
a557240
Compare
a557240
to
f1ce45e
Compare
f1ce45e
to
b45d507
Compare
...this._breadcrumbFrames.filter(frame => | ||
['replay.init', 'ui.click', 'replay.mutations', 'ui.slowClickDetected'].includes( | ||
frame.category | ||
) | ||
), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is going to filter out custom frames now, so like "Redux Action" for example won't have a home anymore.
We can put it back in here for sure, but maybe it's also a good time to ask where the best spots are for it to be.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also this hides the different dead/slow/rage click events! #50590
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should leave custom breadcrumbs in instead of taking it away. I know some users use the redux crumbs and/or custom crumbs and expect them to be there. I know we have one request for crumbs to be searchable and in the timeline even.
I do agree we should start to think about how to treat them.
#50590 says we should have the dead/rage clicks visible for us too
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ya. i sort of noticed that the custom ones were removed after the fact. fixing now!
const time = new Date(frame.timestamp * 1000); | ||
return { | ||
...frame, | ||
offsetMS: Math.abs(time.getTime() - startTimestampMs), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We generally treat abbreviations as a word, but there's no documentation for it (nor can I find an eslint rule for it), but it's also inconsistently used here.
offsetMS: Math.abs(time.getTime() - startTimestampMs), | |
offsetMs: Math.abs(time.getTime() - startTimestampMs), |
export function recordingEndFrame(replayRecord: ReplayRecord): RecordingFrame { | ||
return { | ||
type: EventType.Custom, | ||
timestamp: replayRecord.finished_at.getTime(), | ||
data: { | ||
tag: 'replay.end', | ||
payload: {}, | ||
}, | ||
}; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this actually get used? I can't recall ever seeing it in a replay.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a slight tweak on what we were doing before.
Before: the code would amend the timestamp of the first rrweb event to be earlier. This is so that rrweb aligned with the earliest crumb&span&error data we got.
There was also a replay-init
breadcrumb created that was inconsistently displayed in the timeline & breadcrumb list.
The code would insert a replay-end
rrweb event, so the rrweb player would have an end timestamp that matches the last crumb&span&error data.
Thinking about this fresh:
- I still do think it's nice to have the
replay-init
breadcrumb, and we should display it. - It's important to have the rrweb events match crumb&span&error data so that timeline rendering matches with the player. This could accounts for some drift between the sdk/serverside 'duration' being different from the calculated one; but i don't think it's the whole story (duration on the index page is not calculated, and can be days long)
// TODO(replays): We should get correct timestamps from the backend instead | ||
// of having to fix them up here. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we track how often these two timestamps are still mismatched? It's more of a SDK issue than backend.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ya good call. i'll throw it into amplitude so we can see the good vs. bad counts and maybe be able to group by unique replayid
...this._breadcrumbFrames.filter(frame => | ||
['replay.init', 'ui.click', 'replay.mutations', 'ui.slowClickDetected'].includes( | ||
frame.category | ||
) | ||
), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should leave custom breadcrumbs in instead of taking it away. I know some users use the redux crumbs and/or custom crumbs and expect them to be there. I know we have one request for crumbs to be searchable and in the timeline even.
I do agree we should start to think about how to treat them.
#50590 says we should have the dead/rage clicks visible for us too
9d45aab
to
003ddb4
Compare
The idea here is that we can have some standard base-types (BreadcrumbFrame, SpanFrame, and ErrorFrame) which we can return from our ReplayReader instance. With memoized returns we can reduce the amount of iterations that we run against the arrays whenever we're switching tabs in the Replay Details view, this will come at a cost of some more memory.
This PR focuses on adding the new hydrated type definitions, and doing the up-front work to insert missing fields to make things consistent and easy to use. More fields could be added over time too (like bringing back
transformCrumbs()
or some more specific version.)To follow up we will need to go through each component and convert types into the new *Frame system. The only tough areas will be the Breadcrumb List and Timeline. Both of those expect arrays of type Breadcrumb, but not they'll be getting Breadcrumb, Spans, and Errors mixed together. It'll be a small matter of some if-statements and then using the correct field.
Related to #47991
Fixes #50590
Fixes #46130