Skip to content

Commit

Permalink
♻️ split measures in eventCounts and timings
Browse files Browse the repository at this point in the history
  • Loading branch information
bcaudan committed Oct 22, 2020
1 parent c5ed675 commit cac2164
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 91 deletions.
87 changes: 33 additions & 54 deletions packages/rum/src/domain/rumEventsCollection/view/trackViews.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -482,82 +482,82 @@ describe('rum view measures', () => {
it('should track error count', () => {
const { lifeCycle } = setupBuilder.build()
expect(getHandledCount()).toEqual(1)
expect(getViewEvent(0).measures.errorCount).toEqual(0)
expect(getViewEvent(0).eventCounts.errorCount).toEqual(0)

lifeCycle.notify(LifeCycleEventType.ERROR_COLLECTED, {} as any)
lifeCycle.notify(LifeCycleEventType.ERROR_COLLECTED, {} as any)
history.pushState({}, '', '/bar')

expect(getHandledCount()).toEqual(3)
expect(getViewEvent(1).measures.errorCount).toEqual(2)
expect(getViewEvent(2).measures.errorCount).toEqual(0)
expect(getViewEvent(1).eventCounts.errorCount).toEqual(2)
expect(getViewEvent(2).eventCounts.errorCount).toEqual(0)
})

it('should track long task count', () => {
const { lifeCycle } = setupBuilder.build()
expect(getHandledCount()).toEqual(1)
expect(getViewEvent(0).measures.longTaskCount).toEqual(0)
expect(getViewEvent(0).eventCounts.longTaskCount).toEqual(0)

lifeCycle.notify(LifeCycleEventType.PERFORMANCE_ENTRY_COLLECTED, FAKE_LONG_TASK)
history.pushState({}, '', '/bar')

expect(getHandledCount()).toEqual(3)
expect(getViewEvent(1).measures.longTaskCount).toEqual(1)
expect(getViewEvent(2).measures.longTaskCount).toEqual(0)
expect(getViewEvent(1).eventCounts.longTaskCount).toEqual(1)
expect(getViewEvent(2).eventCounts.longTaskCount).toEqual(0)
})

it('should track resource count', () => {
const { lifeCycle } = setupBuilder.build()
expect(getHandledCount()).toEqual(1)
expect(getViewEvent(0).measures.resourceCount).toEqual(0)
expect(getViewEvent(0).eventCounts.resourceCount).toEqual(0)

lifeCycle.notify(LifeCycleEventType.RESOURCE_ADDED_TO_BATCH)
history.pushState({}, '', '/bar')

expect(getHandledCount()).toEqual(3)
expect(getViewEvent(1).measures.resourceCount).toEqual(1)
expect(getViewEvent(2).measures.resourceCount).toEqual(0)
expect(getViewEvent(1).eventCounts.resourceCount).toEqual(1)
expect(getViewEvent(2).eventCounts.resourceCount).toEqual(0)
})

it('should track user action count', () => {
const { lifeCycle } = setupBuilder.build()
expect(getHandledCount()).toEqual(1)
expect(getViewEvent(0).measures.userActionCount).toEqual(0)
expect(getViewEvent(0).eventCounts.userActionCount).toEqual(0)

lifeCycle.notify(LifeCycleEventType.CUSTOM_ACTION_COLLECTED, { action: FAKE_CUSTOM_USER_ACTION, context: {} })
lifeCycle.notify(LifeCycleEventType.AUTO_ACTION_COMPLETED, FAKE_AUTO_USER_ACTION as AutoUserAction)
history.pushState({}, '', '/bar')

expect(getHandledCount()).toEqual(3)
expect(getViewEvent(1).measures.userActionCount).toEqual(2)
expect(getViewEvent(2).measures.userActionCount).toEqual(0)
expect(getViewEvent(1).eventCounts.userActionCount).toEqual(2)
expect(getViewEvent(2).eventCounts.userActionCount).toEqual(0)
})

it('should reset event count when the view changes', () => {
const { lifeCycle } = setupBuilder.build()
expect(getHandledCount()).toEqual(1)
expect(getViewEvent(0).measures.resourceCount).toEqual(0)
expect(getViewEvent(0).eventCounts.resourceCount).toEqual(0)

lifeCycle.notify(LifeCycleEventType.RESOURCE_ADDED_TO_BATCH)
history.pushState({}, '', '/bar')

expect(getHandledCount()).toEqual(3)
expect(getViewEvent(1).measures.resourceCount).toEqual(1)
expect(getViewEvent(2).measures.resourceCount).toEqual(0)
expect(getViewEvent(1).eventCounts.resourceCount).toEqual(1)
expect(getViewEvent(2).eventCounts.resourceCount).toEqual(0)

lifeCycle.notify(LifeCycleEventType.RESOURCE_ADDED_TO_BATCH)
lifeCycle.notify(LifeCycleEventType.RESOURCE_ADDED_TO_BATCH)
history.pushState({}, '', '/baz')

expect(getHandledCount()).toEqual(5)
expect(getViewEvent(3).measures.resourceCount).toEqual(2)
expect(getViewEvent(4).measures.resourceCount).toEqual(0)
expect(getViewEvent(3).eventCounts.resourceCount).toEqual(2)
expect(getViewEvent(4).eventCounts.resourceCount).toEqual(0)
})

it('should update measures when notified with a PERFORMANCE_ENTRY_COLLECTED event (throttled)', () => {
it('should update eventCounts when notified with a PERFORMANCE_ENTRY_COLLECTED event (throttled)', () => {
const { lifeCycle, clock } = setupBuilder.withFakeClock().build()
expect(getHandledCount()).toEqual(1)
expect(getViewEvent(0).measures).toEqual({
expect(getViewEvent(0).eventCounts).toEqual({
errorCount: 0,
longTaskCount: 0,
resourceCount: 0,
Expand All @@ -571,22 +571,18 @@ describe('rum view measures', () => {
clock.tick(THROTTLE_VIEW_UPDATE_PERIOD)

expect(getHandledCount()).toEqual(2)
expect(getViewEvent(1).measures).toEqual({
domComplete: 456,
domContentLoaded: 345,
domInteractive: 234,
expect(getViewEvent(1).eventCounts).toEqual({
errorCount: 0,
loadEventEnd: 567,
longTaskCount: 0,
resourceCount: 0,
userActionCount: 0,
})
})

it('should update measures when notified with a RESOURCE_ADDED_TO_BATCH event (throttled)', () => {
it('should update eventCounts when notified with a RESOURCE_ADDED_TO_BATCH event (throttled)', () => {
const { lifeCycle, clock } = setupBuilder.withFakeClock().build()
expect(getHandledCount()).toEqual(1)
expect(getViewEvent(0).measures).toEqual({
expect(getViewEvent(0).eventCounts).toEqual({
errorCount: 0,
longTaskCount: 0,
resourceCount: 0,
Expand All @@ -600,18 +596,18 @@ describe('rum view measures', () => {
clock.tick(THROTTLE_VIEW_UPDATE_PERIOD)

expect(getHandledCount()).toEqual(2)
expect(getViewEvent(1).measures).toEqual({
expect(getViewEvent(1).eventCounts).toEqual({
errorCount: 0,
longTaskCount: 0,
resourceCount: 1,
userActionCount: 0,
})
})

it('should update measures when ending a view', () => {
it('should update eventCounts when ending a view', () => {
const { lifeCycle } = setupBuilder.build()
expect(getHandledCount()).toEqual(1)
expect(getViewEvent(0).measures).toEqual({
expect(getViewEvent(0).eventCounts).toEqual({
errorCount: 0,
longTaskCount: 0,
resourceCount: 0,
Expand All @@ -625,26 +621,21 @@ describe('rum view measures', () => {
history.pushState({}, '', '/bar')

expect(getHandledCount()).toEqual(3)
expect(getViewEvent(1).measures).toEqual({
domComplete: 456,
domContentLoaded: 345,
domInteractive: 234,
expect(getViewEvent(1).eventCounts).toEqual({
errorCount: 0,
firstContentfulPaint: 123,
loadEventEnd: 567,
longTaskCount: 0,
resourceCount: 0,
userActionCount: 0,
})
expect(getViewEvent(2).measures).toEqual({
expect(getViewEvent(2).eventCounts).toEqual({
errorCount: 0,
longTaskCount: 0,
resourceCount: 0,
userActionCount: 0,
})
})

it('should not update measures after ending a view', () => {
it('should not update eventCounts after ending a view', () => {
const { lifeCycle, clock } = setupBuilder.withFakeClock().build()
expect(getHandledCount()).toEqual(1)

Expand Down Expand Up @@ -698,18 +689,12 @@ describe('rum view measures', () => {
}
})

it('should not set load measures to the second view', () => {
expect(getLoadMeasures(secondView.last)).toEqual({
domComplete: undefined,
domContentLoaded: undefined,
domInteractive: undefined,
firstContentfulPaint: undefined,
loadEventEnd: undefined,
})
it('should not set timings to the second view', () => {
expect(secondView.last.timings).toEqual({})
})

it('should set measures only on the initial view', () => {
expect(getLoadMeasures(initialView.last)).toEqual({
it('should set timings only on the initial view', () => {
expect(initialView.last.timings).toEqual({
domComplete: 456,
domContentLoaded: 345,
domInteractive: 234,
Expand All @@ -718,19 +703,13 @@ describe('rum view measures', () => {
})
})

it('should not update the initial view duration when updating it with new measures', () => {
it('should not update the initial view duration when updating it with new timings', () => {
expect(initialView.end.duration).toBe(VIEW_DURATION)
expect(initialView.last.duration).toBe(VIEW_DURATION)
})

it('should update the initial view loadingTime following the loadEventEnd value', () => {
expect(initialView.last.loadingTime).toBe(FAKE_NAVIGATION_ENTRY.loadEventEnd)
})

function getLoadMeasures({
measures: { domComplete, domContentLoaded, domInteractive, firstContentfulPaint, loadEventEnd },
}: View) {
return { domComplete, domContentLoaded, domInteractive, firstContentfulPaint, loadEventEnd }
}
})
})
12 changes: 6 additions & 6 deletions packages/rum/src/domain/rumEventsCollection/view/trackViews.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ export interface View {
id: string
location: Location
referrer: string
measures: ViewMeasures
timings: Timings
eventCounts: EventCounts
documentVersion: number
startTime: number
duration: number
Expand All @@ -23,16 +24,14 @@ export interface ViewCreatedEvent {
startTime: number
}

interface Timings {
export interface Timings {
firstContentfulPaint?: number
domInteractive?: number
domContentLoaded?: number
domComplete?: number
loadEventEnd?: number
}

export type ViewMeasures = Timings & EventCounts

export enum ViewLoadingType {
INITIAL_LOAD = 'initial_load',
ROUTE_CHANGE = 'route_change',
Expand Down Expand Up @@ -111,7 +110,7 @@ function newView(
resourceCount: 0,
userActionCount: 0,
}
let timings: Timings | undefined
let timings: Timings = {}
let documentVersion = 0
let loadingTime: number | undefined
let endTime: number | undefined
Expand Down Expand Up @@ -147,14 +146,15 @@ function newView(
documentVersion += 1
lifeCycle.notify(LifeCycleEventType.VIEW_UPDATED, {
documentVersion,
eventCounts,
id,
loadingTime,
loadingType,
location,
referrer,
startTime,
timings,
duration: (endTime === undefined ? performance.now() : endTime) - startTime,
measures: { ...timings, ...eventCounts },
})
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,23 +24,25 @@ describe('viewCollection', () => {
const view = {
documentVersion: 3,
duration: 100,
eventCounts: {
errorCount: 10,
longTaskCount: 10,
resourceCount: 10,
userActionCount: 10,
},
id: 'xxx',
loadingTime: 20,
loadingType: ViewLoadingType.INITIAL_LOAD,
location: {},
measures: {
referrer: '',
startTime: 1234,
timings: {
domComplete: 10,
domContentLoaded: 10,
domInteractive: 10,
errorCount: 10,
firstContentfulPaint: 10,
loadEventEnd: 10,
longTaskCount: 10,
resourceCount: 10,
userActionCount: 10,
},
referrer: '',
startTime: 1234,
}
lifeCycle.notify(LifeCycleEventType.VIEW_UPDATED, view as View)

Expand Down Expand Up @@ -92,23 +94,25 @@ describe('viewCollection V2', () => {
const view = {
documentVersion: 3,
duration: 100,
eventCounts: {
errorCount: 10,
longTaskCount: 10,
resourceCount: 10,
userActionCount: 10,
},
id: 'xxx',
loadingTime: 20,
loadingType: ViewLoadingType.INITIAL_LOAD,
location: {},
measures: {
referrer: '',
startTime: 1234,
timings: {
domComplete: 10,
domContentLoaded: 10,
domInteractive: 10,
errorCount: 10,
firstContentfulPaint: 10,
loadEventEnd: 10,
longTaskCount: 10,
resourceCount: 10,
userActionCount: 10,
},
referrer: '',
startTime: 1234,
}
lifeCycle.notify(LifeCycleEventType.VIEW_UPDATED, view as View)

Expand Down
30 changes: 15 additions & 15 deletions packages/rum/src/domain/rumEventsCollection/view/viewCollection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@ function processViewUpdate(view: View) {
loadingTime: msToNs(view.loadingTime),
loadingType: view.loadingType,
measures: {
...view.measures,
domComplete: msToNs(view.measures.domComplete),
domContentLoaded: msToNs(view.measures.domContentLoaded),
domInteractive: msToNs(view.measures.domInteractive),
firstContentfulPaint: msToNs(view.measures.firstContentfulPaint),
loadEventEnd: msToNs(view.measures.loadEventEnd),
...view.eventCounts,
domComplete: msToNs(view.timings.domComplete),
domContentLoaded: msToNs(view.timings.domContentLoaded),
domInteractive: msToNs(view.timings.domInteractive),
firstContentfulPaint: msToNs(view.timings.firstContentfulPaint),
loadEventEnd: msToNs(view.timings.loadEventEnd),
},
},
}
Expand All @@ -52,23 +52,23 @@ function processViewUpdateV2(view: View) {
type: RumEventType.VIEW,
view: {
action: {
count: view.measures.userActionCount,
count: view.eventCounts.userActionCount,
},
domComplete: msToNs(view.measures.domComplete),
domContentLoaded: msToNs(view.measures.domContentLoaded),
domInteractive: msToNs(view.measures.domInteractive),
domComplete: msToNs(view.timings.domComplete),
domContentLoaded: msToNs(view.timings.domContentLoaded),
domInteractive: msToNs(view.timings.domInteractive),
error: {
count: view.measures.errorCount,
count: view.eventCounts.errorCount,
},
firstContentfulPaint: msToNs(view.measures.firstContentfulPaint),
loadEventEnd: msToNs(view.measures.loadEventEnd),
firstContentfulPaint: msToNs(view.timings.firstContentfulPaint),
loadEventEnd: msToNs(view.timings.loadEventEnd),
loadingTime: msToNs(view.loadingTime),
loadingType: view.loadingType,
longTask: {
count: view.measures.longTaskCount,
count: view.eventCounts.longTaskCount,
},
resource: {
count: view.measures.resourceCount,
count: view.eventCounts.resourceCount,
},
timeSpent: msToNs(view.duration),
},
Expand Down
Loading

0 comments on commit cac2164

Please sign in to comment.