Skip to content

Commit

Permalink
fixed http metrics
Browse files Browse the repository at this point in the history
  • Loading branch information
vpalmisano committed Oct 30, 2024
1 parent d10ce66 commit bb16bd1
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 34 deletions.
10 changes: 1 addition & 9 deletions scripts/page-stats.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
/* global webrtcperf */

// Page performance
webrtcperf.httpBitrateStats = new webrtcperf.MeasuredStats({ ttl: 30 })
webrtcperf.httpLatencyStats = new webrtcperf.MeasuredStats({ ttl: 30 })

Expand All @@ -17,18 +16,11 @@ window.collectHttpResourcesStats = () => {
}

if (typeof window.PerformanceObserver === 'function') {
// Stop ServiceWorkers.
/* navigator.serviceWorker.addEventListener('controllerchange', () => {
webrtcperf.unregisterServiceWorkers()
})
webrtcperf.unregisterServiceWorkers() */

// https://nicj.net/resourcetiming-in-practice/
const processEntries = entries => {
const timestamp = Date.now()
entries
.filter(entry => {
// webrtcperf.log(`entry`, entry)
const { duration, transferSize } = entry
// Filter cached entries.
if (!transferSize || duration < 10) {
Expand All @@ -44,5 +36,5 @@ if (typeof window.PerformanceObserver === 'function') {
})
}
const observer = new PerformanceObserver(list => processEntries(list.getEntries()))
observer.observe({ type: 'resource', buffered: true })
observer.observe({ entryTypes: ['resource', 'navigation'], buffered: true })
}
2 changes: 0 additions & 2 deletions src/rtcstats.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,6 @@ export enum PageStatsNames {

/** The page total HTTP received bytes. */
httpRecvBytes = 'httpRecvBytes',
/** The page HTTP receive bitrate. */
httpRecvBitrate = 'httpRecvBitrate',
/** The page HTTP receive latency. */
httpRecvLatency = 'httpRecvLatency',

Expand Down
74 changes: 51 additions & 23 deletions src/session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import * as sdpTransform from 'sdp-transform'
import { gunzipSync } from 'zlib'

import { rtcStatKey, RtcStats, updateRtcStats } from './rtcstats'
import { FastStats } from './stats'
import {
checkChromeExecutable,
downloadUrl,
Expand Down Expand Up @@ -80,11 +81,6 @@ declare global {
startFrameDelay: number
}
let collectVideoEndToEndNetworkDelayStats: () => number
let collectHttpResourcesStats: () => {
recvBytes: number
recvBitrate: number
recvLatency: number
}
let collectCpuPressure: () => number
let collectCustomMetrics: () => Promise<Record<string, number | string>>
let getParticipantName: () => string
Expand Down Expand Up @@ -310,6 +306,7 @@ export class Session extends EventEmitter {
stats: SessionStats = {}
/** The browser opened pages. */
readonly pages = new Map<number, Page>()
readonly httpResourcesStats = new Map<number, { recvBytes: number; recvLatency: FastStats }>()
/** The browser opened pages metrics. */
readonly pagesMetrics = new Map<number, Metrics>()
/** The page warnings count. */
Expand Down Expand Up @@ -920,7 +917,6 @@ window.SERVER_USE_HTTPS = ${this.serverUseHttps};
'scripts/e2e-audio-stats.js',
'scripts/e2e-video-stats.js',
'scripts/playout-delay-hint.js',
'scripts/page-stats.js',
'scripts/save-tracks.js',
'scripts/pressure-stats.js',
]) {
Expand Down Expand Up @@ -989,6 +985,7 @@ window.SERVER_USE_HTTPS = ${this.serverUseHttps};
page.once('close', () => {
log.debug(`page ${index + 1} closed`)
this.pages.delete(index)
this.httpResourcesStats.delete(index)
this.pagesMetrics.delete(index)

if (saveFile) {
Expand Down Expand Up @@ -1053,6 +1050,7 @@ window.SERVER_USE_HTTPS = ${this.serverUseHttps};
interceptions.push({
urlPattern: url,
modifyResponse: async ({ event, body }) => {
const responseHeaders = event.responseHeaders || []
for (const { search, replace, file, headers } of replacements) {
if (search && replace) {
log.debug(`using responseModifiers in: ${event.request.url}: ${search.toString()} => ${replace}`)
Expand All @@ -1063,14 +1061,14 @@ window.SERVER_USE_HTTPS = ${this.serverUseHttps};
}
if (headers) {
for (const [name, value] of Object.entries(headers)) {
event.responseHeaders?.push({
responseHeaders.push({
name,
value,
})
}
}
}
return { body }
return { body, responseHeaders }
},
})
})
Expand Down Expand Up @@ -1347,12 +1345,44 @@ window.SERVER_USE_HTTPS = ${this.serverUseHttps};

await page.exposeFunction('WebRtcPerf_sdpWrite', (sdp: sdpTransform.SessionDescription) => sdpTransform.write(sdp))

/* page.on('workercreated', worker =>
log.debug(`Worker created: ${worker.url()}`),
)
page.on('workerdestroyed', worker =>
log.debug(`Worker created: ${worker.url()}`),
) */
// HTTP stats.
const resourcesStats = {
recvBytes: 0,
recvLatency: new FastStats({ store_data: false }),
}
this.httpResourcesStats.set(index, resourcesStats)

const pendingRequests = new Map<string, { timestamp: number }>()
pageCDPSession.on('Network.requestWillBeSent', event => {
if (event.request.url.startsWith('data:')) return
const { requestId, timestamp } = event
pendingRequests.set(requestId, { timestamp })
})

pageCDPSession.on('Network.responseReceived', event => {
const request = pendingRequests.get(event.requestId)
if (!request) return
const { response } = event
if (response.fromDiskCache) {
pendingRequests.delete(event.requestId)
return
}
resourcesStats.recvBytes += response.encodedDataLength
})

pageCDPSession.on('Network.dataReceived', event => {
const request = pendingRequests.get(event.requestId)
if (!request) return
resourcesStats.recvBytes += event.encodedDataLength
})

pageCDPSession.on('Network.loadingFinished', event => {
const request = pendingRequests.get(event.requestId)
if (!request) return
pendingRequests.delete(event.requestId)
const { timestamp } = event
resourcesStats.recvLatency.push(timestamp - request.timestamp)
})

// open the page url
try {
Expand Down Expand Up @@ -1486,7 +1516,6 @@ window.SERVER_USE_HTTPS = ${this.serverUseHttps};
const videoStartFrameDelayStats: Record<string, number> = {}
const videoEndToEndNetworkDelayStats: Record<string, number> = {}
const httpRecvBytesStats: Record<string, number> = {}
const httpRecvBitrateStats: Record<string, number> = {}
const httpRecvLatencyStats: Record<string, number> = {}
const pageCpu: Record<string, number> = {}
const pageMemory: Record<string, number> = {}
Expand All @@ -1512,20 +1541,20 @@ window.SERVER_USE_HTTPS = ${this.serverUseHttps};
audioEndToEndDelay,
videoEndToEndDelay,
videoEndToEndNetworkDelay,
httpResourcesStats,
cpuPressure,
customMetrics,
} = await page.evaluate(async () => ({
peerConnectionStats: await collectPeerConnectionStats(),
audioEndToEndDelay: collectAudioEndToEndStats(),
videoEndToEndDelay: collectVideoEndToEndStats(),
videoEndToEndNetworkDelay: collectVideoEndToEndNetworkDelayStats(),
httpResourcesStats: collectHttpResourcesStats(),
cpuPressure: collectCpuPressure(),
customMetrics: 'collectCustomMetrics' in window ? collectCustomMetrics() : null,
}))
const { participantName } = peerConnectionStats

const httpResourcesStats = this.httpResourcesStats.get(pageIndex)

// Get host from the first collected remote address.
if (!peerConnectionStats.signalingHost && peerConnectionStats.stats.length) {
const values = Object.values(peerConnectionStats.stats[0])
Expand Down Expand Up @@ -1573,11 +1602,11 @@ window.SERVER_USE_HTTPS = ${this.serverUseHttps};
}

// HTTP stats.
if (httpResourcesStats.recvBytes !== undefined) httpRecvBytesStats[pageKey] = httpResourcesStats.recvBytes
if (httpResourcesStats.recvBitrate !== undefined)
httpRecvBitrateStats[pageKey] = httpResourcesStats.recvBitrate
if (httpResourcesStats.recvLatency !== undefined)
httpRecvLatencyStats[pageKey] = httpResourcesStats.recvLatency
if (httpResourcesStats) {
if (httpResourcesStats.recvBytes > 0) httpRecvBytesStats[pageKey] = httpResourcesStats.recvBytes
if (httpResourcesStats.recvLatency.length)
httpRecvLatencyStats[pageKey] = httpResourcesStats.recvLatency.amean()
}

if (cpuPressure !== undefined) cpuPressureStats[pageKey] = cpuPressure

Expand Down Expand Up @@ -1667,7 +1696,6 @@ window.SERVER_USE_HTTPS = ${this.serverUseHttps};
collectedStats.videoStartFrameDelay = videoStartFrameDelayStats
collectedStats.videoEndToEndNetworkDelay = videoEndToEndNetworkDelayStats
collectedStats.httpRecvBytes = httpRecvBytesStats
collectedStats.httpRecvBitrate = httpRecvBitrateStats
collectedStats.httpRecvLatency = httpRecvLatencyStats
collectedStats.cpuPressure = cpuPressureStats
collectedStats.pageCpu = pageCpu
Expand Down

0 comments on commit bb16bd1

Please sign in to comment.