@webex/internal-plugin-metrics 3.0.0-beta.173 → 3.0.0-beta.175

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.
@@ -59,6 +59,7 @@ var CallDiagnosticEventsBatcher = _batcher.default.extend({
59
59
  joinTimes.clickToInterstitial = cdl.getClickToInterstitial();
60
60
  joinTimes.interstitialToJoinOK = cdl.getInterstitialToJoinOK();
61
61
  joinTimes.totalJmt = cdl.getTotalJMT();
62
+ joinTimes.clientJmt = cdl.getClientJMT();
62
63
  break;
63
64
  case 'client.ice.end':
64
65
  joinTimes.ICESetupTime = cdl.getICESetupTime();
@@ -72,7 +73,8 @@ var CallDiagnosticEventsBatcher = _batcher.default.extend({
72
73
  case 'client.media-engine.ready':
73
74
  joinTimes.totalMediaJMT = cdl.getTotalMediaJMT();
74
75
  joinTimes.interstitialToMediaOKJMT = cdl.getInterstitialToMediaOKJMT();
75
- joinTimes.callInitMediaEngineReady = cdl.getInterstitialToMediaOKJMT(); // same as interstitialToMediaOKJMT
76
+ joinTimes.callInitMediaEngineReady = cdl.getCallInitMediaEngineReady();
77
+ joinTimes.stayLobbyTime = cdl.getStayLobbyTime();
76
78
  break;
77
79
  case 'client.mediaquality.event':
78
80
  audioSetupDelay.joinRespRxStart = cdl.getAudioJoinRespRxStart();
@@ -1 +1 @@
1
- {"version":3,"names":["CallDiagnosticEventsBatcher","Batcher","extend","namespace","getBuildType","webClientDomain","includes","process","env","NODE_ENV","prepareItem","item","origin","buildType","event","eventData","networkType","eventName","eventPayload","name","joinTimes","audioSetupDelay","videoSetupDelay","cdl","webex","internal","newMetrics","callDiagnosticLatencies","meetingInfoReqResp","getMeetingInfoReqResp","clickToInterstitial","getClickToInterstitial","showInterstitialTime","getShowInterstitialTime","callInitJoinReq","getCallInitJoinReq","joinReqResp","getJoinReqResp","joinReqSentReceived","getJoinRespSentReceived","pageJmt","getPageJMT","interstitialToJoinOK","getInterstitialToJoinOK","totalJmt","getTotalJMT","ICESetupTime","getICESetupTime","audioICESetupTime","getAudioICESetupTime","videoICESetupTime","getVideoICESetupTime","shareICESetupTime","getShareICESetupTime","localSDPGenRemoteSDPRecv","getLocalSDPGenRemoteSDPRecv","totalMediaJMT","getTotalMediaJMT","interstitialToMediaOKJMT","getInterstitialToMediaOKJMT","callInitMediaEngineReady","joinRespRxStart","getAudioJoinRespRxStart","joinRespTxStart","getAudioJoinRespTxStart","getVideoJoinRespRxStart","getVideoJoinRespTxStart","resolve","prepareRequest","queue","forEach","originTime","sent","Date","toISOString","submitHttpRequest","payload","request","method","service","resource","body","metrics"],"sources":["call-diagnostic-metrics-batcher.ts"],"sourcesContent":["/* eslint-disable class-methods-use-this */\n/* eslint-disable valid-jsdoc */\n\nimport {isEmpty, merge} from 'lodash';\nimport Batcher from '../batcher';\nimport {\n ClientEvent,\n MetricEventNames,\n MediaQualityEventAudioSetupDelayPayload,\n MediaQualityEventVideoSetupDelayPayload,\n} from '../metrics.types';\n\nconst CallDiagnosticEventsBatcher = Batcher.extend({\n namespace: 'Metrics',\n\n /**\n * @param webClientDomain\n * @returns\n */\n getBuildType(webClientDomain) {\n if (\n webClientDomain?.includes('localhost') ||\n webClientDomain?.includes('127.0.0.1') ||\n process.env.NODE_ENV !== 'production'\n ) {\n return 'test';\n }\n\n return process.env.NODE_ENV === 'production' ? 'prod' : 'test';\n },\n\n /**\n * Prepare item\n * @param item\n * @returns\n */\n prepareItem(item) {\n const origin = {\n buildType: this.getBuildType(item.event?.eventData?.webClientDomain),\n networkType: 'unknown',\n };\n\n // check event names and append latencies?\n const eventName = item.eventPayload?.event?.name as MetricEventNames;\n const joinTimes: ClientEvent['payload']['joinTimes'] = {};\n const audioSetupDelay: MediaQualityEventAudioSetupDelayPayload = {};\n const videoSetupDelay: MediaQualityEventVideoSetupDelayPayload = {};\n\n const cdl = this.webex.internal.newMetrics.callDiagnosticLatencies;\n\n switch (eventName) {\n case 'client.interstitial-window.launched':\n joinTimes.meetingInfoReqResp = cdl.getMeetingInfoReqResp();\n joinTimes.clickToInterstitial = cdl.getClickToInterstitial();\n break;\n\n case 'client.call.initiated':\n joinTimes.meetingInfoReqResp = cdl.getMeetingInfoReqResp();\n joinTimes.showInterstitialTime = cdl.getShowInterstitialTime();\n break;\n\n case 'client.locus.join.response':\n joinTimes.meetingInfoReqResp = cdl.getMeetingInfoReqResp();\n joinTimes.callInitJoinReq = cdl.getCallInitJoinReq();\n joinTimes.joinReqResp = cdl.getJoinReqResp();\n joinTimes.joinReqSentReceived = cdl.getJoinRespSentReceived();\n joinTimes.pageJmt = cdl.getPageJMT();\n joinTimes.clickToInterstitial = cdl.getClickToInterstitial();\n joinTimes.interstitialToJoinOK = cdl.getInterstitialToJoinOK();\n joinTimes.totalJmt = cdl.getTotalJMT();\n break;\n\n case 'client.ice.end':\n joinTimes.ICESetupTime = cdl.getICESetupTime();\n joinTimes.audioICESetupTime = cdl.getAudioICESetupTime();\n joinTimes.videoICESetupTime = cdl.getVideoICESetupTime();\n joinTimes.shareICESetupTime = cdl.getShareICESetupTime();\n break;\n\n case 'client.media.rx.start':\n joinTimes.localSDPGenRemoteSDPRecv = cdl.getLocalSDPGenRemoteSDPRecv();\n break;\n\n case 'client.media-engine.ready':\n joinTimes.totalMediaJMT = cdl.getTotalMediaJMT();\n joinTimes.interstitialToMediaOKJMT = cdl.getInterstitialToMediaOKJMT();\n joinTimes.callInitMediaEngineReady = cdl.getInterstitialToMediaOKJMT(); // same as interstitialToMediaOKJMT\n break;\n\n case 'client.mediaquality.event':\n audioSetupDelay.joinRespRxStart = cdl.getAudioJoinRespRxStart();\n audioSetupDelay.joinRespTxStart = cdl.getAudioJoinRespTxStart();\n videoSetupDelay.joinRespRxStart = cdl.getVideoJoinRespRxStart();\n videoSetupDelay.joinRespTxStart = cdl.getVideoJoinRespTxStart();\n }\n\n if (!isEmpty(joinTimes)) {\n item.eventPayload.event = merge(item.eventPayload.event, {joinTimes});\n }\n\n if (!isEmpty(audioSetupDelay)) {\n item.eventPayload.event = merge(item.eventPayload.event, {audioSetupDelay});\n }\n\n if (!isEmpty(videoSetupDelay)) {\n item.eventPayload.event = merge(item.eventPayload.event, {videoSetupDelay});\n }\n\n item.eventPayload.origin = Object.assign(origin, item.eventPayload.origin);\n\n return Promise.resolve(item);\n },\n\n /**\n * Prepare request, add time sensitive date etc.\n * @param queue\n * @returns\n */\n prepareRequest(queue) {\n // Add sent timestamp\n queue.forEach((item) => {\n item.eventPayload.originTime = item.eventPayload.originTime || {};\n item.eventPayload.originTime.sent = new Date().toISOString();\n });\n\n return Promise.resolve(queue);\n },\n\n /**\n *\n * @param payload\n * @returns\n */\n submitHttpRequest(payload) {\n return this.webex.request({\n method: 'POST',\n service: 'metrics',\n resource: 'clientmetrics',\n body: {\n metrics: payload,\n },\n });\n },\n});\n\nexport default CallDiagnosticEventsBatcher;\n"],"mappings":"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"}
1
+ {"version":3,"names":["CallDiagnosticEventsBatcher","Batcher","extend","namespace","getBuildType","webClientDomain","includes","process","env","NODE_ENV","prepareItem","item","origin","buildType","event","eventData","networkType","eventName","eventPayload","name","joinTimes","audioSetupDelay","videoSetupDelay","cdl","webex","internal","newMetrics","callDiagnosticLatencies","meetingInfoReqResp","getMeetingInfoReqResp","clickToInterstitial","getClickToInterstitial","showInterstitialTime","getShowInterstitialTime","callInitJoinReq","getCallInitJoinReq","joinReqResp","getJoinReqResp","joinReqSentReceived","getJoinRespSentReceived","pageJmt","getPageJMT","interstitialToJoinOK","getInterstitialToJoinOK","totalJmt","getTotalJMT","clientJmt","getClientJMT","ICESetupTime","getICESetupTime","audioICESetupTime","getAudioICESetupTime","videoICESetupTime","getVideoICESetupTime","shareICESetupTime","getShareICESetupTime","localSDPGenRemoteSDPRecv","getLocalSDPGenRemoteSDPRecv","totalMediaJMT","getTotalMediaJMT","interstitialToMediaOKJMT","getInterstitialToMediaOKJMT","callInitMediaEngineReady","getCallInitMediaEngineReady","stayLobbyTime","getStayLobbyTime","joinRespRxStart","getAudioJoinRespRxStart","joinRespTxStart","getAudioJoinRespTxStart","getVideoJoinRespRxStart","getVideoJoinRespTxStart","resolve","prepareRequest","queue","forEach","originTime","sent","Date","toISOString","submitHttpRequest","payload","request","method","service","resource","body","metrics"],"sources":["call-diagnostic-metrics-batcher.ts"],"sourcesContent":["/* eslint-disable class-methods-use-this */\n/* eslint-disable valid-jsdoc */\n\nimport {isEmpty, merge} from 'lodash';\nimport Batcher from '../batcher';\nimport {\n ClientEvent,\n MetricEventNames,\n MediaQualityEventAudioSetupDelayPayload,\n MediaQualityEventVideoSetupDelayPayload,\n} from '../metrics.types';\n\nconst CallDiagnosticEventsBatcher = Batcher.extend({\n namespace: 'Metrics',\n\n /**\n * @param webClientDomain\n * @returns\n */\n getBuildType(webClientDomain) {\n if (\n webClientDomain?.includes('localhost') ||\n webClientDomain?.includes('127.0.0.1') ||\n process.env.NODE_ENV !== 'production'\n ) {\n return 'test';\n }\n\n return process.env.NODE_ENV === 'production' ? 'prod' : 'test';\n },\n\n /**\n * Prepare item\n * @param item\n * @returns\n */\n prepareItem(item) {\n const origin = {\n buildType: this.getBuildType(item.event?.eventData?.webClientDomain),\n networkType: 'unknown',\n };\n\n // check event names and append latencies?\n const eventName = item.eventPayload?.event?.name as MetricEventNames;\n const joinTimes: ClientEvent['payload']['joinTimes'] = {};\n const audioSetupDelay: MediaQualityEventAudioSetupDelayPayload = {};\n const videoSetupDelay: MediaQualityEventVideoSetupDelayPayload = {};\n\n const cdl = this.webex.internal.newMetrics.callDiagnosticLatencies;\n\n switch (eventName) {\n case 'client.interstitial-window.launched':\n joinTimes.meetingInfoReqResp = cdl.getMeetingInfoReqResp();\n joinTimes.clickToInterstitial = cdl.getClickToInterstitial();\n break;\n\n case 'client.call.initiated':\n joinTimes.meetingInfoReqResp = cdl.getMeetingInfoReqResp();\n joinTimes.showInterstitialTime = cdl.getShowInterstitialTime();\n break;\n\n case 'client.locus.join.response':\n joinTimes.meetingInfoReqResp = cdl.getMeetingInfoReqResp();\n joinTimes.callInitJoinReq = cdl.getCallInitJoinReq();\n joinTimes.joinReqResp = cdl.getJoinReqResp();\n joinTimes.joinReqSentReceived = cdl.getJoinRespSentReceived();\n joinTimes.pageJmt = cdl.getPageJMT();\n joinTimes.clickToInterstitial = cdl.getClickToInterstitial();\n joinTimes.interstitialToJoinOK = cdl.getInterstitialToJoinOK();\n joinTimes.totalJmt = cdl.getTotalJMT();\n joinTimes.clientJmt = cdl.getClientJMT();\n break;\n\n case 'client.ice.end':\n joinTimes.ICESetupTime = cdl.getICESetupTime();\n joinTimes.audioICESetupTime = cdl.getAudioICESetupTime();\n joinTimes.videoICESetupTime = cdl.getVideoICESetupTime();\n joinTimes.shareICESetupTime = cdl.getShareICESetupTime();\n break;\n\n case 'client.media.rx.start':\n joinTimes.localSDPGenRemoteSDPRecv = cdl.getLocalSDPGenRemoteSDPRecv();\n break;\n\n case 'client.media-engine.ready':\n joinTimes.totalMediaJMT = cdl.getTotalMediaJMT();\n joinTimes.interstitialToMediaOKJMT = cdl.getInterstitialToMediaOKJMT();\n joinTimes.callInitMediaEngineReady = cdl.getCallInitMediaEngineReady();\n joinTimes.stayLobbyTime = cdl.getStayLobbyTime();\n break;\n\n case 'client.mediaquality.event':\n audioSetupDelay.joinRespRxStart = cdl.getAudioJoinRespRxStart();\n audioSetupDelay.joinRespTxStart = cdl.getAudioJoinRespTxStart();\n videoSetupDelay.joinRespRxStart = cdl.getVideoJoinRespRxStart();\n videoSetupDelay.joinRespTxStart = cdl.getVideoJoinRespTxStart();\n }\n\n if (!isEmpty(joinTimes)) {\n item.eventPayload.event = merge(item.eventPayload.event, {joinTimes});\n }\n\n if (!isEmpty(audioSetupDelay)) {\n item.eventPayload.event = merge(item.eventPayload.event, {audioSetupDelay});\n }\n\n if (!isEmpty(videoSetupDelay)) {\n item.eventPayload.event = merge(item.eventPayload.event, {videoSetupDelay});\n }\n\n item.eventPayload.origin = Object.assign(origin, item.eventPayload.origin);\n\n return Promise.resolve(item);\n },\n\n /**\n * Prepare request, add time sensitive date etc.\n * @param queue\n * @returns\n */\n prepareRequest(queue) {\n // Add sent timestamp\n queue.forEach((item) => {\n item.eventPayload.originTime = item.eventPayload.originTime || {};\n item.eventPayload.originTime.sent = new Date().toISOString();\n });\n\n return Promise.resolve(queue);\n },\n\n /**\n *\n * @param payload\n * @returns\n */\n submitHttpRequest(payload) {\n return this.webex.request({\n method: 'POST',\n service: 'metrics',\n resource: 'clientmetrics',\n body: {\n metrics: payload,\n },\n });\n },\n});\n\nexport default CallDiagnosticEventsBatcher;\n"],"mappings":"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"}
@@ -48,6 +48,29 @@ var CallDiagnosticLatencies = /*#__PURE__*/function () {
48
48
  key: "saveTimestamp",
49
49
  value: function saveTimestamp(key) {
50
50
  var value = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : new Date().getTime();
51
+ // for some events we're only interested in the first timestamp not last
52
+ // as these events can happen multiple times
53
+ if (key === 'client.media.rx.start' || key === 'client.media.tx.start') {
54
+ this.saveFirstTimestampOnly(key, value);
55
+ } else {
56
+ this.latencyTimestamps.set(key, value);
57
+ }
58
+ }
59
+
60
+ /**
61
+ * Store only the first timestamp value for the given key
62
+ * @param key - key
63
+ * @param value -value
64
+ * @throws
65
+ * @returns
66
+ */
67
+ }, {
68
+ key: "saveFirstTimestampOnly",
69
+ value: function saveFirstTimestampOnly(key) {
70
+ var value = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : new Date().getTime();
71
+ if (this.latencyTimestamps.has(key)) {
72
+ return;
73
+ }
51
74
  this.latencyTimestamps.set(key, value);
52
75
  }
53
76
 
@@ -212,7 +235,17 @@ var CallDiagnosticLatencies = /*#__PURE__*/function () {
212
235
  }, {
213
236
  key: "getInterstitialToJoinOK",
214
237
  value: function getInterstitialToJoinOK() {
215
- return this.getDiffBetweenTimestamps('internal.client.meeting.click.joinbutton', 'client.locus.join.response');
238
+ return this.getDiffBetweenTimestamps('internal.client.interstitial-window.click.joinbutton', 'client.locus.join.response');
239
+ }
240
+
241
+ /**
242
+ * Call Init To MediaEngineReady
243
+ * @returns - latency
244
+ */
245
+ }, {
246
+ key: "getCallInitMediaEngineReady",
247
+ value: function getCallInitMediaEngineReady() {
248
+ return this.getDiffBetweenTimestamps('internal.client.interstitial-window.click.joinbutton', 'client.media-engine.ready');
216
249
  }
217
250
 
218
251
  /**
@@ -220,9 +253,17 @@ var CallDiagnosticLatencies = /*#__PURE__*/function () {
220
253
  * @returns - latency
221
254
  */
222
255
  }, {
223
- key: "getInterstitialToMediaOK",
224
- value: function getInterstitialToMediaOK() {
225
- return this.getDiffBetweenTimestamps('internal.client.meeting.click.joinbutton', 'sdk.media-flow.started');
256
+ key: "getInterstitialToMediaOKJMT",
257
+ value: function getInterstitialToMediaOKJMT() {
258
+ var interstitialJoinClickTimestamp = this.latencyTimestamps.get('internal.client.interstitial-window.click.joinbutton');
259
+
260
+ // get the first timestamp
261
+ var mediaFlowStartedTimestamp = Math.min(this.latencyTimestamps.get('client.media.rx.start'), this.latencyTimestamps.get('client.media.tx.start'));
262
+ var lobbyTime = this.getStayLobbyTime() || 0;
263
+ if (interstitialJoinClickTimestamp && mediaFlowStartedTimestamp) {
264
+ return mediaFlowStartedTimestamp - interstitialJoinClickTimestamp - lobbyTime;
265
+ }
266
+ return undefined;
226
267
  }
227
268
 
228
269
  /**
@@ -282,21 +323,11 @@ var CallDiagnosticLatencies = /*#__PURE__*/function () {
282
323
  var interstitialToJoinOk = this.getInterstitialToJoinOK();
283
324
  var joinConfJMT = this.getJoinConfJMT();
284
325
  if (interstitialToJoinOk && joinConfJMT) {
285
- return interstitialToJoinOk + joinConfJMT;
326
+ return interstitialToJoinOk - joinConfJMT;
286
327
  }
287
328
  return undefined;
288
329
  }
289
330
 
290
- /**
291
- * Interstitial To Media OK JMT
292
- * @returns - latency
293
- */
294
- }, {
295
- key: "getInterstitialToMediaOKJMT",
296
- value: function getInterstitialToMediaOKJMT() {
297
- return this.getDiffBetweenTimestamps('internal.client.interstitial-window.click.joinbutton', 'client.media-engine.ready');
298
- }
299
-
300
331
  /**
301
332
  * Audio setup delay receive
302
333
  */
@@ -1 +1 @@
1
- {"version":3,"names":["CallDiagnosticLatencies","latencyTimestamps","clear","key","value","Date","getTime","set","a","b","start","get","end","undefined","getDiffBetweenTimestamps","clickToInterstitial","getClickToInterstitial","interstitialToJoinOk","getInterstitialToJoinOK","joinReqResp","getJoinReqResp","ICESetupTime","getICESetupTime","joinConfJMT","getJoinConfJMT","stayLobbyTime","getStayLobbyTime"],"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 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.meeting.click.joinbutton',\n 'client.locus.join.response'\n );\n }\n\n /**\n * Interstitial To Media Ok\n * @returns - latency\n */\n public getInterstitialToMediaOK() {\n return this.getDiffBetweenTimestamps(\n 'internal.client.meeting.click.joinbutton',\n 'sdk.media-flow.started'\n );\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 * Interstitial To Media OK JMT\n * @returns - latency\n */\n public getInterstitialToMediaOKJMT() {\n return this.getDiffBetweenTimestamps(\n 'internal.client.interstitial-window.click.joinbutton',\n 'client.media-engine.ready'\n );\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","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":";;;;;;;;;;;;AAAA;AACA;AAIA;AAEA;AACA;AACA;AACA;AACA;AAJA,IAKqBA,uBAAuB;EAG1C;AACF;AACA;EACE,mCAAc;IAAA;IAAA;IACZ,IAAI,CAACC,iBAAiB,GAAG,kBAAS;EACpC;;EAEA;AACF;AACA;EAFE;IAAA;IAAA,OAGA,2BAAyB;MACvB,IAAI,CAACA,iBAAiB,CAACC,KAAK,EAAE;IAChC;;IAEA;AACF;AACA;AACA;AACA;AACA;AACA;EANE;IAAA;IAAA,OAOA,uBAAqBC,GAAqB,EAAwC;MAAA,IAAtCC,KAAa,uEAAG,IAAIC,IAAI,EAAE,CAACC,OAAO,EAAE;MAC9E;MACA;MACA,IAAIH,GAAG,KAAK,uBAAuB,IAAIA,GAAG,KAAK,uBAAuB,EAAE;QACtE,IAAI,CAACI,sBAAsB,CAACJ,GAAG,EAAEC,KAAK,CAAC;MACzC,CAAC,MAAM;QACL,IAAI,CAACH,iBAAiB,CAACO,GAAG,CAACL,GAAG,EAAEC,KAAK,CAAC;MACxC;IACF;;IAEA;AACF;AACA;AACA;AACA;AACA;AACA;EANE;IAAA;IAAA,OAOA,gCAAuBD,GAAqB,EAAwC;MAAA,IAAtCC,KAAa,uEAAG,IAAIC,IAAI,EAAE,CAACC,OAAO,EAAE;MAChF,IAAI,IAAI,CAACL,iBAAiB,CAACQ,GAAG,CAACN,GAAG,CAAC,EAAE;QACnC;MACF;MACA,IAAI,CAACF,iBAAiB,CAACO,GAAG,CAACL,GAAG,EAAEC,KAAK,CAAC;IACxC;;IAEA;AACF;AACA;AACA;AACA;AACA;EALE;IAAA;IAAA,OAMA,kCAAgCM,CAAmB,EAAEC,CAAmB,EAAE;MACxE,IAAMC,KAAK,GAAG,IAAI,CAACX,iBAAiB,CAACY,GAAG,CAACH,CAAC,CAAC;MAC3C,IAAMI,GAAG,GAAG,IAAI,CAACb,iBAAiB,CAACY,GAAG,CAACF,CAAC,CAAC;MACzC,IAAIC,KAAK,IAAIE,GAAG,EAAE;QAChB,OAAOA,GAAG,GAAGF,KAAK;MACpB;MAEA,OAAOG,SAAS;IAClB;;IAEA;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EATE;IAAA;IAAA,OAUA,iCAA+B;MAC7B,OAAO,IAAI,CAACC,wBAAwB,CAClC,qCAAqC,EACrC,sCAAsC,CACvC;IACH;;IAEA;AACF;AACA;AACA;EAHE;IAAA;IAAA,OAIA,mCAAiC;MAC/B,OAAO,IAAI,CAACA,wBAAwB,CAClC,8CAA8C,EAC9C,sDAAsD,CACvD;IACH;;IAEA;AACF;AACA;AACA;EAHE;IAAA;IAAA,OAIA,8BAA4B;MAC1B,OAAO,IAAI,CAACA,wBAAwB,CAClC,0CAA0C,EAC1C,2BAA2B,CAC5B;IACH;;IAEA;AACF;AACA;AACA;EAHE;IAAA;IAAA,OAIA,0BAAwB;MACtB,OAAO,IAAI,CAACA,wBAAwB,CAAC,2BAA2B,EAAE,4BAA4B,CAAC;IACjG;;IAEA;AACF;AACA;AACA;EAHE;IAAA;IAAA,OAIA,mCAAiC;MAC/B;MACA,OAAOD,SAAS;IAClB;;IAEA;AACF;AACA;AACA;EAHE;IAAA;IAAA,OAIA,uCAAqC;MACnC,OAAO,IAAI,CAACC,wBAAwB,CAClC,yCAAyC,EACzC,yCAAyC,CAC1C;IACH;;IAEA;AACF;AACA;AACA;EAHE;IAAA;IAAA,OAIA,2BAAyB;MACvB,OAAO,IAAI,CAACA,wBAAwB,CAAC,kBAAkB,EAAE,gBAAgB,CAAC;IAC5E;;IAEA;AACF;AACA;AACA;EAHE;IAAA;IAAA,OAIA,gCAA8B;MAC5B,OAAO,IAAI,CAACA,wBAAwB,CAAC,kBAAkB,EAAE,gBAAgB,CAAC;IAC5E;;IAEA;AACF;AACA;AACA;EAHE;IAAA;IAAA,OAIA,gCAA8B;MAC5B,OAAO,IAAI,CAACA,wBAAwB,CAAC,kBAAkB,EAAE,gBAAgB,CAAC;IAC5E;;IAEA;AACF;AACA;AACA;EAHE;IAAA;IAAA,OAIA,gCAA8B;MAC5B,OAAO,IAAI,CAACA,wBAAwB,CAAC,kBAAkB,EAAE,gBAAgB,CAAC;IAC5E;;IAEA;AACF;AACA;AACA;EAHE;IAAA;IAAA,OAIA,4BAA0B;MACxB,OAAO,IAAI,CAACA,wBAAwB,CAClC,4BAA4B,EAC5B,4CAA4C,CAC7C;IACH;;IAEA;AACF;AACA;AACA;EAHE;IAAA;IAAA,OAIA,sBAAoB;MAClB,OAAO,IAAI,CAACf,iBAAiB,CAACY,GAAG,CAAC,kCAAkC,CAAC,IAAIE,SAAS;IACpF;;IAEA;AACF;AACA;AACA;EAHE;IAAA;IAAA,OAIA,kCAAgC;MAC9B,OAAO,IAAI,CAACC,wBAAwB,CAClC,0CAA0C,EAC1C,oDAAoD,CACrD;IACH;;IAEA;AACF;AACA;AACA;EAHE;IAAA;IAAA,OAIA,mCAAiC;MAC/B,OAAO,IAAI,CAACA,wBAAwB,CAClC,sDAAsD,EACtD,4BAA4B,CAC7B;IACH;;IAEA;AACF;AACA;AACA;EAHE;IAAA;IAAA,OAIA,uCAAqC;MACnC,OAAO,IAAI,CAACA,wBAAwB,CAClC,sDAAsD,EACtD,2BAA2B,CAC5B;IACH;;IAEA;AACF;AACA;AACA;EAHE;IAAA;IAAA,OAIA,uCAAqC;MACnC,IAAMC,8BAA8B,GAAG,IAAI,CAAChB,iBAAiB,CAACY,GAAG,CAC/D,sDAAsD,CACvD;;MAED;MACA,IAAMK,yBAAyB,GAAGC,IAAI,CAACC,GAAG,CACxC,IAAI,CAACnB,iBAAiB,CAACY,GAAG,CAAC,uBAAuB,CAAC,EACnD,IAAI,CAACZ,iBAAiB,CAACY,GAAG,CAAC,uBAAuB,CAAC,CACpD;MAED,IAAMQ,SAAS,GAAG,IAAI,CAACC,gBAAgB,EAAE,IAAI,CAAC;MAE9C,IAAIL,8BAA8B,IAAIC,yBAAyB,EAAE;QAC/D,OAAOA,yBAAyB,GAAGD,8BAA8B,GAAGI,SAAS;MAC/E;MAEA,OAAON,SAAS;IAClB;;IAEA;AACF;AACA;AACA;EAHE;IAAA;IAAA,OAIA,uBAAqB;MACnB,IAAMQ,mBAAmB,GAAG,IAAI,CAACC,sBAAsB,EAAE;MACzD,IAAMC,oBAAoB,GAAG,IAAI,CAACC,uBAAuB,EAAE;MAE3D,IAAIH,mBAAmB,IAAIE,oBAAoB,EAAE;QAC/C,OAAOF,mBAAmB,GAAGE,oBAAoB;MACnD;MAEA,OAAOV,SAAS;IAClB;;IAEA;AACF;AACA;AACA;EAHE;IAAA;IAAA,OAIA,0BAAwB;MACtB,IAAMY,WAAW,GAAG,IAAI,CAACC,cAAc,EAAE;MACzC,IAAMC,YAAY,GAAG,IAAI,CAACC,eAAe,EAAE;MAE3C,IAAIH,WAAW,IAAIE,YAAY,EAAE;QAC/B,OAAOF,WAAW,GAAGE,YAAY;MACnC;MAEA,OAAOd,SAAS;IAClB;;IAEA;AACF;AACA;AACA;EAHE;IAAA;IAAA,OAIA,4BAA0B;MACxB,IAAMQ,mBAAmB,GAAG,IAAI,CAACC,sBAAsB,EAAE;MACzD,IAAMC,oBAAoB,GAAG,IAAI,CAACC,uBAAuB,EAAE;MAC3D,IAAMK,WAAW,GAAG,IAAI,CAACC,cAAc,EAAE;MACzC,IAAMC,aAAa,GAAG,IAAI,CAACX,gBAAgB,EAAE,IAAI,CAAC;MAElD,IAAIC,mBAAmB,IAAIE,oBAAoB,IAAIM,WAAW,EAAE;QAC9D,OAAOR,mBAAmB,GAAGE,oBAAoB,GAAGM,WAAW,GAAGE,aAAa;MACjF;MAEA,OAAOlB,SAAS;IAClB;;IAEA;AACF;AACA;AACA;EAHE;IAAA;IAAA,OAIA,wBAAsB;MACpB,IAAMU,oBAAoB,GAAG,IAAI,CAACC,uBAAuB,EAAE;MAC3D,IAAMK,WAAW,GAAG,IAAI,CAACC,cAAc,EAAE;MAEzC,IAAIP,oBAAoB,IAAIM,WAAW,EAAE;QACvC,OAAON,oBAAoB,GAAGM,WAAW;MAC3C;MAEA,OAAOhB,SAAS;IAClB;;IAEA;AACF;AACA;EAFE;IAAA;IAAA,OAGA,mCAAiC;MAC/B,OAAO,IAAI,CAACC,wBAAwB,CAAC,4BAA4B,EAAE,uBAAuB,CAAC;IAC7F;;IAEA;AACF;AACA;EAFE;IAAA;IAAA,OAGA,mCAAiC;MAC/B,OAAO,IAAI,CAACA,wBAAwB,CAAC,4BAA4B,EAAE,uBAAuB,CAAC;IAC7F;;IAEA;AACF;AACA;EAFE;IAAA;IAAA,OAGA,mCAAiC;MAC/B,OAAO,IAAI,CAACA,wBAAwB,CAAC,4BAA4B,EAAE,uBAAuB,CAAC;IAC7F;;IAEA;AACF;AACA;EAFE;IAAA;IAAA,OAGA,mCAAiC;MAC/B,OAAO,IAAI,CAACA,wBAAwB,CAAC,4BAA4B,EAAE,uBAAuB,CAAC;IAC7F;EAAC;EAAA;AAAA;AAAA"}
package/dist/metrics.js CHANGED
@@ -161,7 +161,7 @@ var Metrics = _webexCore.WebexPlugin.extend({
161
161
  });
162
162
  });
163
163
  },
164
- version: "3.0.0-beta.173"
164
+ version: "3.0.0-beta.175"
165
165
  });
166
166
  var _default = Metrics;
167
167
  exports.default = _default;
@@ -22,6 +22,14 @@ export default class CallDiagnosticLatencies {
22
22
  * @returns
23
23
  */
24
24
  saveTimestamp(key: MetricEventNames, value?: number): void;
25
+ /**
26
+ * Store only the first timestamp value for the given key
27
+ * @param key - key
28
+ * @param value -value
29
+ * @throws
30
+ * @returns
31
+ */
32
+ saveFirstTimestampOnly(key: MetricEventNames, value?: number): void;
25
33
  /**
26
34
  * Helper to calculate end - start
27
35
  * @param a start
@@ -105,11 +113,16 @@ export default class CallDiagnosticLatencies {
105
113
  * @returns - latency
106
114
  */
107
115
  getInterstitialToJoinOK(): number;
116
+ /**
117
+ * Call Init To MediaEngineReady
118
+ * @returns - latency
119
+ */
120
+ getCallInitMediaEngineReady(): number;
108
121
  /**
109
122
  * Interstitial To Media Ok
110
123
  * @returns - latency
111
124
  */
112
- getInterstitialToMediaOK(): number;
125
+ getInterstitialToMediaOKJMT(): number;
113
126
  /**
114
127
  * Total JMT
115
128
  * @returns - latency
@@ -130,11 +143,6 @@ export default class CallDiagnosticLatencies {
130
143
  * @returns - latency
131
144
  */
132
145
  getClientJMT(): number;
133
- /**
134
- * Interstitial To Media OK JMT
135
- * @returns - latency
136
- */
137
- getInterstitialToMediaOKJMT(): number;
138
146
  /**
139
147
  * Audio setup delay receive
140
148
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webex/internal-plugin-metrics",
3
- "version": "3.0.0-beta.173",
3
+ "version": "3.0.0-beta.175",
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.173",
32
- "@webex/common-timers": "3.0.0-beta.173",
33
- "@webex/internal-plugin-device": "3.0.0-beta.173",
34
- "@webex/internal-plugin-metrics": "3.0.0-beta.173",
35
- "@webex/test-helper-chai": "3.0.0-beta.173",
36
- "@webex/test-helper-mock-webex": "3.0.0-beta.173",
37
- "@webex/webex-core": "3.0.0-beta.173"
31
+ "@webex/common": "3.0.0-beta.175",
32
+ "@webex/common-timers": "3.0.0-beta.175",
33
+ "@webex/internal-plugin-device": "3.0.0-beta.175",
34
+ "@webex/internal-plugin-metrics": "3.0.0-beta.175",
35
+ "@webex/test-helper-chai": "3.0.0-beta.175",
36
+ "@webex/test-helper-mock-webex": "3.0.0-beta.175",
37
+ "@webex/webex-core": "3.0.0-beta.175"
38
38
  }
39
39
  }
@@ -68,6 +68,7 @@ const CallDiagnosticEventsBatcher = Batcher.extend({
68
68
  joinTimes.clickToInterstitial = cdl.getClickToInterstitial();
69
69
  joinTimes.interstitialToJoinOK = cdl.getInterstitialToJoinOK();
70
70
  joinTimes.totalJmt = cdl.getTotalJMT();
71
+ joinTimes.clientJmt = cdl.getClientJMT();
71
72
  break;
72
73
 
73
74
  case 'client.ice.end':
@@ -84,7 +85,8 @@ const CallDiagnosticEventsBatcher = Batcher.extend({
84
85
  case 'client.media-engine.ready':
85
86
  joinTimes.totalMediaJMT = cdl.getTotalMediaJMT();
86
87
  joinTimes.interstitialToMediaOKJMT = cdl.getInterstitialToMediaOKJMT();
87
- joinTimes.callInitMediaEngineReady = cdl.getInterstitialToMediaOKJMT(); // same as interstitialToMediaOKJMT
88
+ joinTimes.callInitMediaEngineReady = cdl.getCallInitMediaEngineReady();
89
+ joinTimes.stayLobbyTime = cdl.getStayLobbyTime();
88
90
  break;
89
91
 
90
92
  case 'client.mediaquality.event':
@@ -35,6 +35,26 @@ export default class CallDiagnosticLatencies {
35
35
  * @returns
36
36
  */
37
37
  public saveTimestamp(key: MetricEventNames, value: number = new Date().getTime()) {
38
+ // for some events we're only interested in the first timestamp not last
39
+ // as these events can happen multiple times
40
+ if (key === 'client.media.rx.start' || key === 'client.media.tx.start') {
41
+ this.saveFirstTimestampOnly(key, value);
42
+ } else {
43
+ this.latencyTimestamps.set(key, value);
44
+ }
45
+ }
46
+
47
+ /**
48
+ * Store only the first timestamp value for the given key
49
+ * @param key - key
50
+ * @param value -value
51
+ * @throws
52
+ * @returns
53
+ */
54
+ saveFirstTimestampOnly(key: MetricEventNames, value: number = new Date().getTime()) {
55
+ if (this.latencyTimestamps.has(key)) {
56
+ return;
57
+ }
38
58
  this.latencyTimestamps.set(key, value);
39
59
  }
40
60
 
@@ -189,20 +209,44 @@ export default class CallDiagnosticLatencies {
189
209
  */
190
210
  public getInterstitialToJoinOK() {
191
211
  return this.getDiffBetweenTimestamps(
192
- 'internal.client.meeting.click.joinbutton',
212
+ 'internal.client.interstitial-window.click.joinbutton',
193
213
  'client.locus.join.response'
194
214
  );
195
215
  }
196
216
 
197
217
  /**
198
- * Interstitial To Media Ok
218
+ * Call Init To MediaEngineReady
199
219
  * @returns - latency
200
220
  */
201
- public getInterstitialToMediaOK() {
221
+ public getCallInitMediaEngineReady() {
202
222
  return this.getDiffBetweenTimestamps(
203
- 'internal.client.meeting.click.joinbutton',
204
- 'sdk.media-flow.started'
223
+ 'internal.client.interstitial-window.click.joinbutton',
224
+ 'client.media-engine.ready'
225
+ );
226
+ }
227
+
228
+ /**
229
+ * Interstitial To Media Ok
230
+ * @returns - latency
231
+ */
232
+ public getInterstitialToMediaOKJMT() {
233
+ const interstitialJoinClickTimestamp = this.latencyTimestamps.get(
234
+ 'internal.client.interstitial-window.click.joinbutton'
235
+ );
236
+
237
+ // get the first timestamp
238
+ const mediaFlowStartedTimestamp = Math.min(
239
+ this.latencyTimestamps.get('client.media.rx.start'),
240
+ this.latencyTimestamps.get('client.media.tx.start')
205
241
  );
242
+
243
+ const lobbyTime = this.getStayLobbyTime() || 0;
244
+
245
+ if (interstitialJoinClickTimestamp && mediaFlowStartedTimestamp) {
246
+ return mediaFlowStartedTimestamp - interstitialJoinClickTimestamp - lobbyTime;
247
+ }
248
+
249
+ return undefined;
206
250
  }
207
251
 
208
252
  /**
@@ -261,23 +305,12 @@ export default class CallDiagnosticLatencies {
261
305
  const joinConfJMT = this.getJoinConfJMT();
262
306
 
263
307
  if (interstitialToJoinOk && joinConfJMT) {
264
- return interstitialToJoinOk + joinConfJMT;
308
+ return interstitialToJoinOk - joinConfJMT;
265
309
  }
266
310
 
267
311
  return undefined;
268
312
  }
269
313
 
270
- /**
271
- * Interstitial To Media OK JMT
272
- * @returns - latency
273
- */
274
- public getInterstitialToMediaOKJMT() {
275
- return this.getDiffBetweenTimestamps(
276
- 'internal.client.interstitial-window.click.joinbutton',
277
- 'client.media-engine.ready'
278
- );
279
- }
280
-
281
314
  /**
282
315
  * Audio setup delay receive
283
316
  */
@@ -106,6 +106,7 @@ describe('plugin-metrics', () => {
106
106
  webex.internal.newMetrics.callDiagnosticLatencies.getDiffBetweenTimestamps = sinon.stub().returns(10);
107
107
  webex.internal.newMetrics.callDiagnosticLatencies.getJoinRespSentReceived = sinon.stub().returns(20);
108
108
  webex.internal.newMetrics.callDiagnosticLatencies.getPageJMT = sinon.stub().returns(30);
109
+ webex.internal.newMetrics.callDiagnosticLatencies.getClientJMT = sinon.stub().returns(5);
109
110
  await webex.internal.newMetrics.callDiagnosticMetrics.submitToCallDiagnostics(
110
111
  //@ts-ignore
111
112
  {event: {name: 'client.locus.join.response'}}
@@ -125,6 +126,7 @@ describe('plugin-metrics', () => {
125
126
  meetingInfoReqResp: 10,
126
127
  pageJmt: 30,
127
128
  totalJmt: 20,
129
+ clientJmt: 5,
128
130
  },
129
131
  });
130
132
  assert.lengthOf(webex.internal.newMetrics.callDiagnosticMetrics.callDiagnosticEventsBatcher.queue, 0);
@@ -172,7 +174,8 @@ describe('plugin-metrics', () => {
172
174
  });
173
175
 
174
176
  it('appends the correct join times to the request for client.media-engine.ready', async () => {
175
- webex.internal.newMetrics.callDiagnosticLatencies.getDiffBetweenTimestamps = sinon.stub().returns(10)
177
+ webex.internal.newMetrics.callDiagnosticLatencies.getDiffBetweenTimestamps = sinon.stub().returns(10);
178
+ webex.internal.newMetrics.callDiagnosticLatencies.getInterstitialToMediaOKJMT = sinon.stub().returns(10);
176
179
  await webex.internal.newMetrics.callDiagnosticMetrics.submitToCallDiagnostics(
177
180
  //@ts-ignore
178
181
  {event: {name: 'client.media-engine.ready'}}
@@ -187,6 +190,7 @@ describe('plugin-metrics', () => {
187
190
  totalMediaJMT: 30,
188
191
  interstitialToMediaOKJMT: 10,
189
192
  callInitMediaEngineReady: 10,
193
+ stayLobbyTime: 10,
190
194
  },
191
195
  });
192
196
  assert.lengthOf(webex.internal.newMetrics.callDiagnosticMetrics.callDiagnosticEventsBatcher.queue, 0);
@@ -25,6 +25,23 @@ describe("internal-plugin-metrics", () => {
25
25
  assert.deepEqual(cdl.latencyTimestamps.get('client.alert.displayed'), now.getTime())
26
26
  });
27
27
 
28
+ it('should save only first timestamp correctly', () => {
29
+ assert.deepEqual(cdl.latencyTimestamps.size, 0);
30
+ cdl.saveFirstTimestampOnly('client.alert.displayed', 10);
31
+ cdl.saveFirstTimestampOnly('client.alert.displayed', 20);
32
+ assert.deepEqual(cdl.latencyTimestamps.get('client.alert.displayed'), 10);
33
+ });
34
+
35
+ it('should save only first timestamp correctly for client.media.tx.start and client.media.rx.start', () => {
36
+ assert.deepEqual(cdl.latencyTimestamps.size, 0);
37
+ cdl.saveFirstTimestampOnly('client.media.tx.start', 10);
38
+ cdl.saveFirstTimestampOnly('client.media.tx.start', 20);
39
+ cdl.saveFirstTimestampOnly('client.media.rx.start', 12);
40
+ cdl.saveFirstTimestampOnly('client.media.rx.start', 22);
41
+ assert.deepEqual(cdl.latencyTimestamps.get('client.media.tx.start'), 10);
42
+ assert.deepEqual(cdl.latencyTimestamps.get('client.media.rx.start'), 12);
43
+ });
44
+
28
45
  it('should update existing property and now add new keys', () => {
29
46
  assert.deepEqual(cdl.latencyTimestamps.size, 0);
30
47
  cdl.saveTimestamp('client.alert.displayed');
@@ -130,22 +147,23 @@ describe("internal-plugin-metrics", () => {
130
147
  });
131
148
 
132
149
  it('calculates getInterstitialToJoinOK correctly', () => {
133
- cdl.saveTimestamp('internal.client.meeting.click.joinbutton', 10);
150
+ cdl.saveTimestamp('internal.client.interstitial-window.click.joinbutton', 10);
134
151
  cdl.saveTimestamp('client.locus.join.response', 20);
135
152
  assert.deepEqual(cdl.getInterstitialToJoinOK(), 10);
136
153
  });
137
154
 
138
- it('calculates getInterstitialToMediaOK correctly', () => {
139
- cdl.saveTimestamp('internal.client.meeting.click.joinbutton', 10);
140
- cdl.saveTimestamp('sdk.media-flow.started', 20);
141
- assert.deepEqual(cdl.getInterstitialToMediaOK(), 10);
155
+ it('calculates getCallInitMediaEngineReady correctly', () => {
156
+ cdl.saveTimestamp('internal.client.interstitial-window.click.joinbutton', 10);
157
+ cdl.saveTimestamp('client.media-engine.ready', 20);
158
+ assert.deepEqual(cdl.getCallInitMediaEngineReady(), 10);
142
159
  });
143
160
 
144
161
  it('calculates getTotalJMT correctly', () => {
162
+ cdl.saveTimestamp('internal.client.interstitial-window.click.joinbutton', 5);
145
163
  cdl.saveTimestamp('internal.client.meeting.click.joinbutton', 10);
146
164
  cdl.saveTimestamp('internal.client.meeting.interstitial-window.showed', 20);
147
165
  cdl.saveTimestamp('client.locus.join.response', 40);
148
- assert.deepEqual(cdl.getTotalJMT(), 40);
166
+ assert.deepEqual(cdl.getTotalJMT(), 45);
149
167
  });
150
168
 
151
169
  it('calculates getJoinConfJMT correctly', () => {
@@ -157,13 +175,12 @@ describe("internal-plugin-metrics", () => {
157
175
  });
158
176
 
159
177
  it('calculates getClientJMT correctly', () => {
160
- cdl.saveTimestamp('internal.client.meeting.click.joinbutton', 5);
161
- cdl.saveTimestamp('internal.client.meeting.interstitial-window.showed', 7)
162
- cdl.saveTimestamp('client.locus.join.request', 10);
163
- cdl.saveTimestamp('client.locus.join.response', 20);
164
- cdl.saveTimestamp('client.ice.start', 30);
165
- cdl.saveTimestamp('client.ice.end', 40);
166
- assert.deepEqual(cdl.getClientJMT(), 35);
178
+ cdl.saveTimestamp('internal.client.interstitial-window.click.joinbutton', 2);
179
+ cdl.saveTimestamp('client.locus.join.request', 6);
180
+ cdl.saveTimestamp('client.locus.join.response', 8);
181
+ cdl.saveTimestamp('client.ice.start', 10);
182
+ cdl.saveTimestamp('client.ice.end', 11);
183
+ assert.deepEqual(cdl.getClientJMT(), 3);
167
184
  });
168
185
 
169
186
  it('calculates getAudioJoinRespRxStart correctly', () => {
@@ -191,9 +208,13 @@ describe("internal-plugin-metrics", () => {
191
208
  });
192
209
 
193
210
  it('calculates getInterstitialToMediaOKJMT correctly', () => {
194
- cdl.saveTimestamp('internal.client.interstitial-window.click.joinbutton', 5);
195
- cdl.saveTimestamp('client.media-engine.ready', 7);
196
- assert.deepEqual(cdl.getInterstitialToMediaOKJMT(), 2);
211
+ cdl.saveTimestamp('internal.client.interstitial-window.click.joinbutton', 4);
212
+ cdl.saveTimestamp('client.locus.join.response', 10);
213
+ cdl.saveTimestamp('internal.host.meeting.participant.admitted', 12);
214
+ cdl.saveTimestamp('client.media.rx.start', 14);
215
+ cdl.saveTimestamp('client.media.tx.start', 15);
216
+ cdl.saveTimestamp('client.media.rx.start', 16);
217
+ assert.deepEqual(cdl.getInterstitialToMediaOKJMT(), 8);
197
218
  });
198
219
  })
199
220
  })