Skip to content

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

Merged
merged 10 commits into from
Jun 16, 2023

Conversation

ryan953
Copy link
Member

@ryan953 ryan953 commented Jun 11, 2023

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

@ryan953 ryan953 requested a review from a team as a code owner June 11, 2023 19:53
@github-actions github-actions bot added the Scope: Frontend Automatically applied to PRs that change frontend components label Jun 11, 2023
@ryan953 ryan953 force-pushed the ryan953/47991-hydrate-replay-frame-types branch from b937961 to a557240 Compare June 11, 2023 19:56
@ryan953 ryan953 force-pushed the ryan953/47991-hydrate-replay-frame-types branch from a557240 to f1ce45e Compare June 11, 2023 22:25
@ryan953 ryan953 force-pushed the ryan953/47991-hydrate-replay-frame-types branch from f1ce45e to b45d507 Compare June 11, 2023 22:53
Comment on lines 214 to 236
...this._breadcrumbFrames.filter(frame =>
['replay.init', 'ui.click', 'replay.mutations', 'ui.slowClickDetected'].includes(
frame.category
)
),
Copy link
Member Author

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.

Copy link
Member Author

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

Copy link
Member

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

Copy link
Member Author

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!

@ryan953 ryan953 requested review from billyvg and eliashussary June 12, 2023 15:30
const time = new Date(frame.timestamp * 1000);
return {
...frame,
offsetMS: Math.abs(time.getTime() - startTimestampMs),
Copy link
Member

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.

Suggested change
offsetMS: Math.abs(time.getTime() - startTimestampMs),
offsetMs: Math.abs(time.getTime() - startTimestampMs),

Comment on lines +16 to +25
export function recordingEndFrame(replayRecord: ReplayRecord): RecordingFrame {
return {
type: EventType.Custom,
timestamp: replayRecord.finished_at.getTime(),
data: {
tag: 'replay.end',
payload: {},
},
};
}
Copy link
Member

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.

Copy link
Member Author

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)

Comment on lines +96 to +104
// TODO(replays): We should get correct timestamps from the backend instead
// of having to fix them up here.
Copy link
Member

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.

Copy link
Member Author

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

Comment on lines 214 to 236
...this._breadcrumbFrames.filter(frame =>
['replay.init', 'ui.click', 'replay.mutations', 'ui.slowClickDetected'].includes(
frame.category
)
),
Copy link
Member

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

@ryan953 ryan953 merged commit cb68d30 into master Jun 16, 2023
@ryan953 ryan953 deleted the ryan953/47991-hydrate-replay-frame-types branch June 16, 2023 17:25
ryan953 added a commit that referenced this pull request Jun 16, 2023
@github-actions github-actions bot locked and limited conversation to collaborators Jul 2, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Scope: Frontend Automatically applied to PRs that change frontend components
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Replay: Hide Slow/dead/rage click breadcrumb Improve type casting inside of replayDataUtils.tsx
2 participants