@webex/internal-plugin-metrics 3.0.0-beta.177 → 3.0.0-beta.178
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/call-diagnostic/call-diagnostic-metrics-latencies.js +30 -4
- package/dist/call-diagnostic/call-diagnostic-metrics-latencies.js.map +1 -1
- package/dist/metrics.js +1 -1
- package/dist/metrics.types.js.map +1 -1
- package/dist/types/call-diagnostic/call-diagnostic-metrics-latencies.d.ts +10 -1
- package/dist/types/metrics.types.d.ts +1 -1
- package/package.json +8 -8
- package/src/call-diagnostic/call-diagnostic-metrics-latencies.ts +34 -10
- package/src/metrics.types.ts +0 -1
- package/test/unit/spec/call-diagnostic/call-diagnostic-metrics-batcher.ts +4 -0
- package/test/unit/spec/call-diagnostic/call-diagnostic-metrics-latencies.ts +20 -2
|
@@ -25,7 +25,9 @@ var CallDiagnosticLatencies = /*#__PURE__*/function () {
|
|
|
25
25
|
function CallDiagnosticLatencies() {
|
|
26
26
|
(0, _classCallCheck2.default)(this, CallDiagnosticLatencies);
|
|
27
27
|
(0, _defineProperty2.default)(this, "latencyTimestamps", void 0);
|
|
28
|
+
(0, _defineProperty2.default)(this, "precomputedLatencies", void 0);
|
|
28
29
|
this.latencyTimestamps = new _map.default();
|
|
30
|
+
this.precomputedLatencies = new _map.default();
|
|
29
31
|
}
|
|
30
32
|
|
|
31
33
|
/**
|
|
@@ -40,7 +42,7 @@ var CallDiagnosticLatencies = /*#__PURE__*/function () {
|
|
|
40
42
|
/**
|
|
41
43
|
* Store timestamp value
|
|
42
44
|
* @param key - key
|
|
43
|
-
* @param
|
|
45
|
+
* @param value -value
|
|
44
46
|
* @throws
|
|
45
47
|
* @returns
|
|
46
48
|
*/
|
|
@@ -57,6 +59,19 @@ var CallDiagnosticLatencies = /*#__PURE__*/function () {
|
|
|
57
59
|
}
|
|
58
60
|
}
|
|
59
61
|
|
|
62
|
+
/**
|
|
63
|
+
* Store precomputed latency value
|
|
64
|
+
* @param key - key
|
|
65
|
+
* @param value -value
|
|
66
|
+
* @throws
|
|
67
|
+
* @returns
|
|
68
|
+
*/
|
|
69
|
+
}, {
|
|
70
|
+
key: "saveLatency",
|
|
71
|
+
value: function saveLatency(key, value) {
|
|
72
|
+
this.precomputedLatencies.set(key, value);
|
|
73
|
+
}
|
|
74
|
+
|
|
60
75
|
/**
|
|
61
76
|
* Store only the first timestamp value for the given key
|
|
62
77
|
* @param key - key
|
|
@@ -124,7 +139,12 @@ var CallDiagnosticLatencies = /*#__PURE__*/function () {
|
|
|
124
139
|
}, {
|
|
125
140
|
key: "getCallInitJoinReq",
|
|
126
141
|
value: function getCallInitJoinReq() {
|
|
127
|
-
|
|
142
|
+
if (this.latencyTimestamps.get('internal.client.meeting.click.joinbutton')) {
|
|
143
|
+
return this.getDiffBetweenTimestamps('internal.client.meeting.click.joinbutton', 'client.locus.join.request');
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// for cross launch and guest flows
|
|
147
|
+
return this.precomputedLatencies.get('internal.call.init.join.req') || undefined;
|
|
128
148
|
}
|
|
129
149
|
|
|
130
150
|
/**
|
|
@@ -215,7 +235,7 @@ var CallDiagnosticLatencies = /*#__PURE__*/function () {
|
|
|
215
235
|
}, {
|
|
216
236
|
key: "getPageJMT",
|
|
217
237
|
value: function getPageJMT() {
|
|
218
|
-
return this.
|
|
238
|
+
return this.precomputedLatencies.get('internal.client.pageJMT') || undefined;
|
|
219
239
|
}
|
|
220
240
|
|
|
221
241
|
/**
|
|
@@ -225,7 +245,13 @@ var CallDiagnosticLatencies = /*#__PURE__*/function () {
|
|
|
225
245
|
}, {
|
|
226
246
|
key: "getClickToInterstitial",
|
|
227
247
|
value: function getClickToInterstitial() {
|
|
228
|
-
|
|
248
|
+
// for normal join (where green join button exists before interstitial, i.e reminder, space list etc)
|
|
249
|
+
if (this.latencyTimestamps.get('internal.client.meeting.click.joinbutton')) {
|
|
250
|
+
return this.getDiffBetweenTimestamps('internal.client.meeting.click.joinbutton', 'internal.client.meeting.interstitial-window.showed');
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// for cross launch and guest flows
|
|
254
|
+
return this.precomputedLatencies.get('internal.click.to.interstitial') || undefined;
|
|
229
255
|
}
|
|
230
256
|
|
|
231
257
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["CallDiagnosticLatencies","latencyTimestamps","clear","key","value","Date","getTime","saveFirstTimestampOnly","set","has","a","b","start","get","end","undefined","getDiffBetweenTimestamps","interstitialJoinClickTimestamp","mediaFlowStartedTimestamp","Math","min","lobbyTime","getStayLobbyTime","clickToInterstitial","getClickToInterstitial","interstitialToJoinOk","getInterstitialToJoinOK","joinReqResp","getJoinReqResp","ICESetupTime","getICESetupTime","joinConfJMT","getJoinConfJMT","stayLobbyTime"],"sources":["call-diagnostic-metrics-latencies.ts"],"sourcesContent":["/* eslint-disable class-methods-use-this */\n/* eslint-disable valid-jsdoc */\n\nimport {MetricEventNames} from '../metrics.types';\n\n// we only care about client event and feature event for now\n\n/**\n * @description Helper class to store latencies timestamp and to calculate various latencies for CA.\n * @exports\n * @class CallDiagnosticLatencies\n */\nexport default class CallDiagnosticLatencies {\n latencyTimestamps: Map<MetricEventNames, number>;\n\n /**\n * @constructor\n */\n constructor() {\n this.latencyTimestamps = new Map();\n }\n\n /**\n * Clear timestamps\n */\n public clearTimestamps() {\n this.latencyTimestamps.clear();\n }\n\n /**\n * Store timestamp value\n * @param key - key\n * @param value -value\n * @throws\n * @returns\n */\n public saveTimestamp(key: MetricEventNames, value: number = new Date().getTime()) {\n // for some events we're only interested in the first timestamp not last\n // as these events can happen multiple times\n if (key === 'client.media.rx.start' || key === 'client.media.tx.start') {\n this.saveFirstTimestampOnly(key, value);\n } else {\n this.latencyTimestamps.set(key, value);\n }\n }\n\n /**\n * Store only the first timestamp value for the given key\n * @param key - key\n * @param value -value\n * @throws\n * @returns\n */\n saveFirstTimestampOnly(key: MetricEventNames, value: number = new Date().getTime()) {\n if (this.latencyTimestamps.has(key)) {\n return;\n }\n this.latencyTimestamps.set(key, value);\n }\n\n /**\n * Helper to calculate end - start\n * @param a start\n * @param b end\n * @returns latency\n */\n public getDiffBetweenTimestamps(a: MetricEventNames, b: MetricEventNames) {\n const start = this.latencyTimestamps.get(a);\n const end = this.latencyTimestamps.get(b);\n if (start && end) {\n return end - start;\n }\n\n return undefined;\n }\n\n /**\n * Meeting Info Request\n * @note Meeting Info request happen not just in the join phase. CA requires\n * metrics around meeting info request that are only part of join phase.\n * This internal.* event is used to track the real timestamps\n * (when the actual request/response happen). This is because the actual CA event is\n * sent inside the join method on the meeting object based on some logic, but that's not exactly when\n * those events are actually fired. The logic only confirms that they have happened, and we send them over.\n * @returns - latency\n */\n public getMeetingInfoReqResp() {\n return this.getDiffBetweenTimestamps(\n 'internal.client.meetinginfo.request',\n 'internal.client.meetinginfo.response'\n );\n }\n\n /**\n * Interstitial Time\n * @returns - latency\n */\n public getShowInterstitialTime() {\n return this.getDiffBetweenTimestamps(\n 'internal.client.interstitial-window.launched',\n 'internal.client.interstitial-window.click.joinbutton'\n );\n }\n\n /**\n * Call Init Join Request\n * @returns - latency\n */\n public getCallInitJoinReq() {\n return this.getDiffBetweenTimestamps(\n 'internal.client.meeting.click.joinbutton',\n 'client.locus.join.request'\n );\n }\n\n /**\n * Locus Join Request\n * @returns - latency\n */\n public getJoinReqResp() {\n return this.getDiffBetweenTimestamps('client.locus.join.request', 'client.locus.join.response');\n }\n\n /**\n * Locus Join Response Sent Received\n * @returns - latency\n */\n public getJoinRespSentReceived() {\n // TODO: not clear SPARK-440554\n return undefined;\n }\n\n /**\n * Local SDP Generated Remote SDP REceived\n * @returns - latency\n */\n public getLocalSDPGenRemoteSDPRecv() {\n return this.getDiffBetweenTimestamps(\n 'client.media-engine.local-sdp-generated',\n 'client.media-engine.remote-sdp-received'\n );\n }\n\n /**\n * ICE Setup Time\n * @returns - latency\n */\n public getICESetupTime() {\n return this.getDiffBetweenTimestamps('client.ice.start', 'client.ice.end');\n }\n\n /**\n * Audio ICE time\n * @returns - latency\n */\n public getAudioICESetupTime() {\n return this.getDiffBetweenTimestamps('client.ice.start', 'client.ice.end');\n }\n\n /**\n * Video ICE Time\n * @returns - latency\n */\n public getVideoICESetupTime() {\n return this.getDiffBetweenTimestamps('client.ice.start', 'client.ice.end');\n }\n\n /**\n * Share ICE Time\n * @returns - latency\n */\n public getShareICESetupTime() {\n return this.getDiffBetweenTimestamps('client.ice.start', 'client.ice.end');\n }\n\n /**\n * Stay Lobby Time\n * @returns - latency\n */\n public getStayLobbyTime() {\n return this.getDiffBetweenTimestamps(\n 'client.locus.join.response',\n 'internal.host.meeting.participant.admitted'\n );\n }\n\n /**\n * Page JMT\n * @returns - latency\n */\n public getPageJMT() {\n return this.latencyTimestamps.get('internal.client.pageJMT.received') || undefined;\n }\n\n /**\n * Click To Interstitial\n * @returns - latency\n */\n public getClickToInterstitial() {\n return this.getDiffBetweenTimestamps(\n 'internal.client.meeting.click.joinbutton',\n 'internal.client.meeting.interstitial-window.showed'\n );\n }\n\n /**\n * Interstitial To Join Ok\n * @returns - latency\n */\n public getInterstitialToJoinOK() {\n return this.getDiffBetweenTimestamps(\n 'internal.client.interstitial-window.click.joinbutton',\n 'client.locus.join.response'\n );\n }\n\n /**\n * Call Init To MediaEngineReady\n * @returns - latency\n */\n public getCallInitMediaEngineReady() {\n return this.getDiffBetweenTimestamps(\n 'internal.client.interstitial-window.click.joinbutton',\n 'client.media-engine.ready'\n );\n }\n\n /**\n * Interstitial To Media Ok\n * @returns - latency\n */\n public getInterstitialToMediaOKJMT() {\n const interstitialJoinClickTimestamp = this.latencyTimestamps.get(\n 'internal.client.interstitial-window.click.joinbutton'\n );\n\n // get the first timestamp\n const mediaFlowStartedTimestamp = Math.min(\n this.latencyTimestamps.get('client.media.rx.start'),\n this.latencyTimestamps.get('client.media.tx.start')\n );\n\n const lobbyTime = this.getStayLobbyTime() || 0;\n\n if (interstitialJoinClickTimestamp && mediaFlowStartedTimestamp) {\n return mediaFlowStartedTimestamp - interstitialJoinClickTimestamp - lobbyTime;\n }\n\n return undefined;\n }\n\n /**\n * Total JMT\n * @returns - latency\n */\n public getTotalJMT() {\n const clickToInterstitial = this.getClickToInterstitial();\n const interstitialToJoinOk = this.getInterstitialToJoinOK();\n\n if (clickToInterstitial && interstitialToJoinOk) {\n return clickToInterstitial + interstitialToJoinOk;\n }\n\n return undefined;\n }\n\n /**\n * Join Conf JMT\n * @returns - latency\n */\n public getJoinConfJMT() {\n const joinReqResp = this.getJoinReqResp();\n const ICESetupTime = this.getICESetupTime();\n\n if (joinReqResp && ICESetupTime) {\n return joinReqResp + ICESetupTime;\n }\n\n return undefined;\n }\n\n /**\n * Total Media JMT\n * @returns - latency\n */\n public getTotalMediaJMT() {\n const clickToInterstitial = this.getClickToInterstitial();\n const interstitialToJoinOk = this.getInterstitialToJoinOK();\n const joinConfJMT = this.getJoinConfJMT();\n const stayLobbyTime = this.getStayLobbyTime() || 0;\n\n if (clickToInterstitial && interstitialToJoinOk && joinConfJMT) {\n return clickToInterstitial + interstitialToJoinOk + joinConfJMT - stayLobbyTime;\n }\n\n return undefined;\n }\n\n /**\n * Client JMT\n * @returns - latency\n */\n public getClientJMT() {\n const interstitialToJoinOk = this.getInterstitialToJoinOK();\n const joinConfJMT = this.getJoinConfJMT();\n\n if (interstitialToJoinOk && joinConfJMT) {\n return interstitialToJoinOk - joinConfJMT;\n }\n\n return undefined;\n }\n\n /**\n * Audio setup delay receive\n */\n public getAudioJoinRespRxStart() {\n return this.getDiffBetweenTimestamps('client.locus.join.response', 'client.media.rx.start');\n }\n\n /**\n * Video setup delay receive\n */\n public getVideoJoinRespRxStart() {\n return this.getDiffBetweenTimestamps('client.locus.join.response', 'client.media.rx.start');\n }\n\n /**\n * Audio setup delay transmit\n */\n public getAudioJoinRespTxStart() {\n return this.getDiffBetweenTimestamps('client.locus.join.response', 'client.media.tx.start');\n }\n\n /**\n * Video setup delay transmit\n */\n public getVideoJoinRespTxStart() {\n return this.getDiffBetweenTimestamps('client.locus.join.response', 'client.media.tx.start');\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"names":["CallDiagnosticLatencies","latencyTimestamps","precomputedLatencies","clear","key","value","Date","getTime","saveFirstTimestampOnly","set","has","a","b","start","get","end","undefined","getDiffBetweenTimestamps","interstitialJoinClickTimestamp","mediaFlowStartedTimestamp","Math","min","lobbyTime","getStayLobbyTime","clickToInterstitial","getClickToInterstitial","interstitialToJoinOk","getInterstitialToJoinOK","joinReqResp","getJoinReqResp","ICESetupTime","getICESetupTime","joinConfJMT","getJoinConfJMT","stayLobbyTime"],"sources":["call-diagnostic-metrics-latencies.ts"],"sourcesContent":["/* eslint-disable class-methods-use-this */\n/* eslint-disable valid-jsdoc */\n\nimport {MetricEventNames} from '../metrics.types';\n\n// we only care about client event and feature event for now\n\n/**\n * @description Helper class to store latencies timestamp and to calculate various latencies for CA.\n * @exports\n * @class CallDiagnosticLatencies\n */\nexport default class CallDiagnosticLatencies {\n latencyTimestamps: Map<MetricEventNames, number>;\n precomputedLatencies: Map<string, number>;\n\n /**\n * @constructor\n */\n constructor() {\n this.latencyTimestamps = new Map();\n this.precomputedLatencies = new Map();\n }\n\n /**\n * Clear timestamps\n */\n public clearTimestamps() {\n this.latencyTimestamps.clear();\n }\n\n /**\n * Store timestamp value\n * @param key - key\n * @param value -value\n * @throws\n * @returns\n */\n public saveTimestamp(key: MetricEventNames, value: number = new Date().getTime()) {\n // for some events we're only interested in the first timestamp not last\n // as these events can happen multiple times\n if (key === 'client.media.rx.start' || key === 'client.media.tx.start') {\n this.saveFirstTimestampOnly(key, value);\n } else {\n this.latencyTimestamps.set(key, value);\n }\n }\n\n /**\n * Store precomputed latency value\n * @param key - key\n * @param value -value\n * @throws\n * @returns\n */\n public saveLatency(key: string, value: number) {\n this.precomputedLatencies.set(key, value);\n }\n\n /**\n * Store only the first timestamp value for the given key\n * @param key - key\n * @param value -value\n * @throws\n * @returns\n */\n saveFirstTimestampOnly(key: MetricEventNames, value: number = new Date().getTime()) {\n if (this.latencyTimestamps.has(key)) {\n return;\n }\n this.latencyTimestamps.set(key, value);\n }\n\n /**\n * Helper to calculate end - start\n * @param a start\n * @param b end\n * @returns latency\n */\n public getDiffBetweenTimestamps(a: MetricEventNames, b: MetricEventNames) {\n const start = this.latencyTimestamps.get(a);\n const end = this.latencyTimestamps.get(b);\n if (start && end) {\n return end - start;\n }\n\n return undefined;\n }\n\n /**\n * Meeting Info Request\n * @note Meeting Info request happen not just in the join phase. CA requires\n * metrics around meeting info request that are only part of join phase.\n * This internal.* event is used to track the real timestamps\n * (when the actual request/response happen). This is because the actual CA event is\n * sent inside the join method on the meeting object based on some logic, but that's not exactly when\n * those events are actually fired. The logic only confirms that they have happened, and we send them over.\n * @returns - latency\n */\n public getMeetingInfoReqResp() {\n return this.getDiffBetweenTimestamps(\n 'internal.client.meetinginfo.request',\n 'internal.client.meetinginfo.response'\n );\n }\n\n /**\n * Interstitial Time\n * @returns - latency\n */\n public getShowInterstitialTime() {\n return this.getDiffBetweenTimestamps(\n 'internal.client.interstitial-window.launched',\n 'internal.client.interstitial-window.click.joinbutton'\n );\n }\n\n /**\n * Call Init Join Request\n * @returns - latency\n */\n public getCallInitJoinReq() {\n if (this.latencyTimestamps.get('internal.client.meeting.click.joinbutton')) {\n return this.getDiffBetweenTimestamps(\n 'internal.client.meeting.click.joinbutton',\n 'client.locus.join.request'\n );\n }\n\n // for cross launch and guest flows\n return this.precomputedLatencies.get('internal.call.init.join.req') || undefined;\n }\n\n /**\n * Locus Join Request\n * @returns - latency\n */\n public getJoinReqResp() {\n return this.getDiffBetweenTimestamps('client.locus.join.request', 'client.locus.join.response');\n }\n\n /**\n * Locus Join Response Sent Received\n * @returns - latency\n */\n public getJoinRespSentReceived() {\n // TODO: not clear SPARK-440554\n return undefined;\n }\n\n /**\n * Local SDP Generated Remote SDP REceived\n * @returns - latency\n */\n public getLocalSDPGenRemoteSDPRecv() {\n return this.getDiffBetweenTimestamps(\n 'client.media-engine.local-sdp-generated',\n 'client.media-engine.remote-sdp-received'\n );\n }\n\n /**\n * ICE Setup Time\n * @returns - latency\n */\n public getICESetupTime() {\n return this.getDiffBetweenTimestamps('client.ice.start', 'client.ice.end');\n }\n\n /**\n * Audio ICE time\n * @returns - latency\n */\n public getAudioICESetupTime() {\n return this.getDiffBetweenTimestamps('client.ice.start', 'client.ice.end');\n }\n\n /**\n * Video ICE Time\n * @returns - latency\n */\n public getVideoICESetupTime() {\n return this.getDiffBetweenTimestamps('client.ice.start', 'client.ice.end');\n }\n\n /**\n * Share ICE Time\n * @returns - latency\n */\n public getShareICESetupTime() {\n return this.getDiffBetweenTimestamps('client.ice.start', 'client.ice.end');\n }\n\n /**\n * Stay Lobby Time\n * @returns - latency\n */\n public getStayLobbyTime() {\n return this.getDiffBetweenTimestamps(\n 'client.locus.join.response',\n 'internal.host.meeting.participant.admitted'\n );\n }\n\n /**\n * Page JMT\n * @returns - latency\n */\n public getPageJMT() {\n return this.precomputedLatencies.get('internal.client.pageJMT') || undefined;\n }\n\n /**\n * Click To Interstitial\n * @returns - latency\n */\n public getClickToInterstitial() {\n // for normal join (where green join button exists before interstitial, i.e reminder, space list etc)\n if (this.latencyTimestamps.get('internal.client.meeting.click.joinbutton')) {\n return this.getDiffBetweenTimestamps(\n 'internal.client.meeting.click.joinbutton',\n 'internal.client.meeting.interstitial-window.showed'\n );\n }\n\n // for cross launch and guest flows\n return this.precomputedLatencies.get('internal.click.to.interstitial') || undefined;\n }\n\n /**\n * Interstitial To Join Ok\n * @returns - latency\n */\n public getInterstitialToJoinOK() {\n return this.getDiffBetweenTimestamps(\n 'internal.client.interstitial-window.click.joinbutton',\n 'client.locus.join.response'\n );\n }\n\n /**\n * Call Init To MediaEngineReady\n * @returns - latency\n */\n public getCallInitMediaEngineReady() {\n return this.getDiffBetweenTimestamps(\n 'internal.client.interstitial-window.click.joinbutton',\n 'client.media-engine.ready'\n );\n }\n\n /**\n * Interstitial To Media Ok\n * @returns - latency\n */\n public getInterstitialToMediaOKJMT() {\n const interstitialJoinClickTimestamp = this.latencyTimestamps.get(\n 'internal.client.interstitial-window.click.joinbutton'\n );\n\n // get the first timestamp\n const mediaFlowStartedTimestamp = Math.min(\n this.latencyTimestamps.get('client.media.rx.start'),\n this.latencyTimestamps.get('client.media.tx.start')\n );\n\n const lobbyTime = this.getStayLobbyTime() || 0;\n\n if (interstitialJoinClickTimestamp && mediaFlowStartedTimestamp) {\n return mediaFlowStartedTimestamp - interstitialJoinClickTimestamp - lobbyTime;\n }\n\n return undefined;\n }\n\n /**\n * Total JMT\n * @returns - latency\n */\n public getTotalJMT() {\n const clickToInterstitial = this.getClickToInterstitial();\n const interstitialToJoinOk = this.getInterstitialToJoinOK();\n\n if (clickToInterstitial && interstitialToJoinOk) {\n return clickToInterstitial + interstitialToJoinOk;\n }\n\n return undefined;\n }\n\n /**\n * Join Conf JMT\n * @returns - latency\n */\n public getJoinConfJMT() {\n const joinReqResp = this.getJoinReqResp();\n const ICESetupTime = this.getICESetupTime();\n\n if (joinReqResp && ICESetupTime) {\n return joinReqResp + ICESetupTime;\n }\n\n return undefined;\n }\n\n /**\n * Total Media JMT\n * @returns - latency\n */\n public getTotalMediaJMT() {\n const clickToInterstitial = this.getClickToInterstitial();\n const interstitialToJoinOk = this.getInterstitialToJoinOK();\n const joinConfJMT = this.getJoinConfJMT();\n const stayLobbyTime = this.getStayLobbyTime() || 0;\n\n if (clickToInterstitial && interstitialToJoinOk && joinConfJMT) {\n return clickToInterstitial + interstitialToJoinOk + joinConfJMT - stayLobbyTime;\n }\n\n return undefined;\n }\n\n /**\n * Client JMT\n * @returns - latency\n */\n public getClientJMT() {\n const interstitialToJoinOk = this.getInterstitialToJoinOK();\n const joinConfJMT = this.getJoinConfJMT();\n\n if (interstitialToJoinOk && joinConfJMT) {\n return interstitialToJoinOk - joinConfJMT;\n }\n\n return undefined;\n }\n\n /**\n * Audio setup delay receive\n */\n public getAudioJoinRespRxStart() {\n return this.getDiffBetweenTimestamps('client.locus.join.response', 'client.media.rx.start');\n }\n\n /**\n * Video setup delay receive\n */\n public getVideoJoinRespRxStart() {\n return this.getDiffBetweenTimestamps('client.locus.join.response', 'client.media.rx.start');\n }\n\n /**\n * Audio setup delay transmit\n */\n public getAudioJoinRespTxStart() {\n return this.getDiffBetweenTimestamps('client.locus.join.response', 'client.media.tx.start');\n }\n\n /**\n * Video setup delay transmit\n */\n public getVideoJoinRespTxStart() {\n return this.getDiffBetweenTimestamps('client.locus.join.response', 'client.media.tx.start');\n }\n}\n"],"mappings":"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"}
|
package/dist/metrics.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":[],"sources":["metrics.types.ts"],"sourcesContent":["import {ClientEvent as RawClientEvent} from './call-diagnostic/generated-types-temp/ClientEvent';\nimport {Event as RawEvent} from './call-diagnostic/generated-types-temp/Event';\nimport {MediaQualityEvent as RawMediaQualityEvent} from './call-diagnostic/generated-types-temp/MediaQualityEvent';\n\nexport type Event = Omit<RawEvent, 'event'> & {event: RawClientEvent | RawMediaQualityEvent};\n\nexport type ClientEventError = NonNullable<RawClientEvent['errors']>[0];\n\nexport type SubmitClientEventOptions = {\n meetingId?: string;\n mediaConnections?: any[];\n rawError?: any;\n showToUser?: boolean;\n correlationId?: string;\n};\n\nexport type SubmitMQEOptions = {\n meetingId: string;\n mediaConnections?: any[];\n networkType?: Event['origin']['networkType'];\n};\n\nexport type InternalEvent = {\n name:\n | 'internal.client.meetinginfo.request'\n | 'internal.client.meetinginfo.response'\n | 'internal.reset.join.latencies'\n | 'internal.client.interstitial-window.launched'\n | 'internal.client.meeting.click.joinbutton'\n | 'internal.host.meeting.participant.admitted'\n | 'internal.client.meeting.interstitial-window.showed'\n | 'internal.client.
|
|
1
|
+
{"version":3,"names":[],"sources":["metrics.types.ts"],"sourcesContent":["import {ClientEvent as RawClientEvent} from './call-diagnostic/generated-types-temp/ClientEvent';\nimport {Event as RawEvent} from './call-diagnostic/generated-types-temp/Event';\nimport {MediaQualityEvent as RawMediaQualityEvent} from './call-diagnostic/generated-types-temp/MediaQualityEvent';\n\nexport type Event = Omit<RawEvent, 'event'> & {event: RawClientEvent | RawMediaQualityEvent};\n\nexport type ClientEventError = NonNullable<RawClientEvent['errors']>[0];\n\nexport type SubmitClientEventOptions = {\n meetingId?: string;\n mediaConnections?: any[];\n rawError?: any;\n showToUser?: boolean;\n correlationId?: string;\n};\n\nexport type SubmitMQEOptions = {\n meetingId: string;\n mediaConnections?: any[];\n networkType?: Event['origin']['networkType'];\n};\n\nexport type InternalEvent = {\n name:\n | 'internal.client.meetinginfo.request'\n | 'internal.client.meetinginfo.response'\n | 'internal.reset.join.latencies'\n | 'internal.client.interstitial-window.launched'\n | 'internal.client.meeting.click.joinbutton'\n | 'internal.host.meeting.participant.admitted'\n | 'internal.client.meeting.interstitial-window.showed'\n | 'internal.client.interstitial-window.click.joinbutton';\n payload?: never;\n options?: never;\n};\n\nexport interface ClientEvent {\n name: RawClientEvent['name'];\n payload?: RawClientEvent;\n options: SubmitClientEventOptions;\n}\n\nexport interface BehavioralEvent {\n // TODO: not implemented\n name: 'host.meeting.participant.admitted' | 'sdk.media-flow.started';\n payload?: never;\n options?: never;\n}\n\nexport interface OperationalEvent {\n // TODO: not implemented\n name: never;\n payload?: never;\n options?: never;\n}\n\nexport interface FeatureEvent {\n // TODO: not implemented\n name: never;\n payload?: never;\n options?: never;\n}\n\nexport interface MediaQualityEvent {\n name: RawMediaQualityEvent['name'];\n payload?: RawMediaQualityEvent;\n options: SubmitMQEOptions;\n}\n\nexport type RecursivePartial<T> = {\n [P in keyof T]?: T[P] extends (infer U)[]\n ? RecursivePartial<U>[]\n : T[P] extends object\n ? RecursivePartial<T[P]>\n : T[P];\n};\n\nexport type MetricEventNames =\n | InternalEvent['name']\n | ClientEvent['name']\n | BehavioralEvent['name']\n | OperationalEvent['name']\n | FeatureEvent['name']\n | MediaQualityEvent['name'];\n\nexport type ClientType = NonNullable<RawEvent['origin']['clientInfo']>['clientType'];\nexport type SubClientType = NonNullable<RawEvent['origin']['clientInfo']>['subClientType'];\nexport type NetworkType = NonNullable<RawEvent['origin']>['networkType'];\n\nexport type ClientEventPayload = RecursivePartial<ClientEvent['payload']>;\n\nexport type MediaQualityEventAudioSetupDelayPayload = NonNullable<\n MediaQualityEvent['payload']\n>['audioSetupDelay'];\nexport type MediaQualityEventVideoSetupDelayPayload = NonNullable<\n MediaQualityEvent['payload']\n>['videoSetupDelay'];\n\nexport type SubmitMQEPayload = RecursivePartial<MediaQualityEvent['payload']> & {\n intervals: NonNullable<MediaQualityEvent['payload']>['intervals'];\n};\n\nexport type SubmitInternalEvent = (args: {\n name: InternalEvent['name'];\n payload?: RecursivePartial<InternalEvent['payload']>;\n options?: any;\n}) => void;\n\nexport type SubmitBehavioralEvent = (args: {\n name: BehavioralEvent['name'];\n payload?: RecursivePartial<BehavioralEvent['payload']>;\n options?: any;\n}) => void;\n\nexport type SubmitClientEvent = (args: {\n name: ClientEvent['name'];\n payload?: RecursivePartial<ClientEvent['payload']>;\n options: SubmitClientEventOptions;\n}) => void;\n\nexport type SubmitOperationalEvent = (args: {\n name: OperationalEvent['name'];\n payload?: RecursivePartial<OperationalEvent['payload']>;\n options?: any;\n}) => void;\n\nexport type SubmitMQE = (args: {\n name: MediaQualityEvent['name'];\n payload: SubmitMQEPayload;\n options: any;\n}) => void;\n"],"mappings":""}
|
|
@@ -6,6 +6,7 @@ import { MetricEventNames } from '../metrics.types';
|
|
|
6
6
|
*/
|
|
7
7
|
export default class CallDiagnosticLatencies {
|
|
8
8
|
latencyTimestamps: Map<MetricEventNames, number>;
|
|
9
|
+
precomputedLatencies: Map<string, number>;
|
|
9
10
|
/**
|
|
10
11
|
* @constructor
|
|
11
12
|
*/
|
|
@@ -17,11 +18,19 @@ export default class CallDiagnosticLatencies {
|
|
|
17
18
|
/**
|
|
18
19
|
* Store timestamp value
|
|
19
20
|
* @param key - key
|
|
20
|
-
* @param
|
|
21
|
+
* @param value -value
|
|
21
22
|
* @throws
|
|
22
23
|
* @returns
|
|
23
24
|
*/
|
|
24
25
|
saveTimestamp(key: MetricEventNames, value?: number): void;
|
|
26
|
+
/**
|
|
27
|
+
* Store precomputed latency value
|
|
28
|
+
* @param key - key
|
|
29
|
+
* @param value -value
|
|
30
|
+
* @throws
|
|
31
|
+
* @returns
|
|
32
|
+
*/
|
|
33
|
+
saveLatency(key: string, value: number): void;
|
|
25
34
|
/**
|
|
26
35
|
* Store only the first timestamp value for the given key
|
|
27
36
|
* @param key - key
|
|
@@ -18,7 +18,7 @@ export type SubmitMQEOptions = {
|
|
|
18
18
|
networkType?: Event['origin']['networkType'];
|
|
19
19
|
};
|
|
20
20
|
export type InternalEvent = {
|
|
21
|
-
name: 'internal.client.meetinginfo.request' | 'internal.client.meetinginfo.response' | 'internal.reset.join.latencies' | 'internal.client.interstitial-window.launched' | 'internal.client.meeting.click.joinbutton' | 'internal.host.meeting.participant.admitted' | 'internal.client.meeting.interstitial-window.showed' | 'internal.client.
|
|
21
|
+
name: 'internal.client.meetinginfo.request' | 'internal.client.meetinginfo.response' | 'internal.reset.join.latencies' | 'internal.client.interstitial-window.launched' | 'internal.client.meeting.click.joinbutton' | 'internal.host.meeting.participant.admitted' | 'internal.client.meeting.interstitial-window.showed' | 'internal.client.interstitial-window.click.joinbutton';
|
|
22
22
|
payload?: never;
|
|
23
23
|
options?: never;
|
|
24
24
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webex/internal-plugin-metrics",
|
|
3
|
-
"version": "3.0.0-beta.
|
|
3
|
+
"version": "3.0.0-beta.178",
|
|
4
4
|
"description": "",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -28,12 +28,12 @@
|
|
|
28
28
|
"build": "yarn run -T tsc --declaration true --declarationDir ./dist/types"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@webex/common": "3.0.0-beta.
|
|
32
|
-
"@webex/common-timers": "3.0.0-beta.
|
|
33
|
-
"@webex/internal-plugin-device": "3.0.0-beta.
|
|
34
|
-
"@webex/internal-plugin-metrics": "3.0.0-beta.
|
|
35
|
-
"@webex/test-helper-chai": "3.0.0-beta.
|
|
36
|
-
"@webex/test-helper-mock-webex": "3.0.0-beta.
|
|
37
|
-
"@webex/webex-core": "3.0.0-beta.
|
|
31
|
+
"@webex/common": "3.0.0-beta.178",
|
|
32
|
+
"@webex/common-timers": "3.0.0-beta.178",
|
|
33
|
+
"@webex/internal-plugin-device": "3.0.0-beta.178",
|
|
34
|
+
"@webex/internal-plugin-metrics": "3.0.0-beta.178",
|
|
35
|
+
"@webex/test-helper-chai": "3.0.0-beta.178",
|
|
36
|
+
"@webex/test-helper-mock-webex": "3.0.0-beta.178",
|
|
37
|
+
"@webex/webex-core": "3.0.0-beta.178"
|
|
38
38
|
}
|
|
39
39
|
}
|
|
@@ -12,12 +12,14 @@ import {MetricEventNames} from '../metrics.types';
|
|
|
12
12
|
*/
|
|
13
13
|
export default class CallDiagnosticLatencies {
|
|
14
14
|
latencyTimestamps: Map<MetricEventNames, number>;
|
|
15
|
+
precomputedLatencies: Map<string, number>;
|
|
15
16
|
|
|
16
17
|
/**
|
|
17
18
|
* @constructor
|
|
18
19
|
*/
|
|
19
20
|
constructor() {
|
|
20
21
|
this.latencyTimestamps = new Map();
|
|
22
|
+
this.precomputedLatencies = new Map();
|
|
21
23
|
}
|
|
22
24
|
|
|
23
25
|
/**
|
|
@@ -30,7 +32,7 @@ export default class CallDiagnosticLatencies {
|
|
|
30
32
|
/**
|
|
31
33
|
* Store timestamp value
|
|
32
34
|
* @param key - key
|
|
33
|
-
* @param
|
|
35
|
+
* @param value -value
|
|
34
36
|
* @throws
|
|
35
37
|
* @returns
|
|
36
38
|
*/
|
|
@@ -44,6 +46,17 @@ export default class CallDiagnosticLatencies {
|
|
|
44
46
|
}
|
|
45
47
|
}
|
|
46
48
|
|
|
49
|
+
/**
|
|
50
|
+
* Store precomputed latency value
|
|
51
|
+
* @param key - key
|
|
52
|
+
* @param value -value
|
|
53
|
+
* @throws
|
|
54
|
+
* @returns
|
|
55
|
+
*/
|
|
56
|
+
public saveLatency(key: string, value: number) {
|
|
57
|
+
this.precomputedLatencies.set(key, value);
|
|
58
|
+
}
|
|
59
|
+
|
|
47
60
|
/**
|
|
48
61
|
* Store only the first timestamp value for the given key
|
|
49
62
|
* @param key - key
|
|
@@ -107,10 +120,15 @@ export default class CallDiagnosticLatencies {
|
|
|
107
120
|
* @returns - latency
|
|
108
121
|
*/
|
|
109
122
|
public getCallInitJoinReq() {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
123
|
+
if (this.latencyTimestamps.get('internal.client.meeting.click.joinbutton')) {
|
|
124
|
+
return this.getDiffBetweenTimestamps(
|
|
125
|
+
'internal.client.meeting.click.joinbutton',
|
|
126
|
+
'client.locus.join.request'
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// for cross launch and guest flows
|
|
131
|
+
return this.precomputedLatencies.get('internal.call.init.join.req') || undefined;
|
|
114
132
|
}
|
|
115
133
|
|
|
116
134
|
/**
|
|
@@ -189,7 +207,7 @@ export default class CallDiagnosticLatencies {
|
|
|
189
207
|
* @returns - latency
|
|
190
208
|
*/
|
|
191
209
|
public getPageJMT() {
|
|
192
|
-
return this.
|
|
210
|
+
return this.precomputedLatencies.get('internal.client.pageJMT') || undefined;
|
|
193
211
|
}
|
|
194
212
|
|
|
195
213
|
/**
|
|
@@ -197,10 +215,16 @@ export default class CallDiagnosticLatencies {
|
|
|
197
215
|
* @returns - latency
|
|
198
216
|
*/
|
|
199
217
|
public getClickToInterstitial() {
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
218
|
+
// for normal join (where green join button exists before interstitial, i.e reminder, space list etc)
|
|
219
|
+
if (this.latencyTimestamps.get('internal.client.meeting.click.joinbutton')) {
|
|
220
|
+
return this.getDiffBetweenTimestamps(
|
|
221
|
+
'internal.client.meeting.click.joinbutton',
|
|
222
|
+
'internal.client.meeting.interstitial-window.showed'
|
|
223
|
+
);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// for cross launch and guest flows
|
|
227
|
+
return this.precomputedLatencies.get('internal.click.to.interstitial') || undefined;
|
|
204
228
|
}
|
|
205
229
|
|
|
206
230
|
/**
|
package/src/metrics.types.ts
CHANGED
|
@@ -29,7 +29,6 @@ export type InternalEvent = {
|
|
|
29
29
|
| 'internal.client.meeting.click.joinbutton'
|
|
30
30
|
| 'internal.host.meeting.participant.admitted'
|
|
31
31
|
| 'internal.client.meeting.interstitial-window.showed'
|
|
32
|
-
| 'internal.client.pageJMT.received'
|
|
33
32
|
| 'internal.client.interstitial-window.click.joinbutton';
|
|
34
33
|
payload?: never;
|
|
35
34
|
options?: never;
|
|
@@ -64,6 +64,7 @@ describe('plugin-metrics', () => {
|
|
|
64
64
|
|
|
65
65
|
it('appends the correct join times to the request for client.interstitial-window.launched', async () => {
|
|
66
66
|
webex.internal.newMetrics.callDiagnosticLatencies.getDiffBetweenTimestamps = sinon.stub().returns(10);
|
|
67
|
+
webex.internal.newMetrics.callDiagnosticLatencies.getClickToInterstitial = sinon.stub().returns(10);
|
|
67
68
|
await webex.internal.newMetrics.callDiagnosticMetrics.submitToCallDiagnostics(
|
|
68
69
|
//@ts-ignore
|
|
69
70
|
{event: {name: 'client.interstitial-window.launched'}}
|
|
@@ -107,6 +108,8 @@ describe('plugin-metrics', () => {
|
|
|
107
108
|
webex.internal.newMetrics.callDiagnosticLatencies.getJoinRespSentReceived = sinon.stub().returns(20);
|
|
108
109
|
webex.internal.newMetrics.callDiagnosticLatencies.getPageJMT = sinon.stub().returns(30);
|
|
109
110
|
webex.internal.newMetrics.callDiagnosticLatencies.getClientJMT = sinon.stub().returns(5);
|
|
111
|
+
webex.internal.newMetrics.callDiagnosticLatencies.getClickToInterstitial = sinon.stub().returns(10);
|
|
112
|
+
webex.internal.newMetrics.callDiagnosticLatencies.getCallInitJoinReq = sinon.stub().returns(10);
|
|
110
113
|
await webex.internal.newMetrics.callDiagnosticMetrics.submitToCallDiagnostics(
|
|
111
114
|
//@ts-ignore
|
|
112
115
|
{event: {name: 'client.locus.join.response'}}
|
|
@@ -176,6 +179,7 @@ describe('plugin-metrics', () => {
|
|
|
176
179
|
it('appends the correct join times to the request for client.media-engine.ready', async () => {
|
|
177
180
|
webex.internal.newMetrics.callDiagnosticLatencies.getDiffBetweenTimestamps = sinon.stub().returns(10);
|
|
178
181
|
webex.internal.newMetrics.callDiagnosticLatencies.getInterstitialToMediaOKJMT = sinon.stub().returns(10);
|
|
182
|
+
webex.internal.newMetrics.callDiagnosticLatencies.getClickToInterstitial = sinon.stub().returns(10);
|
|
179
183
|
await webex.internal.newMetrics.callDiagnosticMetrics.submitToCallDiagnostics(
|
|
180
184
|
//@ts-ignore
|
|
181
185
|
{event: {name: 'client.media-engine.ready'}}
|
|
@@ -25,6 +25,13 @@ describe("internal-plugin-metrics", () => {
|
|
|
25
25
|
assert.deepEqual(cdl.latencyTimestamps.get('client.alert.displayed'), now.getTime())
|
|
26
26
|
});
|
|
27
27
|
|
|
28
|
+
it('should save latency correctly', () => {
|
|
29
|
+
assert.deepEqual(cdl.precomputedLatencies.size, 0);
|
|
30
|
+
cdl.saveLatency('client.alert.displayed', 10);
|
|
31
|
+
assert.deepEqual(cdl.precomputedLatencies.size, 1);
|
|
32
|
+
assert.deepEqual(cdl.precomputedLatencies.get('client.alert.displayed'), 10)
|
|
33
|
+
});
|
|
34
|
+
|
|
28
35
|
it('should save only first timestamp correctly', () => {
|
|
29
36
|
assert.deepEqual(cdl.latencyTimestamps.size, 0);
|
|
30
37
|
cdl.saveFirstTimestampOnly('client.alert.displayed', 10);
|
|
@@ -49,7 +56,6 @@ describe("internal-plugin-metrics", () => {
|
|
|
49
56
|
cdl.saveTimestamp('client.alert.displayed', 1234);
|
|
50
57
|
assert.deepEqual(cdl.latencyTimestamps.get('client.alert.displayed'), 1234);
|
|
51
58
|
assert.deepEqual(cdl.latencyTimestamps.size, 1);
|
|
52
|
-
|
|
53
59
|
})
|
|
54
60
|
|
|
55
61
|
it('should clear all timestamps correctly', () => {
|
|
@@ -93,6 +99,12 @@ describe("internal-plugin-metrics", () => {
|
|
|
93
99
|
assert.deepEqual(cdl.getCallInitJoinReq(), 10);
|
|
94
100
|
});
|
|
95
101
|
|
|
102
|
+
it('calculates getCallInitJoinReq correctly without click join button event', () => {
|
|
103
|
+
cdl.saveLatency('internal.call.init.join.req', 12);
|
|
104
|
+
cdl.saveTimestamp('client.locus.join.request', 20);
|
|
105
|
+
assert.deepEqual(cdl.getCallInitJoinReq(), 12);
|
|
106
|
+
});
|
|
107
|
+
|
|
96
108
|
it('calculates getJoinReqResp correctly', () => {
|
|
97
109
|
cdl.saveTimestamp('client.locus.join.request', 10);
|
|
98
110
|
cdl.saveTimestamp('client.locus.join.response', 20);
|
|
@@ -136,7 +148,7 @@ describe("internal-plugin-metrics", () => {
|
|
|
136
148
|
});
|
|
137
149
|
|
|
138
150
|
it('calculates getPageJMT correctly', () => {
|
|
139
|
-
cdl.
|
|
151
|
+
cdl.saveLatency('internal.client.pageJMT', 10);
|
|
140
152
|
assert.deepEqual(cdl.getPageJMT(), 10);
|
|
141
153
|
});
|
|
142
154
|
|
|
@@ -146,6 +158,12 @@ describe("internal-plugin-metrics", () => {
|
|
|
146
158
|
assert.deepEqual(cdl.getClickToInterstitial(), 10);
|
|
147
159
|
});
|
|
148
160
|
|
|
161
|
+
it('calculates getClickToInterstitial without join button timestamp', () => {
|
|
162
|
+
cdl.saveLatency('internal.click.to.interstitial', 5);
|
|
163
|
+
cdl.saveTimestamp('internal.client.meeting.interstitial-window.showed', 20);
|
|
164
|
+
assert.deepEqual(cdl.getClickToInterstitial(), 5);
|
|
165
|
+
});
|
|
166
|
+
|
|
149
167
|
it('calculates getInterstitialToJoinOK correctly', () => {
|
|
150
168
|
cdl.saveTimestamp('internal.client.interstitial-window.click.joinbutton', 10);
|
|
151
169
|
cdl.saveTimestamp('client.locus.join.response', 20);
|