Skip to content
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

Show session recording durations in sessions list when available #4853

Merged
merged 9 commits into from
Jun 25, 2021

Conversation

mariusandra
Copy link
Collaborator

Changes

Testing locally with some random sessions it does bump a few "1sec" sessions to "~10sec" territory and add a few other minutes here and there:

Before:
Screenshot 2021-06-22 at 23 57 59

After:
image

Checklist

  • All querysets/queries filter by Organization, by Team, and by User
  • Django backend tests
  • Jest frontend tests
  • Cypress end-to-end tests
  • Migrations are safe to run at scale (e.g. PostHog Cloud) – present proof if not obvious
  • Frontend/CSS is usable at 320px (iPhone SE) and decent at 360px (most phones)
  • Breaking changes are backwards-compatible. Ensure old/new frontend requests work with new/old backends, and vice versa.

@mariusandra mariusandra marked this pull request as ready for review June 23, 2021 08:10
@mariusandra mariusandra requested a review from paolodamico June 23, 2021 08:27
@timgl
Copy link
Collaborator

timgl commented Jun 23, 2021

This is a good solution but the original issue raised was about "Distribution of Session Lengths" in the sessions insight (internal link for example). I'd be harder to solve though as you'd need to do a query across both the events table and session recordings table.

Maybe the actual solution is trying to figure out why $pageleave doesn't get sent? I suspect it may have something to do with the fact that we're using that beacon to also send session recording data which is really big

@mariusandra
Copy link
Collaborator Author

There were several issues raised in the thread, including this one about incorrect durations in the sessions list. That's what the "more context in issue" bit above is referring to as well.

As for "Distribution of Session Lengths", there's no easy solution and what I replied in the thread still holds true: the best bet is to wait until we start showing a distribution of times between funnel steps.

Copying from the thread (with slight cleanup):

  • This will be soon possible with a funnel from pageview to pageleave for a specific URL. It’s already there for self-hosted users with postgres.
  • The “distribution of session lengths” table with a filter for a specific URL will probably be wrong. I think it’ll also consider it as a session if the user visited this URL twice, but then visited many other pages in between
  • It’s easy to get the full time spent in a session from a recording, but not so much for individual pages visited. Session recording events aren't tagged with page URLs and we'd have to parse a lot of json. Implementing it this way will require quite some dev time, has many unknowns (where do we store this? precalculation? …) and might not be worth it in the end.
  • Thus the best solution is still to wait a bit until we support this in funnels :)

Copy link
Contributor

@paolodamico paolodamico left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few minor comments, but code-wise looks good.

Not sure if displaying the session duration just relying on the recording size is the best approach here though. What if we didn't have a recording for the entirety of the session? I know for instance some users were conditionally turning session recording in certain pages only.

yield {"id": recording["session_id"], "viewed": recording["session_id"] in viewed}
if isinstance(recording["duration"], datetime.timedelta):
# postgres
recording_duration = recording["duration"].seconds
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be better to use recording["duration"].total_seconds() in case the timedelta is not set with the seconds property?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh django, you continue to surprise me :)

frontend/src/types.ts Show resolved Hide resolved
@@ -211,7 +217,9 @@ export function SessionsView({ personIds, isPersonPage = false }: SessionsTableP
</div>

<ResizableTable
locale={{ emptyText: 'No Sessions on ' + dayjs(selectedDate).format('YYYY-MM-DD') }}
locale={{
emptyText: selectedDate ? 'No Sessions on ' + selectedDate.format('YYYY-MM-DD') : 'No Sessions',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Date format would look better like this (and in line with the new tooltips & legends)

selectedDate.year() == dayjs().year() ? 'MMM D' : 'MMM D, YYYY'

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cool! we should probably util this some day

@@ -104,6 +104,12 @@ export function SessionsView({ personIds, isPersonPage = false }: SessionsTableP
{
title: 'Session duration',
render: function RenderDuration(session: SessionType) {
if (session.session_recordings.length > 0) {
const sum = session.session_recordings
.map(({ recording_duration }) => recording_duration)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if we need to do recording_duration || 0 in case it's null or undefined from the backend?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should always have some value, but to be sure, I added a or 0 in the backend.

@mariusandra
Copy link
Collaborator Author

I added one fix to also update the session end time according to the recording duration, when it makes sense to do so.

Not sure if displaying the session duration just relying on the recording size is the best approach here though. What if we didn't have a recording for the entirety of the session? I know for instance some users were conditionally turning session recording in certain pages only.

Well, we do Math.max(duration_from_recordings, duration_from_events), so this should be fine. Worst case, nothing changes. Best case, the length will be a bit longer.

@mariusandra mariusandra requested a review from paolodamico June 24, 2021 15:41
Copy link
Contributor

@paolodamico paolodamico left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚢 !

@paolodamico
Copy link
Contributor

Unrelated failing tests

@paolodamico paolodamico merged commit 11e18c2 into master Jun 25, 2021
@paolodamico paolodamico deleted the session-recording-duration branch June 25, 2021 08:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants