Skip to content

Commit

Permalink
πŸ› [RUMF-71] do not report negative performance timing duration (#264)
Browse files Browse the repository at this point in the history
* πŸ› [RUMF-71] do not report negative performance timing duration

* πŸ”‡ [RUM] remove logs for abnormal duration

* πŸ‘Œ [RUMF-71] discard the whole performance entry if it looks abnormal
  • Loading branch information
BenoitZugmeyer committed Feb 12, 2020
1 parent 7e2a99d commit 33178dc
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 48 deletions.
73 changes: 28 additions & 45 deletions packages/rum/src/resourceUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,57 +39,40 @@ export function computeResourceKind(timing: PerformanceResourceTiming) {
return ResourceKind.OTHER
}

const durationPairs: Array<[keyof PerformanceResourceTiming, keyof PerformanceResourceTiming]> = [
['connectStart', 'connectEnd'],
['domainLookupStart', 'domainLookupEnd'],
['responseStart', 'responseEnd'],
['requestStart', 'responseStart'],
['redirectStart', 'redirectEnd'],
['secureConnectionStart', 'connectEnd'],
]
function reporteAbnormalEntry(entry: PerformanceResourceTiming) {
let error = ''
for (const [start, end] of durationPairs) {
if (entry[start] < 0) {
error += `${start} is negative\n`
} else if (entry[start] > entry[end]) {
error += `${start} is greater than ${end}\n`
}
}
if (error) {
addMonitoringMessage(`Got an abnormal PerformanceResourceTiming:
${error}
Entry: ${JSON.stringify(entry)}`)
}
function formatTiming(start: number, end: number) {
return { duration: msToNs(end - start), start: msToNs(start) }
}

function isValidTiming(start: number, end: number) {
return start > 0 && end > 0 && end >= start
}

export function computePerformanceResourceDetails(
entry?: PerformanceResourceTiming
): PerformanceResourceDetails | undefined {
if (entry && hasTimingAllowedAttributes(entry)) {
reporteAbnormalEntry(entry)
return {
connect: { duration: msToNs(entry.connectEnd - entry.connectStart), start: msToNs(entry.connectStart) },
dns: {
duration: msToNs(entry.domainLookupEnd - entry.domainLookupStart),
start: msToNs(entry.domainLookupStart),
},
download: { duration: msToNs(entry.responseEnd - entry.responseStart), start: msToNs(entry.responseStart) },
firstByte: { duration: msToNs(entry.responseStart - entry.requestStart), start: msToNs(entry.requestStart) },
redirect:
entry.redirectStart > 0
? { duration: msToNs(entry.redirectEnd - entry.redirectStart), start: msToNs(entry.redirectStart) }
: undefined,
ssl:
entry.secureConnectionStart > 0
? {
duration: msToNs(entry.connectEnd - entry.secureConnectionStart),
start: msToNs(entry.secureConnectionStart),
}
: undefined,
}
if (!entry || !hasTimingAllowedAttributes(entry)) {
return undefined
}
if (
!isValidTiming(entry.connectStart, entry.connectEnd) ||
!isValidTiming(entry.domainLookupStart, entry.domainLookupEnd) ||
!isValidTiming(entry.responseStart, entry.responseEnd) ||
!isValidTiming(entry.requestStart, entry.responseStart)
) {
return undefined
}
return {
connect: formatTiming(entry.connectStart, entry.connectEnd),
dns: formatTiming(entry.domainLookupStart, entry.domainLookupEnd),
download: formatTiming(entry.responseStart, entry.responseEnd),
firstByte: formatTiming(entry.requestStart, entry.responseStart),
redirect: isValidTiming(entry.redirectStart, entry.redirectEnd)
? formatTiming(entry.redirectStart, entry.redirectEnd)
: undefined,
ssl: isValidTiming(entry.secureConnectionStart, entry.connectEnd)
? formatTiming(entry.secureConnectionStart, entry.connectEnd)
: undefined,
}
return undefined
}

export function computeSize(entry?: PerformanceResourceTiming) {
Expand Down
47 changes: 45 additions & 2 deletions packages/rum/test/rum.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,8 +150,11 @@ describe('rum handle performance entry', () => {
const entry: Partial<PerformanceResourceTiming> = {
connectEnd: 10,
connectStart: 3,
domainLookupEnd: 3,
domainLookupStart: 3,
entryType: 'resource',
name: 'http://localhost/test',
requestStart: 20,
responseEnd: 100,
responseStart: 25,
}
Expand All @@ -163,8 +166,48 @@ describe('rum handle performance entry', () => {
new LifeCycle()
)
const resourceEvent = getEntry(addRumEvent, 0) as RumResourceEvent
expect(resourceEvent.http.performance!.connect.duration).toEqual(7 * 1e6)
expect(resourceEvent.http.performance!.download.duration).toEqual(75 * 1e6)
expect(resourceEvent.http.performance!.connect!.duration).toEqual(7 * 1e6)
expect(resourceEvent.http.performance!.download!.duration).toEqual(75 * 1e6)
})

describe('ignore invalid performance entry', () => {
it('when it has a negative timing start', () => {
const entry: Partial<PerformanceResourceTiming> = {
connectEnd: 10,
connectStart: -3,
entryType: 'resource',
name: 'http://localhost/test',
responseEnd: 100,
responseStart: 25,
}

handleResourceEntry(
configuration as Configuration,
entry as PerformanceResourceTiming,
addRumEvent,
new LifeCycle()
)
const resourceEvent = getEntry(addRumEvent, 0) as RumResourceEvent
expect(resourceEvent.http.performance).toBe(undefined)
})

it('when it has timing start after its end', () => {
const entry: Partial<PerformanceResourceTiming> = {
entryType: 'resource',
name: 'http://localhost/test',
responseEnd: 25,
responseStart: 100,
}

handleResourceEntry(
configuration as Configuration,
entry as PerformanceResourceTiming,
addRumEvent,
new LifeCycle()
)
const resourceEvent = getEntry(addRumEvent, 0) as RumResourceEvent
expect(resourceEvent.http.performance).toBe(undefined)
})
})
})

Expand Down
2 changes: 1 addition & 1 deletion test/e2e/scenario/agents.scenario.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ describe('rum', () => {
expect(timing.http.method).toEqual('GET')
expect((timing.http as any).status_code).toEqual(200)
expect(timing.duration).toBeGreaterThan(0)
expect(timing.http.performance!.download.start).toBeGreaterThan(0)
expect(timing.http.performance!.download!.start).toBeGreaterThan(0)
})

it('should send performance timings along the view events', async () => {
Expand Down

0 comments on commit 33178dc

Please sign in to comment.