@webex/internal-plugin-metrics 3.0.0-beta.179 → 3.0.0-beta.180
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 +67 -12
- package/dist/call-diagnostic/call-diagnostic-metrics-latencies.js.map +1 -1
- package/dist/metrics.js +1 -1
- package/dist/new-metrics.js +19 -5
- package/dist/new-metrics.js.map +1 -1
- package/dist/types/call-diagnostic/call-diagnostic-metrics-latencies.d.ts +21 -3
- package/package.json +8 -8
- package/src/call-diagnostic/call-diagnostic-metrics-latencies.ts +48 -5
- package/src/new-metrics.ts +9 -6
- package/test/unit/spec/call-diagnostic/call-diagnostic-metrics-latencies.ts +310 -74
- package/test/unit/spec/new-metrics.ts +9 -6
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
+
var _Reflect$construct = require("@babel/runtime-corejs2/core-js/reflect/construct");
|
|
3
4
|
var _Object$defineProperty = require("@babel/runtime-corejs2/core-js/object/define-property");
|
|
4
5
|
var _interopRequireDefault = require("@babel/runtime-corejs2/helpers/interopRequireDefault");
|
|
5
6
|
_Object$defineProperty(exports, "__esModule", {
|
|
@@ -9,25 +10,41 @@ exports.default = void 0;
|
|
|
9
10
|
var _map = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/map"));
|
|
10
11
|
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/classCallCheck"));
|
|
11
12
|
var _createClass2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/createClass"));
|
|
13
|
+
var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/assertThisInitialized"));
|
|
14
|
+
var _inherits2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/inherits"));
|
|
15
|
+
var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/possibleConstructorReturn"));
|
|
16
|
+
var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/getPrototypeOf"));
|
|
12
17
|
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/defineProperty"));
|
|
13
|
-
|
|
14
|
-
|
|
18
|
+
var _webexCore = require("@webex/webex-core");
|
|
19
|
+
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = _Reflect$construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }
|
|
20
|
+
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !_Reflect$construct) return false; if (_Reflect$construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(_Reflect$construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
|
|
15
21
|
// we only care about client event and feature event for now
|
|
16
22
|
/**
|
|
17
23
|
* @description Helper class to store latencies timestamp and to calculate various latencies for CA.
|
|
18
24
|
* @exports
|
|
19
25
|
* @class CallDiagnosticLatencies
|
|
20
26
|
*/
|
|
21
|
-
var CallDiagnosticLatencies = /*#__PURE__*/function () {
|
|
27
|
+
var CallDiagnosticLatencies = /*#__PURE__*/function (_WebexPlugin) {
|
|
28
|
+
(0, _inherits2.default)(CallDiagnosticLatencies, _WebexPlugin);
|
|
29
|
+
var _super = _createSuper(CallDiagnosticLatencies);
|
|
30
|
+
// meetingId that the current latencies are for
|
|
31
|
+
|
|
22
32
|
/**
|
|
23
33
|
* @constructor
|
|
24
34
|
*/
|
|
25
35
|
function CallDiagnosticLatencies() {
|
|
36
|
+
var _this;
|
|
26
37
|
(0, _classCallCheck2.default)(this, CallDiagnosticLatencies);
|
|
27
|
-
(
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
38
|
+
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
39
|
+
args[_key] = arguments[_key];
|
|
40
|
+
}
|
|
41
|
+
_this = _super.call.apply(_super, [this].concat(args));
|
|
42
|
+
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "latencyTimestamps", void 0);
|
|
43
|
+
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "precomputedLatencies", void 0);
|
|
44
|
+
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "meetingId", void 0);
|
|
45
|
+
_this.latencyTimestamps = new _map.default();
|
|
46
|
+
_this.precomputedLatencies = new _map.default();
|
|
47
|
+
return _this;
|
|
31
48
|
}
|
|
32
49
|
|
|
33
50
|
/**
|
|
@@ -39,6 +56,30 @@ var CallDiagnosticLatencies = /*#__PURE__*/function () {
|
|
|
39
56
|
this.latencyTimestamps.clear();
|
|
40
57
|
}
|
|
41
58
|
|
|
59
|
+
/**
|
|
60
|
+
* Associate current latencies with a meeting id
|
|
61
|
+
* @param meetingId
|
|
62
|
+
*/
|
|
63
|
+
}, {
|
|
64
|
+
key: "setMeetingId",
|
|
65
|
+
value: function setMeetingId(meetingId) {
|
|
66
|
+
this.meetingId = meetingId;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Returns the meeting object associated with current latencies
|
|
71
|
+
* @returns meeting object
|
|
72
|
+
*/
|
|
73
|
+
}, {
|
|
74
|
+
key: "getMeeting",
|
|
75
|
+
value: function getMeeting() {
|
|
76
|
+
if (this.meetingId) {
|
|
77
|
+
// @ts-ignore
|
|
78
|
+
return this.webex.meetings.meetingCollection.get(this.meetingId);
|
|
79
|
+
}
|
|
80
|
+
return undefined;
|
|
81
|
+
}
|
|
82
|
+
|
|
42
83
|
/**
|
|
43
84
|
* Store timestamp value
|
|
44
85
|
* @param key - key
|
|
@@ -48,8 +89,17 @@ var CallDiagnosticLatencies = /*#__PURE__*/function () {
|
|
|
48
89
|
*/
|
|
49
90
|
}, {
|
|
50
91
|
key: "saveTimestamp",
|
|
51
|
-
value: function saveTimestamp(
|
|
52
|
-
var
|
|
92
|
+
value: function saveTimestamp(_ref) {
|
|
93
|
+
var key = _ref.key,
|
|
94
|
+
_ref$value = _ref.value,
|
|
95
|
+
value = _ref$value === void 0 ? new Date().getTime() : _ref$value,
|
|
96
|
+
_ref$options = _ref.options,
|
|
97
|
+
options = _ref$options === void 0 ? {} : _ref$options;
|
|
98
|
+
// save the meetingId so we can use the meeting object in latency calculations if needed
|
|
99
|
+
var meetingId = options.meetingId;
|
|
100
|
+
if (meetingId) {
|
|
101
|
+
this.setMeetingId(meetingId);
|
|
102
|
+
}
|
|
53
103
|
// for some events we're only interested in the first timestamp not last
|
|
54
104
|
// as these events can happen multiple times
|
|
55
105
|
if (key === 'client.media.rx.start' || key === 'client.media.tx.start') {
|
|
@@ -332,9 +382,14 @@ var CallDiagnosticLatencies = /*#__PURE__*/function () {
|
|
|
332
382
|
var clickToInterstitial = this.getClickToInterstitial();
|
|
333
383
|
var interstitialToJoinOk = this.getInterstitialToJoinOK();
|
|
334
384
|
var joinConfJMT = this.getJoinConfJMT();
|
|
335
|
-
var
|
|
385
|
+
var lobbyTime = this.getStayLobbyTime();
|
|
336
386
|
if (clickToInterstitial && interstitialToJoinOk && joinConfJMT) {
|
|
337
|
-
|
|
387
|
+
var _this$getMeeting;
|
|
388
|
+
var totalMediaJMT = clickToInterstitial + interstitialToJoinOk + joinConfJMT;
|
|
389
|
+
if ((_this$getMeeting = this.getMeeting()) !== null && _this$getMeeting !== void 0 && _this$getMeeting.allowMediaInLobby) {
|
|
390
|
+
return totalMediaJMT;
|
|
391
|
+
}
|
|
392
|
+
return totalMediaJMT - lobbyTime;
|
|
338
393
|
}
|
|
339
394
|
return undefined;
|
|
340
395
|
}
|
|
@@ -391,6 +446,6 @@ var CallDiagnosticLatencies = /*#__PURE__*/function () {
|
|
|
391
446
|
}
|
|
392
447
|
}]);
|
|
393
448
|
return CallDiagnosticLatencies;
|
|
394
|
-
}();
|
|
449
|
+
}(_webexCore.WebexPlugin);
|
|
395
450
|
exports.default = CallDiagnosticLatencies;
|
|
396
451
|
//# sourceMappingURL=call-diagnostic-metrics-latencies.js.map
|
|
@@ -1 +1 @@
|
|
|
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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"}
|
|
1
|
+
{"version":3,"names":["CallDiagnosticLatencies","args","latencyTimestamps","precomputedLatencies","clear","meetingId","webex","meetings","meetingCollection","get","undefined","key","value","Date","getTime","options","setMeetingId","saveFirstTimestampOnly","set","has","a","b","start","end","getDiffBetweenTimestamps","interstitialJoinClickTimestamp","mediaFlowStartedTimestamp","Math","min","lobbyTime","getStayLobbyTime","clickToInterstitial","getClickToInterstitial","interstitialToJoinOk","getInterstitialToJoinOK","joinReqResp","getJoinReqResp","ICESetupTime","getICESetupTime","joinConfJMT","getJoinConfJMT","totalMediaJMT","getMeeting","allowMediaInLobby","WebexPlugin"],"sources":["call-diagnostic-metrics-latencies.ts"],"sourcesContent":["/* eslint-disable class-methods-use-this */\n/* eslint-disable valid-jsdoc */\nimport {WebexPlugin} from '@webex/webex-core';\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 extends WebexPlugin {\n latencyTimestamps: Map<MetricEventNames, number>;\n precomputedLatencies: Map<string, number>;\n // meetingId that the current latencies are for\n private meetingId?: string;\n\n /**\n * @constructor\n */\n constructor(...args) {\n super(...args);\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 * Associate current latencies with a meeting id\n * @param meetingId\n */\n private setMeetingId(meetingId: string) {\n this.meetingId = meetingId;\n }\n\n /**\n * Returns the meeting object associated with current latencies\n * @returns meeting object\n */\n private getMeeting() {\n if (this.meetingId) {\n // @ts-ignore\n return this.webex.meetings.meetingCollection.get(this.meetingId);\n }\n\n return undefined;\n }\n\n /**\n * Store timestamp value\n * @param key - key\n * @param value -value\n * @throws\n * @returns\n */\n public saveTimestamp({\n key,\n value = new Date().getTime(),\n options = {},\n }: {\n key: MetricEventNames;\n value?: number;\n options?: {meetingId?: string};\n }) {\n // save the meetingId so we can use the meeting object in latency calculations if needed\n const {meetingId} = options;\n if (meetingId) {\n this.setMeetingId(meetingId);\n }\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 lobbyTime = this.getStayLobbyTime();\n\n if (clickToInterstitial && interstitialToJoinOk && joinConfJMT) {\n const totalMediaJMT = clickToInterstitial + interstitialToJoinOk + joinConfJMT;\n if (this.getMeeting()?.allowMediaInLobby) {\n return totalMediaJMT;\n }\n\n return totalMediaJMT - lobbyTime;\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
package/dist/new-metrics.js
CHANGED
|
@@ -48,7 +48,6 @@ var Metrics = /*#__PURE__*/function (_WebexPlugin) {
|
|
|
48
48
|
_this = _super.call.apply(_super, [this].concat(args));
|
|
49
49
|
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "callDiagnosticLatencies", void 0);
|
|
50
50
|
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "callDiagnosticMetrics", void 0);
|
|
51
|
-
_this.callDiagnosticLatencies = new _callDiagnosticMetricsLatencies.default();
|
|
52
51
|
_this.onReady();
|
|
53
52
|
return _this;
|
|
54
53
|
}
|
|
@@ -66,6 +65,10 @@ var Metrics = /*#__PURE__*/function (_WebexPlugin) {
|
|
|
66
65
|
_this2.callDiagnosticMetrics = new _callDiagnosticMetrics.default({}, {
|
|
67
66
|
parent: _this2.webex
|
|
68
67
|
});
|
|
68
|
+
// @ts-ignore
|
|
69
|
+
_this2.callDiagnosticLatencies = new _callDiagnosticMetricsLatencies.default({}, {
|
|
70
|
+
parent: _this2.webex
|
|
71
|
+
});
|
|
69
72
|
});
|
|
70
73
|
}
|
|
71
74
|
|
|
@@ -82,7 +85,9 @@ var Metrics = /*#__PURE__*/function (_WebexPlugin) {
|
|
|
82
85
|
if (name === 'internal.reset.join.latencies') {
|
|
83
86
|
this.callDiagnosticLatencies.clearTimestamps();
|
|
84
87
|
} else {
|
|
85
|
-
this.callDiagnosticLatencies.saveTimestamp(
|
|
88
|
+
this.callDiagnosticLatencies.saveTimestamp({
|
|
89
|
+
key: name
|
|
90
|
+
});
|
|
86
91
|
}
|
|
87
92
|
}
|
|
88
93
|
|
|
@@ -96,7 +101,9 @@ var Metrics = /*#__PURE__*/function (_WebexPlugin) {
|
|
|
96
101
|
var name = _ref2.name,
|
|
97
102
|
payload = _ref2.payload,
|
|
98
103
|
options = _ref2.options;
|
|
99
|
-
this.callDiagnosticLatencies.saveTimestamp(
|
|
104
|
+
this.callDiagnosticLatencies.saveTimestamp({
|
|
105
|
+
key: name
|
|
106
|
+
});
|
|
100
107
|
throw new Error('Not implemented.');
|
|
101
108
|
}
|
|
102
109
|
|
|
@@ -123,7 +130,9 @@ var Metrics = /*#__PURE__*/function (_WebexPlugin) {
|
|
|
123
130
|
var name = _ref4.name,
|
|
124
131
|
payload = _ref4.payload,
|
|
125
132
|
options = _ref4.options;
|
|
126
|
-
this.callDiagnosticLatencies.saveTimestamp(
|
|
133
|
+
this.callDiagnosticLatencies.saveTimestamp({
|
|
134
|
+
key: name
|
|
135
|
+
});
|
|
127
136
|
this.callDiagnosticMetrics.submitMQE({
|
|
128
137
|
name: name,
|
|
129
138
|
payload: payload,
|
|
@@ -155,7 +164,12 @@ var Metrics = /*#__PURE__*/function (_WebexPlugin) {
|
|
|
155
164
|
var name = _ref6.name,
|
|
156
165
|
payload = _ref6.payload,
|
|
157
166
|
options = _ref6.options;
|
|
158
|
-
this.callDiagnosticLatencies.saveTimestamp(
|
|
167
|
+
this.callDiagnosticLatencies.saveTimestamp({
|
|
168
|
+
key: name,
|
|
169
|
+
options: {
|
|
170
|
+
meetingId: options === null || options === void 0 ? void 0 : options.meetingId
|
|
171
|
+
}
|
|
172
|
+
});
|
|
159
173
|
this.callDiagnosticMetrics.submitClientEvent({
|
|
160
174
|
name: name,
|
|
161
175
|
payload: payload,
|
package/dist/new-metrics.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["Metrics","args","
|
|
1
|
+
{"version":3,"names":["Metrics","args","onReady","webex","once","callDiagnosticMetrics","CallDiagnosticMetrics","parent","callDiagnosticLatencies","CallDiagnosticLatencies","name","payload","options","clearTimestamps","saveTimestamp","key","Error","submitMQE","meetingId","submitClientEvent","WebexPlugin"],"sources":["new-metrics.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-unused-vars */\n/* eslint-disable class-methods-use-this */\n/* eslint-disable valid-jsdoc */\n\n// @ts-ignore\nimport {WebexPlugin} from '@webex/webex-core';\n\nimport CallDiagnosticMetrics from './call-diagnostic/call-diagnostic-metrics';\nimport {\n RecursivePartial,\n ClientEvent,\n FeatureEvent,\n BehavioralEvent,\n OperationalEvent,\n MediaQualityEvent,\n InternalEvent,\n SubmitClientEventOptions,\n} from './metrics.types';\nimport CallDiagnosticLatencies from './call-diagnostic/call-diagnostic-metrics-latencies';\n\n/**\n * Metrics plugin to centralize all types of metrics.\n * @class\n */\nclass Metrics extends WebexPlugin {\n // eslint-disable-next-line no-use-before-define\n static instance: Metrics;\n\n // Call Diagnostic latencies\n callDiagnosticLatencies: CallDiagnosticLatencies;\n // Helper classes to handle the different types of metrics\n callDiagnosticMetrics: CallDiagnosticMetrics;\n\n /**\n * Constructor\n * @param args\n * @constructor\n * @private\n * @returns\n */\n constructor(...args) {\n super(...args);\n\n this.onReady();\n }\n\n /**\n * On Ready\n */\n private onReady() {\n // @ts-ignore\n this.webex.once('ready', () => {\n // @ts-ignore\n this.callDiagnosticMetrics = new CallDiagnosticMetrics({}, {parent: this.webex});\n // @ts-ignore\n this.callDiagnosticLatencies = new CallDiagnosticLatencies({}, {parent: this.webex});\n });\n }\n\n /**\n * Used for internal purposes only\n * @param args\n */\n submitInternalEvent({\n name,\n payload,\n options,\n }: {\n name: InternalEvent['name'];\n payload?: RecursivePartial<InternalEvent['payload']>;\n options?: any;\n }) {\n if (name === 'internal.reset.join.latencies') {\n this.callDiagnosticLatencies.clearTimestamps();\n } else {\n this.callDiagnosticLatencies.saveTimestamp({key: name});\n }\n }\n\n /**\n * Behavioral event\n * @param args\n */\n submitBehavioralEvent({\n name,\n payload,\n options,\n }: {\n name: BehavioralEvent['name'];\n payload?: RecursivePartial<BehavioralEvent['payload']>;\n options?: any;\n }) {\n this.callDiagnosticLatencies.saveTimestamp({key: name});\n throw new Error('Not implemented.');\n }\n\n /**\n * Operational event\n * @param args\n */\n submitOperationalEvent({\n name,\n payload,\n options,\n }: {\n name: OperationalEvent['name'];\n payload?: RecursivePartial<OperationalEvent['payload']>;\n options?: any;\n }) {\n throw new Error('Not implemented.');\n }\n\n /**\n * Call Analyzer: Media Quality Event\n * @param args\n */\n submitMQE({\n name,\n payload,\n options,\n }: {\n name: MediaQualityEvent['name'];\n payload: RecursivePartial<MediaQualityEvent['payload']> & {\n intervals: MediaQualityEvent['payload']['intervals'];\n };\n options: any;\n }) {\n this.callDiagnosticLatencies.saveTimestamp({key: name});\n this.callDiagnosticMetrics.submitMQE({name, payload, options});\n }\n\n /**\n * Call Analyzer: Feature Usage Event\n * @param args\n */\n submitFeatureEvent({\n name,\n payload,\n options,\n }: {\n name: FeatureEvent['name'];\n payload?: RecursivePartial<FeatureEvent['payload']>;\n options: any;\n }) {\n throw new Error('Not implemented.');\n }\n\n /**\n * Call Analyzer: Client Event\n * @public\n * @param args\n */\n public submitClientEvent({\n name,\n payload,\n options,\n }: {\n name: ClientEvent['name'];\n payload?: RecursivePartial<ClientEvent['payload']>;\n options: SubmitClientEventOptions;\n }) {\n this.callDiagnosticLatencies.saveTimestamp({\n key: name,\n options: {meetingId: options?.meetingId},\n });\n this.callDiagnosticMetrics.submitClientEvent({name, payload, options});\n }\n}\n\nexport default Metrics;\n"],"mappings":"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"}
|
|
@@ -1,20 +1,32 @@
|
|
|
1
|
+
import { WebexPlugin } from '@webex/webex-core';
|
|
1
2
|
import { MetricEventNames } from '../metrics.types';
|
|
2
3
|
/**
|
|
3
4
|
* @description Helper class to store latencies timestamp and to calculate various latencies for CA.
|
|
4
5
|
* @exports
|
|
5
6
|
* @class CallDiagnosticLatencies
|
|
6
7
|
*/
|
|
7
|
-
export default class CallDiagnosticLatencies {
|
|
8
|
+
export default class CallDiagnosticLatencies extends WebexPlugin {
|
|
8
9
|
latencyTimestamps: Map<MetricEventNames, number>;
|
|
9
10
|
precomputedLatencies: Map<string, number>;
|
|
11
|
+
private meetingId?;
|
|
10
12
|
/**
|
|
11
13
|
* @constructor
|
|
12
14
|
*/
|
|
13
|
-
constructor();
|
|
15
|
+
constructor(...args: any[]);
|
|
14
16
|
/**
|
|
15
17
|
* Clear timestamps
|
|
16
18
|
*/
|
|
17
19
|
clearTimestamps(): void;
|
|
20
|
+
/**
|
|
21
|
+
* Associate current latencies with a meeting id
|
|
22
|
+
* @param meetingId
|
|
23
|
+
*/
|
|
24
|
+
private setMeetingId;
|
|
25
|
+
/**
|
|
26
|
+
* Returns the meeting object associated with current latencies
|
|
27
|
+
* @returns meeting object
|
|
28
|
+
*/
|
|
29
|
+
private getMeeting;
|
|
18
30
|
/**
|
|
19
31
|
* Store timestamp value
|
|
20
32
|
* @param key - key
|
|
@@ -22,7 +34,13 @@ export default class CallDiagnosticLatencies {
|
|
|
22
34
|
* @throws
|
|
23
35
|
* @returns
|
|
24
36
|
*/
|
|
25
|
-
saveTimestamp(key
|
|
37
|
+
saveTimestamp({ key, value, options, }: {
|
|
38
|
+
key: MetricEventNames;
|
|
39
|
+
value?: number;
|
|
40
|
+
options?: {
|
|
41
|
+
meetingId?: string;
|
|
42
|
+
};
|
|
43
|
+
}): void;
|
|
26
44
|
/**
|
|
27
45
|
* Store precomputed latency value
|
|
28
46
|
* @param key - key
|
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.180",
|
|
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.180",
|
|
32
|
+
"@webex/common-timers": "3.0.0-beta.180",
|
|
33
|
+
"@webex/internal-plugin-device": "3.0.0-beta.180",
|
|
34
|
+
"@webex/internal-plugin-metrics": "3.0.0-beta.180",
|
|
35
|
+
"@webex/test-helper-chai": "3.0.0-beta.180",
|
|
36
|
+
"@webex/test-helper-mock-webex": "3.0.0-beta.180",
|
|
37
|
+
"@webex/webex-core": "3.0.0-beta.180"
|
|
38
38
|
}
|
|
39
39
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/* eslint-disable class-methods-use-this */
|
|
2
2
|
/* eslint-disable valid-jsdoc */
|
|
3
|
+
import {WebexPlugin} from '@webex/webex-core';
|
|
3
4
|
|
|
4
5
|
import {MetricEventNames} from '../metrics.types';
|
|
5
6
|
|
|
@@ -10,14 +11,17 @@ import {MetricEventNames} from '../metrics.types';
|
|
|
10
11
|
* @exports
|
|
11
12
|
* @class CallDiagnosticLatencies
|
|
12
13
|
*/
|
|
13
|
-
export default class CallDiagnosticLatencies {
|
|
14
|
+
export default class CallDiagnosticLatencies extends WebexPlugin {
|
|
14
15
|
latencyTimestamps: Map<MetricEventNames, number>;
|
|
15
16
|
precomputedLatencies: Map<string, number>;
|
|
17
|
+
// meetingId that the current latencies are for
|
|
18
|
+
private meetingId?: string;
|
|
16
19
|
|
|
17
20
|
/**
|
|
18
21
|
* @constructor
|
|
19
22
|
*/
|
|
20
|
-
constructor() {
|
|
23
|
+
constructor(...args) {
|
|
24
|
+
super(...args);
|
|
21
25
|
this.latencyTimestamps = new Map();
|
|
22
26
|
this.precomputedLatencies = new Map();
|
|
23
27
|
}
|
|
@@ -29,6 +33,27 @@ export default class CallDiagnosticLatencies {
|
|
|
29
33
|
this.latencyTimestamps.clear();
|
|
30
34
|
}
|
|
31
35
|
|
|
36
|
+
/**
|
|
37
|
+
* Associate current latencies with a meeting id
|
|
38
|
+
* @param meetingId
|
|
39
|
+
*/
|
|
40
|
+
private setMeetingId(meetingId: string) {
|
|
41
|
+
this.meetingId = meetingId;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Returns the meeting object associated with current latencies
|
|
46
|
+
* @returns meeting object
|
|
47
|
+
*/
|
|
48
|
+
private getMeeting() {
|
|
49
|
+
if (this.meetingId) {
|
|
50
|
+
// @ts-ignore
|
|
51
|
+
return this.webex.meetings.meetingCollection.get(this.meetingId);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return undefined;
|
|
55
|
+
}
|
|
56
|
+
|
|
32
57
|
/**
|
|
33
58
|
* Store timestamp value
|
|
34
59
|
* @param key - key
|
|
@@ -36,7 +61,20 @@ export default class CallDiagnosticLatencies {
|
|
|
36
61
|
* @throws
|
|
37
62
|
* @returns
|
|
38
63
|
*/
|
|
39
|
-
public saveTimestamp(
|
|
64
|
+
public saveTimestamp({
|
|
65
|
+
key,
|
|
66
|
+
value = new Date().getTime(),
|
|
67
|
+
options = {},
|
|
68
|
+
}: {
|
|
69
|
+
key: MetricEventNames;
|
|
70
|
+
value?: number;
|
|
71
|
+
options?: {meetingId?: string};
|
|
72
|
+
}) {
|
|
73
|
+
// save the meetingId so we can use the meeting object in latency calculations if needed
|
|
74
|
+
const {meetingId} = options;
|
|
75
|
+
if (meetingId) {
|
|
76
|
+
this.setMeetingId(meetingId);
|
|
77
|
+
}
|
|
40
78
|
// for some events we're only interested in the first timestamp not last
|
|
41
79
|
// as these events can happen multiple times
|
|
42
80
|
if (key === 'client.media.rx.start' || key === 'client.media.tx.start') {
|
|
@@ -311,10 +349,15 @@ export default class CallDiagnosticLatencies {
|
|
|
311
349
|
const clickToInterstitial = this.getClickToInterstitial();
|
|
312
350
|
const interstitialToJoinOk = this.getInterstitialToJoinOK();
|
|
313
351
|
const joinConfJMT = this.getJoinConfJMT();
|
|
314
|
-
const
|
|
352
|
+
const lobbyTime = this.getStayLobbyTime();
|
|
315
353
|
|
|
316
354
|
if (clickToInterstitial && interstitialToJoinOk && joinConfJMT) {
|
|
317
|
-
|
|
355
|
+
const totalMediaJMT = clickToInterstitial + interstitialToJoinOk + joinConfJMT;
|
|
356
|
+
if (this.getMeeting()?.allowMediaInLobby) {
|
|
357
|
+
return totalMediaJMT;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
return totalMediaJMT - lobbyTime;
|
|
318
361
|
}
|
|
319
362
|
|
|
320
363
|
return undefined;
|
package/src/new-metrics.ts
CHANGED
|
@@ -41,8 +41,6 @@ class Metrics extends WebexPlugin {
|
|
|
41
41
|
constructor(...args) {
|
|
42
42
|
super(...args);
|
|
43
43
|
|
|
44
|
-
this.callDiagnosticLatencies = new CallDiagnosticLatencies();
|
|
45
|
-
|
|
46
44
|
this.onReady();
|
|
47
45
|
}
|
|
48
46
|
|
|
@@ -54,6 +52,8 @@ class Metrics extends WebexPlugin {
|
|
|
54
52
|
this.webex.once('ready', () => {
|
|
55
53
|
// @ts-ignore
|
|
56
54
|
this.callDiagnosticMetrics = new CallDiagnosticMetrics({}, {parent: this.webex});
|
|
55
|
+
// @ts-ignore
|
|
56
|
+
this.callDiagnosticLatencies = new CallDiagnosticLatencies({}, {parent: this.webex});
|
|
57
57
|
});
|
|
58
58
|
}
|
|
59
59
|
|
|
@@ -73,7 +73,7 @@ class Metrics extends WebexPlugin {
|
|
|
73
73
|
if (name === 'internal.reset.join.latencies') {
|
|
74
74
|
this.callDiagnosticLatencies.clearTimestamps();
|
|
75
75
|
} else {
|
|
76
|
-
this.callDiagnosticLatencies.saveTimestamp(name);
|
|
76
|
+
this.callDiagnosticLatencies.saveTimestamp({key: name});
|
|
77
77
|
}
|
|
78
78
|
}
|
|
79
79
|
|
|
@@ -90,7 +90,7 @@ class Metrics extends WebexPlugin {
|
|
|
90
90
|
payload?: RecursivePartial<BehavioralEvent['payload']>;
|
|
91
91
|
options?: any;
|
|
92
92
|
}) {
|
|
93
|
-
this.callDiagnosticLatencies.saveTimestamp(name);
|
|
93
|
+
this.callDiagnosticLatencies.saveTimestamp({key: name});
|
|
94
94
|
throw new Error('Not implemented.');
|
|
95
95
|
}
|
|
96
96
|
|
|
@@ -125,7 +125,7 @@ class Metrics extends WebexPlugin {
|
|
|
125
125
|
};
|
|
126
126
|
options: any;
|
|
127
127
|
}) {
|
|
128
|
-
this.callDiagnosticLatencies.saveTimestamp(name);
|
|
128
|
+
this.callDiagnosticLatencies.saveTimestamp({key: name});
|
|
129
129
|
this.callDiagnosticMetrics.submitMQE({name, payload, options});
|
|
130
130
|
}
|
|
131
131
|
|
|
@@ -159,7 +159,10 @@ class Metrics extends WebexPlugin {
|
|
|
159
159
|
payload?: RecursivePartial<ClientEvent['payload']>;
|
|
160
160
|
options: SubmitClientEventOptions;
|
|
161
161
|
}) {
|
|
162
|
-
this.callDiagnosticLatencies.saveTimestamp(
|
|
162
|
+
this.callDiagnosticLatencies.saveTimestamp({
|
|
163
|
+
key: name,
|
|
164
|
+
options: {meetingId: options?.meetingId},
|
|
165
|
+
});
|
|
163
166
|
this.callDiagnosticMetrics.submitClientEvent({name, payload, options});
|
|
164
167
|
}
|
|
165
168
|
}
|
|
@@ -1,35 +1,51 @@
|
|
|
1
1
|
import {assert} from '@webex/test-helper-chai';
|
|
2
|
-
import CallDiagnosticLatencies from '../../../../src/call-diagnostic/call-diagnostic-metrics-latencies'
|
|
2
|
+
import CallDiagnosticLatencies from '../../../../src/call-diagnostic/call-diagnostic-metrics-latencies';
|
|
3
3
|
import sinon from 'sinon';
|
|
4
4
|
|
|
5
|
-
describe(
|
|
6
|
-
describe(
|
|
5
|
+
describe('internal-plugin-metrics', () => {
|
|
6
|
+
describe('CallDiagnosticLatencies', () => {
|
|
7
7
|
let cdl: CallDiagnosticLatencies;
|
|
8
8
|
var now = new Date();
|
|
9
9
|
|
|
10
|
-
|
|
11
10
|
beforeEach(() => {
|
|
12
11
|
sinon.createSandbox();
|
|
13
12
|
sinon.useFakeTimers(now.getTime());
|
|
14
|
-
|
|
13
|
+
const webex = {
|
|
14
|
+
meetings: {
|
|
15
|
+
meetingCollection: {
|
|
16
|
+
get: (id: string) => {
|
|
17
|
+
if (id === 'meeting-id') {
|
|
18
|
+
return {id: 'meeting-id', allowMediaInLobby: true};
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
cdl = new CallDiagnosticLatencies(
|
|
26
|
+
{},
|
|
27
|
+
{
|
|
28
|
+
parent: webex,
|
|
29
|
+
}
|
|
30
|
+
);
|
|
15
31
|
});
|
|
16
32
|
|
|
17
33
|
afterEach(() => {
|
|
18
34
|
sinon.restore();
|
|
19
|
-
})
|
|
35
|
+
});
|
|
20
36
|
|
|
21
37
|
it('should save timestamp correctly', () => {
|
|
22
38
|
assert.deepEqual(cdl.latencyTimestamps.size, 0);
|
|
23
|
-
cdl.saveTimestamp('client.alert.displayed');
|
|
39
|
+
cdl.saveTimestamp({key: 'client.alert.displayed'});
|
|
24
40
|
assert.deepEqual(cdl.latencyTimestamps.size, 1);
|
|
25
|
-
assert.deepEqual(cdl.latencyTimestamps.get('client.alert.displayed'), now.getTime())
|
|
41
|
+
assert.deepEqual(cdl.latencyTimestamps.get('client.alert.displayed'), now.getTime());
|
|
26
42
|
});
|
|
27
43
|
|
|
28
44
|
it('should save latency correctly', () => {
|
|
29
45
|
assert.deepEqual(cdl.precomputedLatencies.size, 0);
|
|
30
46
|
cdl.saveLatency('client.alert.displayed', 10);
|
|
31
47
|
assert.deepEqual(cdl.precomputedLatencies.size, 1);
|
|
32
|
-
assert.deepEqual(cdl.precomputedLatencies.get('client.alert.displayed'), 10)
|
|
48
|
+
assert.deepEqual(cdl.precomputedLatencies.get('client.alert.displayed'), 10);
|
|
33
49
|
});
|
|
34
50
|
|
|
35
51
|
it('should save only first timestamp correctly', () => {
|
|
@@ -51,30 +67,30 @@ describe("internal-plugin-metrics", () => {
|
|
|
51
67
|
|
|
52
68
|
it('should update existing property and now add new keys', () => {
|
|
53
69
|
assert.deepEqual(cdl.latencyTimestamps.size, 0);
|
|
54
|
-
cdl.saveTimestamp('client.alert.displayed');
|
|
70
|
+
cdl.saveTimestamp({key: 'client.alert.displayed'});
|
|
55
71
|
assert.deepEqual(cdl.latencyTimestamps.get('client.alert.displayed'), now.getTime());
|
|
56
|
-
cdl.saveTimestamp('client.alert.displayed', 1234);
|
|
72
|
+
cdl.saveTimestamp({key: 'client.alert.displayed', value: 1234});
|
|
57
73
|
assert.deepEqual(cdl.latencyTimestamps.get('client.alert.displayed'), 1234);
|
|
58
74
|
assert.deepEqual(cdl.latencyTimestamps.size, 1);
|
|
59
|
-
})
|
|
75
|
+
});
|
|
60
76
|
|
|
61
77
|
it('should clear all timestamps correctly', () => {
|
|
62
|
-
cdl.saveTimestamp('client.alert.displayed');
|
|
63
|
-
cdl.saveTimestamp('client.alert.removed');
|
|
78
|
+
cdl.saveTimestamp({key: 'client.alert.displayed'});
|
|
79
|
+
cdl.saveTimestamp({key: 'client.alert.removed'});
|
|
64
80
|
assert.deepEqual(cdl.latencyTimestamps.size, 2);
|
|
65
81
|
cdl.clearTimestamps();
|
|
66
82
|
assert.deepEqual(cdl.latencyTimestamps.size, 0);
|
|
67
83
|
});
|
|
68
84
|
|
|
69
85
|
it('should calculate diff between timestamps correctly', () => {
|
|
70
|
-
cdl.saveTimestamp('client.alert.displayed', 10);
|
|
71
|
-
cdl.saveTimestamp('client.alert.removed', 20);
|
|
86
|
+
cdl.saveTimestamp({key: 'client.alert.displayed', value: 10});
|
|
87
|
+
cdl.saveTimestamp({key: 'client.alert.removed', value: 20});
|
|
72
88
|
const res = cdl.getDiffBetweenTimestamps('client.alert.displayed', 'client.alert.removed');
|
|
73
89
|
assert.deepEqual(res, 10);
|
|
74
90
|
});
|
|
75
91
|
|
|
76
92
|
it('it returns undefined if either one is doesnt exist', () => {
|
|
77
|
-
cdl.saveTimestamp('client.alert.displayed', 10);
|
|
93
|
+
cdl.saveTimestamp({key: 'client.alert.displayed', value: 10});
|
|
78
94
|
const res1 = cdl.getDiffBetweenTimestamps('client.alert.displayed', 'client.alert.removed');
|
|
79
95
|
assert.deepEqual(res1, undefined);
|
|
80
96
|
const res2 = cdl.getDiffBetweenTimestamps('client.alert.removed', 'client.alert.displayed');
|
|
@@ -82,68 +98,113 @@ describe("internal-plugin-metrics", () => {
|
|
|
82
98
|
});
|
|
83
99
|
|
|
84
100
|
it('calculates getMeetingInfoReqResp correctly', () => {
|
|
85
|
-
cdl.saveTimestamp('internal.client.meetinginfo.request', 10);
|
|
86
|
-
cdl.saveTimestamp('internal.client.meetinginfo.response', 20);
|
|
101
|
+
cdl.saveTimestamp({key: 'internal.client.meetinginfo.request', value: 10});
|
|
102
|
+
cdl.saveTimestamp({key: 'internal.client.meetinginfo.response', value: 20});
|
|
87
103
|
assert.deepEqual(cdl.getMeetingInfoReqResp(), 10);
|
|
88
104
|
});
|
|
89
105
|
|
|
90
106
|
it('calculates getShowInterstitialTime correctly', () => {
|
|
91
|
-
cdl.saveTimestamp('internal.client.interstitial-window.launched', 10);
|
|
92
|
-
cdl.saveTimestamp('internal.client.interstitial-window.click.joinbutton', 20);
|
|
107
|
+
cdl.saveTimestamp({key: 'internal.client.interstitial-window.launched', value: 10});
|
|
108
|
+
cdl.saveTimestamp({key: 'internal.client.interstitial-window.click.joinbutton', value: 20});
|
|
93
109
|
assert.deepEqual(cdl.getShowInterstitialTime(), 10);
|
|
94
110
|
});
|
|
95
111
|
|
|
96
112
|
it('calculates getCallInitJoinReq correctly', () => {
|
|
97
|
-
cdl.saveTimestamp('internal.client.meeting.click.joinbutton', 10);
|
|
98
|
-
cdl.saveTimestamp('client.locus.join.request', 20);
|
|
113
|
+
cdl.saveTimestamp({key: 'internal.client.meeting.click.joinbutton', value: 10});
|
|
114
|
+
cdl.saveTimestamp({key: 'client.locus.join.request', value: 20});
|
|
99
115
|
assert.deepEqual(cdl.getCallInitJoinReq(), 10);
|
|
100
116
|
});
|
|
101
117
|
|
|
102
118
|
it('calculates getCallInitJoinReq correctly without click join button event', () => {
|
|
103
119
|
cdl.saveLatency('internal.call.init.join.req', 12);
|
|
104
|
-
cdl.saveTimestamp(
|
|
120
|
+
cdl.saveTimestamp({
|
|
121
|
+
key: 'client.locus.join.request',
|
|
122
|
+
value: 20,
|
|
123
|
+
});
|
|
105
124
|
assert.deepEqual(cdl.getCallInitJoinReq(), 12);
|
|
106
125
|
});
|
|
107
126
|
|
|
108
127
|
it('calculates getJoinReqResp correctly', () => {
|
|
109
|
-
cdl.saveTimestamp(
|
|
110
|
-
|
|
128
|
+
cdl.saveTimestamp({
|
|
129
|
+
key: 'client.locus.join.request',
|
|
130
|
+
value: 10,
|
|
131
|
+
});
|
|
132
|
+
cdl.saveTimestamp({
|
|
133
|
+
key: 'client.locus.join.response',
|
|
134
|
+
value: 20,
|
|
135
|
+
});
|
|
111
136
|
assert.deepEqual(cdl.getJoinReqResp(), 10);
|
|
112
137
|
});
|
|
113
138
|
|
|
114
139
|
it('calculates getLocalSDPGenRemoteSDPRecv correctly', () => {
|
|
115
|
-
cdl.saveTimestamp(
|
|
116
|
-
|
|
140
|
+
cdl.saveTimestamp({
|
|
141
|
+
key: 'client.media-engine.local-sdp-generated',
|
|
142
|
+
value: 10,
|
|
143
|
+
});
|
|
144
|
+
cdl.saveTimestamp({
|
|
145
|
+
key: 'client.media-engine.remote-sdp-received',
|
|
146
|
+
value: 20,
|
|
147
|
+
});
|
|
117
148
|
assert.deepEqual(cdl.getLocalSDPGenRemoteSDPRecv(), 10);
|
|
118
149
|
});
|
|
119
150
|
|
|
120
151
|
it('calculates getICESetupTime correctly', () => {
|
|
121
|
-
cdl.saveTimestamp(
|
|
122
|
-
|
|
152
|
+
cdl.saveTimestamp({
|
|
153
|
+
key: 'client.ice.start',
|
|
154
|
+
value: 10,
|
|
155
|
+
});
|
|
156
|
+
cdl.saveTimestamp({
|
|
157
|
+
key: 'client.ice.end',
|
|
158
|
+
value: 20,
|
|
159
|
+
});
|
|
123
160
|
assert.deepEqual(cdl.getICESetupTime(), 10);
|
|
124
161
|
});
|
|
125
162
|
|
|
126
163
|
it('calculates getAudioICESetupTime correctly', () => {
|
|
127
|
-
cdl.saveTimestamp(
|
|
128
|
-
|
|
164
|
+
cdl.saveTimestamp({
|
|
165
|
+
key: 'client.ice.start',
|
|
166
|
+
value: 10,
|
|
167
|
+
});
|
|
168
|
+
cdl.saveTimestamp({
|
|
169
|
+
key: 'client.ice.end',
|
|
170
|
+
value: 20,
|
|
171
|
+
});
|
|
129
172
|
assert.deepEqual(cdl.getAudioICESetupTime(), 10);
|
|
130
173
|
});
|
|
131
174
|
|
|
132
175
|
it('calculates getVideoICESetupTime correctly', () => {
|
|
133
|
-
cdl.saveTimestamp(
|
|
134
|
-
|
|
176
|
+
cdl.saveTimestamp({
|
|
177
|
+
key: 'client.ice.start',
|
|
178
|
+
value: 10,
|
|
179
|
+
});
|
|
180
|
+
cdl.saveTimestamp({
|
|
181
|
+
key: 'client.ice.end',
|
|
182
|
+
value: 20,
|
|
183
|
+
});
|
|
135
184
|
assert.deepEqual(cdl.getVideoICESetupTime(), 10);
|
|
136
185
|
});
|
|
137
186
|
|
|
138
187
|
it('calculates getShareICESetupTime correctly', () => {
|
|
139
|
-
cdl.saveTimestamp(
|
|
140
|
-
|
|
188
|
+
cdl.saveTimestamp({
|
|
189
|
+
key: 'client.ice.start',
|
|
190
|
+
value: 10,
|
|
191
|
+
});
|
|
192
|
+
cdl.saveTimestamp({
|
|
193
|
+
key: 'client.ice.end',
|
|
194
|
+
value: 20,
|
|
195
|
+
});
|
|
141
196
|
assert.deepEqual(cdl.getShareICESetupTime(), 10);
|
|
142
197
|
});
|
|
143
198
|
|
|
144
199
|
it('calculates getStayLobbyTime correctly', () => {
|
|
145
|
-
cdl.saveTimestamp(
|
|
146
|
-
|
|
200
|
+
cdl.saveTimestamp({
|
|
201
|
+
key: 'client.locus.join.response',
|
|
202
|
+
value: 10,
|
|
203
|
+
});
|
|
204
|
+
cdl.saveTimestamp({
|
|
205
|
+
key: 'internal.host.meeting.participant.admitted',
|
|
206
|
+
value: 20,
|
|
207
|
+
});
|
|
147
208
|
assert.deepEqual(cdl.getStayLobbyTime(), 10);
|
|
148
209
|
});
|
|
149
210
|
|
|
@@ -153,86 +214,261 @@ describe("internal-plugin-metrics", () => {
|
|
|
153
214
|
});
|
|
154
215
|
|
|
155
216
|
it('calculates getClickToInterstitial correctly', () => {
|
|
156
|
-
cdl.saveTimestamp(
|
|
157
|
-
|
|
217
|
+
cdl.saveTimestamp({
|
|
218
|
+
key: 'internal.client.meeting.click.joinbutton',
|
|
219
|
+
value: 10,
|
|
220
|
+
});
|
|
221
|
+
cdl.saveTimestamp({
|
|
222
|
+
key: 'internal.client.meeting.interstitial-window.showed',
|
|
223
|
+
value: 20,
|
|
224
|
+
});
|
|
158
225
|
assert.deepEqual(cdl.getClickToInterstitial(), 10);
|
|
159
226
|
});
|
|
160
227
|
|
|
161
228
|
it('calculates getClickToInterstitial without join button timestamp', () => {
|
|
162
229
|
cdl.saveLatency('internal.click.to.interstitial', 5);
|
|
163
|
-
cdl.saveTimestamp(
|
|
230
|
+
cdl.saveTimestamp({
|
|
231
|
+
key: 'internal.client.meeting.interstitial-window.showed',
|
|
232
|
+
value: 20,
|
|
233
|
+
});
|
|
164
234
|
assert.deepEqual(cdl.getClickToInterstitial(), 5);
|
|
165
235
|
});
|
|
166
236
|
|
|
167
237
|
it('calculates getInterstitialToJoinOK correctly', () => {
|
|
168
|
-
cdl.saveTimestamp(
|
|
169
|
-
|
|
238
|
+
cdl.saveTimestamp({
|
|
239
|
+
key: 'internal.client.interstitial-window.click.joinbutton',
|
|
240
|
+
value: 10,
|
|
241
|
+
});
|
|
242
|
+
cdl.saveTimestamp({
|
|
243
|
+
key: 'client.locus.join.response',
|
|
244
|
+
value: 20,
|
|
245
|
+
});
|
|
170
246
|
assert.deepEqual(cdl.getInterstitialToJoinOK(), 10);
|
|
171
247
|
});
|
|
172
248
|
|
|
173
249
|
it('calculates getCallInitMediaEngineReady correctly', () => {
|
|
174
|
-
cdl.saveTimestamp(
|
|
175
|
-
|
|
250
|
+
cdl.saveTimestamp({
|
|
251
|
+
key: 'internal.client.interstitial-window.click.joinbutton',
|
|
252
|
+
value: 10,
|
|
253
|
+
});
|
|
254
|
+
cdl.saveTimestamp({
|
|
255
|
+
key: 'client.media-engine.ready',
|
|
256
|
+
value: 20,
|
|
257
|
+
});
|
|
176
258
|
assert.deepEqual(cdl.getCallInitMediaEngineReady(), 10);
|
|
177
259
|
});
|
|
178
260
|
|
|
179
261
|
it('calculates getTotalJMT correctly', () => {
|
|
180
|
-
cdl.saveTimestamp(
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
262
|
+
cdl.saveTimestamp({
|
|
263
|
+
key: 'internal.client.interstitial-window.click.joinbutton',
|
|
264
|
+
value: 5,
|
|
265
|
+
});
|
|
266
|
+
cdl.saveTimestamp({
|
|
267
|
+
key: 'internal.client.meeting.click.joinbutton',
|
|
268
|
+
value: 10,
|
|
269
|
+
});
|
|
270
|
+
cdl.saveTimestamp({
|
|
271
|
+
key: 'internal.client.meeting.interstitial-window.showed',
|
|
272
|
+
value: 20,
|
|
273
|
+
});
|
|
274
|
+
cdl.saveTimestamp({
|
|
275
|
+
key: 'client.locus.join.response',
|
|
276
|
+
value: 40,
|
|
277
|
+
});
|
|
184
278
|
assert.deepEqual(cdl.getTotalJMT(), 45);
|
|
185
279
|
});
|
|
186
280
|
|
|
281
|
+
it('calculates getTotalMediaJMT correctly', () => {
|
|
282
|
+
cdl.saveTimestamp({
|
|
283
|
+
key: 'internal.client.meeting.click.joinbutton',
|
|
284
|
+
value: 5,
|
|
285
|
+
});
|
|
286
|
+
cdl.saveTimestamp({
|
|
287
|
+
key: 'internal.client.meeting.interstitial-window.showed',
|
|
288
|
+
value: 8,
|
|
289
|
+
});
|
|
290
|
+
cdl.saveTimestamp({
|
|
291
|
+
key: 'internal.client.interstitial-window.click.joinbutton',
|
|
292
|
+
value: 10,
|
|
293
|
+
});
|
|
294
|
+
cdl.saveTimestamp({
|
|
295
|
+
key: 'client.locus.join.request',
|
|
296
|
+
value: 12,
|
|
297
|
+
});
|
|
298
|
+
cdl.saveTimestamp({
|
|
299
|
+
key: 'client.locus.join.response',
|
|
300
|
+
value: 20,
|
|
301
|
+
});
|
|
302
|
+
cdl.saveTimestamp({
|
|
303
|
+
key: 'internal.host.meeting.participant.admitted',
|
|
304
|
+
value: 24,
|
|
305
|
+
});
|
|
306
|
+
cdl.saveTimestamp({
|
|
307
|
+
key: 'client.ice.start',
|
|
308
|
+
value: 30,
|
|
309
|
+
});
|
|
310
|
+
cdl.saveTimestamp({
|
|
311
|
+
key: 'client.ice.end',
|
|
312
|
+
value: 40,
|
|
313
|
+
});
|
|
314
|
+
assert.deepEqual(cdl.getTotalMediaJMT(), 27);
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
it('calculates getTotalMediaJMT correctly with allowMediaInLobby true', () => {
|
|
318
|
+
cdl.saveTimestamp({
|
|
319
|
+
key: 'internal.client.meeting.click.joinbutton',
|
|
320
|
+
value: 5,
|
|
321
|
+
options: {meetingId: 'meeting-id'},
|
|
322
|
+
});
|
|
323
|
+
cdl.saveTimestamp({
|
|
324
|
+
key: 'internal.client.meeting.interstitial-window.showed',
|
|
325
|
+
value: 8,
|
|
326
|
+
});
|
|
327
|
+
cdl.saveTimestamp({
|
|
328
|
+
key: 'internal.client.interstitial-window.click.joinbutton',
|
|
329
|
+
value: 10,
|
|
330
|
+
});
|
|
331
|
+
cdl.saveTimestamp({
|
|
332
|
+
key: 'client.locus.join.request',
|
|
333
|
+
value: 12,
|
|
334
|
+
});
|
|
335
|
+
cdl.saveTimestamp({
|
|
336
|
+
key: 'client.locus.join.response',
|
|
337
|
+
value: 20,
|
|
338
|
+
});
|
|
339
|
+
cdl.saveTimestamp({
|
|
340
|
+
key: 'internal.host.meeting.participant.admitted',
|
|
341
|
+
value: 24,
|
|
342
|
+
});
|
|
343
|
+
cdl.saveTimestamp({
|
|
344
|
+
key: 'client.ice.start',
|
|
345
|
+
value: 30,
|
|
346
|
+
});
|
|
347
|
+
cdl.saveTimestamp({
|
|
348
|
+
key: 'client.ice.end',
|
|
349
|
+
value: 40,
|
|
350
|
+
});
|
|
351
|
+
assert.deepEqual(cdl.getTotalMediaJMT(), 31);
|
|
352
|
+
});
|
|
353
|
+
|
|
187
354
|
it('calculates getJoinConfJMT correctly', () => {
|
|
188
|
-
cdl.saveTimestamp(
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
355
|
+
cdl.saveTimestamp({
|
|
356
|
+
key: 'client.locus.join.request',
|
|
357
|
+
value: 10,
|
|
358
|
+
});
|
|
359
|
+
cdl.saveTimestamp({
|
|
360
|
+
key: 'client.locus.join.response',
|
|
361
|
+
value: 20,
|
|
362
|
+
});
|
|
363
|
+
cdl.saveTimestamp({
|
|
364
|
+
key: 'client.ice.start',
|
|
365
|
+
value: 30,
|
|
366
|
+
});
|
|
367
|
+
cdl.saveTimestamp({
|
|
368
|
+
key: 'client.ice.end',
|
|
369
|
+
value: 40,
|
|
370
|
+
});
|
|
192
371
|
assert.deepEqual(cdl.getJoinConfJMT(), 20);
|
|
193
372
|
});
|
|
194
373
|
|
|
195
374
|
it('calculates getClientJMT correctly', () => {
|
|
196
|
-
cdl.saveTimestamp(
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
cdl.saveTimestamp(
|
|
375
|
+
cdl.saveTimestamp({
|
|
376
|
+
key: 'internal.client.interstitial-window.click.joinbutton',
|
|
377
|
+
value: 2,
|
|
378
|
+
});
|
|
379
|
+
cdl.saveTimestamp({
|
|
380
|
+
key: 'client.locus.join.request',
|
|
381
|
+
value: 6,
|
|
382
|
+
});
|
|
383
|
+
cdl.saveTimestamp({
|
|
384
|
+
key: 'client.locus.join.response',
|
|
385
|
+
value: 8,
|
|
386
|
+
});
|
|
387
|
+
cdl.saveTimestamp({
|
|
388
|
+
key: 'client.ice.start',
|
|
389
|
+
value: 10,
|
|
390
|
+
});
|
|
391
|
+
cdl.saveTimestamp({
|
|
392
|
+
key: 'client.ice.end',
|
|
393
|
+
value: 11,
|
|
394
|
+
});
|
|
201
395
|
assert.deepEqual(cdl.getClientJMT(), 3);
|
|
202
396
|
});
|
|
203
397
|
|
|
204
398
|
it('calculates getAudioJoinRespRxStart correctly', () => {
|
|
205
|
-
cdl.saveTimestamp(
|
|
206
|
-
|
|
399
|
+
cdl.saveTimestamp({
|
|
400
|
+
key: 'client.locus.join.response',
|
|
401
|
+
value: 5,
|
|
402
|
+
});
|
|
403
|
+
cdl.saveTimestamp({
|
|
404
|
+
key: 'client.media.rx.start',
|
|
405
|
+
value: 7,
|
|
406
|
+
});
|
|
207
407
|
assert.deepEqual(cdl.getAudioJoinRespRxStart(), 2);
|
|
208
408
|
});
|
|
209
409
|
|
|
210
410
|
it('calculates getVideoJoinRespRxStart correctly', () => {
|
|
211
|
-
cdl.saveTimestamp(
|
|
212
|
-
|
|
411
|
+
cdl.saveTimestamp({
|
|
412
|
+
key: 'client.locus.join.response',
|
|
413
|
+
value: 5,
|
|
414
|
+
});
|
|
415
|
+
cdl.saveTimestamp({
|
|
416
|
+
key: 'client.media.rx.start',
|
|
417
|
+
value: 7,
|
|
418
|
+
});
|
|
213
419
|
assert.deepEqual(cdl.getVideoJoinRespRxStart(), 2);
|
|
214
420
|
});
|
|
215
421
|
|
|
216
422
|
it('calculates getAudioJoinRespTxStart correctly', () => {
|
|
217
|
-
cdl.saveTimestamp(
|
|
218
|
-
|
|
423
|
+
cdl.saveTimestamp({
|
|
424
|
+
key: 'client.locus.join.response',
|
|
425
|
+
value: 5,
|
|
426
|
+
});
|
|
427
|
+
cdl.saveTimestamp({
|
|
428
|
+
key: 'client.media.tx.start',
|
|
429
|
+
value: 7,
|
|
430
|
+
});
|
|
219
431
|
assert.deepEqual(cdl.getAudioJoinRespTxStart(), 2);
|
|
220
432
|
});
|
|
221
433
|
|
|
222
434
|
it('calculates getVideoJoinRespTxStart correctly', () => {
|
|
223
|
-
cdl.saveTimestamp(
|
|
224
|
-
|
|
435
|
+
cdl.saveTimestamp({
|
|
436
|
+
key: 'client.locus.join.response',
|
|
437
|
+
value: 5,
|
|
438
|
+
});
|
|
439
|
+
cdl.saveTimestamp({
|
|
440
|
+
key: 'client.media.tx.start',
|
|
441
|
+
value: 7,
|
|
442
|
+
});
|
|
225
443
|
assert.deepEqual(cdl.getVideoJoinRespTxStart(), 2);
|
|
226
444
|
});
|
|
227
445
|
|
|
228
446
|
it('calculates getInterstitialToMediaOKJMT correctly', () => {
|
|
229
|
-
cdl.saveTimestamp(
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
cdl.saveTimestamp(
|
|
234
|
-
|
|
447
|
+
cdl.saveTimestamp({
|
|
448
|
+
key: 'internal.client.interstitial-window.click.joinbutton',
|
|
449
|
+
value: 4,
|
|
450
|
+
});
|
|
451
|
+
cdl.saveTimestamp({
|
|
452
|
+
key: 'client.locus.join.response',
|
|
453
|
+
value: 10,
|
|
454
|
+
});
|
|
455
|
+
cdl.saveTimestamp({
|
|
456
|
+
key: 'internal.host.meeting.participant.admitted',
|
|
457
|
+
value: 12,
|
|
458
|
+
});
|
|
459
|
+
cdl.saveTimestamp({
|
|
460
|
+
key: 'client.media.rx.start',
|
|
461
|
+
value: 14,
|
|
462
|
+
});
|
|
463
|
+
cdl.saveTimestamp({
|
|
464
|
+
key: 'client.media.tx.start',
|
|
465
|
+
value: 15,
|
|
466
|
+
});
|
|
467
|
+
cdl.saveTimestamp({
|
|
468
|
+
key: 'client.media.rx.start',
|
|
469
|
+
value: 16,
|
|
470
|
+
});
|
|
235
471
|
assert.deepEqual(cdl.getInterstitialToMediaOKJMT(), 8);
|
|
236
472
|
});
|
|
237
|
-
})
|
|
238
|
-
})
|
|
473
|
+
});
|
|
474
|
+
});
|
|
@@ -33,15 +33,18 @@ describe("internal-plugin-metrics", () => {
|
|
|
33
33
|
name: 'client.alert.displayed',
|
|
34
34
|
options: {
|
|
35
35
|
meetingId: '123',
|
|
36
|
-
}
|
|
36
|
+
},
|
|
37
37
|
});
|
|
38
38
|
|
|
39
|
-
assert.calledWith(
|
|
39
|
+
assert.calledWith(
|
|
40
|
+
webex.internal.newMetrics.callDiagnosticLatencies.saveTimestamp,
|
|
41
|
+
{key: 'client.alert.displayed', options: {meetingId: '123'}}
|
|
42
|
+
);
|
|
40
43
|
assert.calledWith(webex.internal.newMetrics.callDiagnosticMetrics.submitClientEvent, {
|
|
41
44
|
name: 'client.alert.displayed',
|
|
42
45
|
payload: undefined,
|
|
43
|
-
options: {
|
|
44
|
-
})
|
|
46
|
+
options: {meetingId: '123'},
|
|
47
|
+
});
|
|
45
48
|
});
|
|
46
49
|
|
|
47
50
|
it('submits MQE successfully', () => {
|
|
@@ -55,7 +58,7 @@ describe("internal-plugin-metrics", () => {
|
|
|
55
58
|
}
|
|
56
59
|
});
|
|
57
60
|
|
|
58
|
-
assert.calledWith(webex.internal.newMetrics.callDiagnosticLatencies.saveTimestamp, 'client.mediaquality.event')
|
|
61
|
+
assert.calledWith(webex.internal.newMetrics.callDiagnosticLatencies.saveTimestamp, {key: 'client.mediaquality.event'})
|
|
59
62
|
assert.calledWith(webex.internal.newMetrics.callDiagnosticMetrics.submitMQE, {
|
|
60
63
|
name: 'client.mediaquality.event',
|
|
61
64
|
//@ts-ignore
|
|
@@ -72,7 +75,7 @@ describe("internal-plugin-metrics", () => {
|
|
|
72
75
|
name: 'client.mediaquality.event',
|
|
73
76
|
});
|
|
74
77
|
|
|
75
|
-
assert.calledWith(webex.internal.newMetrics.callDiagnosticLatencies.saveTimestamp, 'client.mediaquality.event')
|
|
78
|
+
assert.calledWith(webex.internal.newMetrics.callDiagnosticLatencies.saveTimestamp, {key: 'client.mediaquality.event'})
|
|
76
79
|
assert.notCalled(webex.internal.newMetrics.callDiagnosticLatencies.clearTimestamps)
|
|
77
80
|
});
|
|
78
81
|
|