@webex/internal-plugin-metrics 3.0.0-next.3 → 3.0.0-next.5

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.
Files changed (27) hide show
  1. package/dist/call-diagnostic/call-diagnostic-metrics-latencies.js +45 -13
  2. package/dist/call-diagnostic/call-diagnostic-metrics-latencies.js.map +1 -1
  3. package/dist/call-diagnostic/call-diagnostic-metrics.js +34 -29
  4. package/dist/call-diagnostic/call-diagnostic-metrics.js.map +1 -1
  5. package/dist/call-diagnostic/call-diagnostic-metrics.util.js +4 -1
  6. package/dist/call-diagnostic/call-diagnostic-metrics.util.js.map +1 -1
  7. package/dist/index.js.map +1 -1
  8. package/dist/metrics.js +1 -1
  9. package/dist/metrics.types.js.map +1 -1
  10. package/dist/new-metrics.js +5 -4
  11. package/dist/new-metrics.js.map +1 -1
  12. package/dist/types/call-diagnostic/call-diagnostic-metrics-latencies.d.ts +21 -7
  13. package/dist/types/call-diagnostic/call-diagnostic-metrics.d.ts +3 -9
  14. package/dist/types/index.d.ts +2 -2
  15. package/dist/types/metrics.types.d.ts +1 -1
  16. package/package.json +13 -13
  17. package/src/call-diagnostic/call-diagnostic-metrics-latencies.ts +44 -12
  18. package/src/call-diagnostic/call-diagnostic-metrics.ts +6 -0
  19. package/src/call-diagnostic/call-diagnostic-metrics.util.ts +4 -1
  20. package/src/index.ts +2 -0
  21. package/src/metrics.types.ts +3 -1
  22. package/src/new-metrics.ts +2 -2
  23. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics-batcher.ts +4 -4
  24. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics-latencies.ts +138 -1
  25. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics.ts +6 -0
  26. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics.util.ts +6 -1
  27. package/test/unit/spec/new-metrics.ts +29 -31
@@ -1 +1 @@
1
- {"version":3,"names":["_webexCore","require","_callDiagnosticMetrics","_interopRequireDefault","_callDiagnosticMetricsLatencies","_callDiagnosticMetrics2","_utils","_class","_createSuper","Derived","hasNativeReflectConstruct","_isNativeReflectConstruct","_createSuperInternal","Super","_getPrototypeOf2","default","result","NewTarget","constructor","_Reflect$construct","arguments","apply","_possibleConstructorReturn2","Reflect","sham","Proxy","Boolean","prototype","valueOf","call","e","Metrics","_WebexPlugin","_inherits2","_super","_this","_classCallCheck2","_len","length","args","Array","_key","concat","_defineProperty2","_assertThisInitialized2","onReady","_createClass2","key","value","_this2","webex","once","callDiagnosticMetrics","CallDiagnosticMetrics","parent","callDiagnosticLatencies","CallDiagnosticLatencies","submitInternalEvent","_ref","name","payload","options","clearTimestamps","saveTimestamp","submitBehavioralEvent","_ref2","Error","submitOperationalEvent","_ref3","submitMQE","_ref4","submitFeatureEvent","_ref5","submitClientEvent","_ref6","logger","log","_promise","resolve","meetingId","clientMetricsAliasUser","preLoginId","_this3","request","method","api","resource","headers","body","qs","alias","then","res","catch","err","error","generateCommonErrorMetadata","reject","_buildClientEventFetchRequestOptions","_asyncToGenerator2","_regenerator","mark","_callee","_ref7","wrap","_callee$","_context","prev","next","abrupt","buildClientEventFetchRequestOptions","stop","_x","setMetricTimingsAndFetch","setTimingsAndFetch","setMetricTimings","isServiceErrorExpected","serviceErrorCode","WebexPlugin","_default","exports"],"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';\nimport {setMetricTimings} from './call-diagnostic/call-diagnostic-metrics.util';\nimport {generateCommonErrorMetadata} from './utils';\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 }): Promise<any> {\n if (!this.callDiagnosticLatencies || !this.callDiagnosticMetrics) {\n // @ts-ignore\n this.webex.logger.log(\n `NewMetrics: @submitClientEvent. Attempted to submit before webex.ready. Event name: ${name}`\n );\n\n return Promise.resolve();\n }\n this.callDiagnosticLatencies.saveTimestamp({\n key: name,\n options: {meetingId: options?.meetingId},\n });\n\n return this.callDiagnosticMetrics.submitClientEvent({name, payload, options});\n }\n\n /**\n * Issue request to alias a user's pre-login ID with their CI UUID\n * @param {string} preLoginId\n * @returns {Object} HttpResponse object\n */\n public clientMetricsAliasUser(preLoginId: string) {\n // @ts-ignore\n return this.webex\n .request({\n method: 'POST',\n api: 'metrics',\n resource: 'clientmetrics',\n headers: {\n 'x-prelogin-userid': preLoginId,\n },\n body: {},\n qs: {\n alias: true,\n },\n })\n .then((res) => {\n // @ts-ignore\n this.webex.logger.log(`NewMetrics: @clientMetricsAliasUser. Request successful.`);\n\n return res;\n })\n .catch((err) => {\n // @ts-ignore\n this.logger.error(\n `NewMetrics: @clientMetricsAliasUser. Request failed:`,\n `err: ${generateCommonErrorMetadata(err)}`\n );\n\n return Promise.reject(err);\n });\n }\n\n /**\n * Returns a promise that will resolve to fetch options for submitting a metric.\n *\n * This is to support quickly submitting metrics when the browser/tab is closing.\n * Calling submitClientEvent will not work because there some async steps that will\n * not complete before the browser is closed. Instead, we pre-gather all the\n * information/options needed for the request(s), and then simply and quickly\n * fire the fetch(es) when beforeUnload is triggered.\n *\n * We must use fetch instead of request because fetch has a keepalive option that\n * allows the request it to outlive the page.\n *\n * Note: the timings values will be wrong, but setMetricTimingsAndFetch() will\n * properly adjust them before submitting.\n *\n * @public\n * @param {Object} arg\n * @param {String} arg.name - event name\n * @param {Object} arg.payload - event payload\n * @param {Object} arg.options - other options\n * @returns {Promise} promise that resolves to options to be used with fetch\n */\n public async buildClientEventFetchRequestOptions({\n name,\n payload,\n options,\n }: {\n name: ClientEvent['name'];\n payload?: RecursivePartial<ClientEvent['payload']>;\n options?: SubmitClientEventOptions;\n }): Promise<any> {\n return this.callDiagnosticMetrics.buildClientEventFetchRequestOptions({\n name,\n payload,\n options,\n });\n }\n\n /**\n * Submits a metric from pre-built request options via the fetch API. Updates\n * the \"$timings\" and \"originTime\" values to Date.now() since the existing times\n * were set when the options were built (not submitted).\n\n * @param {any} options - the pre-built request options for submitting a metric\n * @returns {Promise} promise that resolves to the response object\n */\n public setMetricTimingsAndFetch(options: any): Promise<any> {\n // @ts-ignore\n return this.webex.setTimingsAndFetch(setMetricTimings(options));\n }\n\n /**\n * Returns true if the specified serviceErrorCode maps to an expected error.\n * @param {number} serviceErrorCode the service error code\n * @returns {boolean}\n */\n public isServiceErrorExpected(serviceErrorCode: number): boolean {\n return this.callDiagnosticMetrics.isServiceErrorExpected(serviceErrorCode);\n }\n}\n\nexport default Metrics;\n"],"mappings":"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"}
1
+ {"version":3,"names":["_webexCore","require","_callDiagnosticMetrics","_interopRequireDefault","_callDiagnosticMetricsLatencies","_callDiagnosticMetrics2","_utils","_class","_createSuper","Derived","hasNativeReflectConstruct","_isNativeReflectConstruct","_createSuperInternal","Super","_getPrototypeOf2","default","result","NewTarget","constructor","_Reflect$construct","arguments","apply","_possibleConstructorReturn2","Reflect","sham","Proxy","Boolean","prototype","valueOf","call","e","Metrics","_WebexPlugin","_inherits2","_super","_this","_classCallCheck2","_len","length","args","Array","_key","concat","_defineProperty2","_assertThisInitialized2","callDiagnosticLatencies","CallDiagnosticLatencies","parent","webex","onReady","_createClass2","key","value","_this2","once","callDiagnosticMetrics","CallDiagnosticMetrics","submitInternalEvent","_ref","name","payload","options","clearTimestamps","saveTimestamp","submitBehavioralEvent","_ref2","Error","submitOperationalEvent","_ref3","submitMQE","_ref4","submitFeatureEvent","_ref5","submitClientEvent","_ref6","logger","log","_promise","resolve","meetingId","clientMetricsAliasUser","preLoginId","_this3","request","method","api","resource","headers","body","qs","alias","then","res","catch","err","error","generateCommonErrorMetadata","reject","_buildClientEventFetchRequestOptions","_asyncToGenerator2","_regenerator","mark","_callee","_ref7","wrap","_callee$","_context","prev","next","abrupt","buildClientEventFetchRequestOptions","stop","_x","setMetricTimingsAndFetch","setTimingsAndFetch","setMetricTimings","isServiceErrorExpected","serviceErrorCode","WebexPlugin","_default","exports"],"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';\nimport {setMetricTimings} from './call-diagnostic/call-diagnostic-metrics.util';\nimport {generateCommonErrorMetadata} from './utils';\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 // @ts-ignore\n this.callDiagnosticLatencies = new CallDiagnosticLatencies({}, {parent: this.webex});\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 });\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 }): Promise<any> {\n if (!this.callDiagnosticLatencies || !this.callDiagnosticMetrics) {\n // @ts-ignore\n this.webex.logger.log(\n `NewMetrics: @submitClientEvent. Attempted to submit before webex.ready. Event name: ${name}`\n );\n\n return Promise.resolve();\n }\n this.callDiagnosticLatencies.saveTimestamp({\n key: name,\n options: {meetingId: options?.meetingId},\n });\n\n return this.callDiagnosticMetrics.submitClientEvent({name, payload, options});\n }\n\n /**\n * Issue request to alias a user's pre-login ID with their CI UUID\n * @param {string} preLoginId\n * @returns {Object} HttpResponse object\n */\n public clientMetricsAliasUser(preLoginId: string) {\n // @ts-ignore\n return this.webex\n .request({\n method: 'POST',\n api: 'metrics',\n resource: 'clientmetrics',\n headers: {\n 'x-prelogin-userid': preLoginId,\n },\n body: {},\n qs: {\n alias: true,\n },\n })\n .then((res) => {\n // @ts-ignore\n this.webex.logger.log(`NewMetrics: @clientMetricsAliasUser. Request successful.`);\n\n return res;\n })\n .catch((err) => {\n // @ts-ignore\n this.logger.error(\n `NewMetrics: @clientMetricsAliasUser. Request failed:`,\n `err: ${generateCommonErrorMetadata(err)}`\n );\n\n return Promise.reject(err);\n });\n }\n\n /**\n * Returns a promise that will resolve to fetch options for submitting a metric.\n *\n * This is to support quickly submitting metrics when the browser/tab is closing.\n * Calling submitClientEvent will not work because there some async steps that will\n * not complete before the browser is closed. Instead, we pre-gather all the\n * information/options needed for the request(s), and then simply and quickly\n * fire the fetch(es) when beforeUnload is triggered.\n *\n * We must use fetch instead of request because fetch has a keepalive option that\n * allows the request it to outlive the page.\n *\n * Note: the timings values will be wrong, but setMetricTimingsAndFetch() will\n * properly adjust them before submitting.\n *\n * @public\n * @param {Object} arg\n * @param {String} arg.name - event name\n * @param {Object} arg.payload - event payload\n * @param {Object} arg.options - other options\n * @returns {Promise} promise that resolves to options to be used with fetch\n */\n public async buildClientEventFetchRequestOptions({\n name,\n payload,\n options,\n }: {\n name: ClientEvent['name'];\n payload?: RecursivePartial<ClientEvent['payload']>;\n options?: SubmitClientEventOptions;\n }): Promise<any> {\n return this.callDiagnosticMetrics.buildClientEventFetchRequestOptions({\n name,\n payload,\n options,\n });\n }\n\n /**\n * Submits a metric from pre-built request options via the fetch API. Updates\n * the \"$timings\" and \"originTime\" values to Date.now() since the existing times\n * were set when the options were built (not submitted).\n\n * @param {any} options - the pre-built request options for submitting a metric\n * @returns {Promise} promise that resolves to the response object\n */\n public setMetricTimingsAndFetch(options: any): Promise<any> {\n // @ts-ignore\n return this.webex.setTimingsAndFetch(setMetricTimings(options));\n }\n\n /**\n * Returns true if the specified serviceErrorCode maps to an expected error.\n * @param {number} serviceErrorCode the service error code\n * @returns {boolean}\n */\n public isServiceErrorExpected(serviceErrorCode: number): boolean {\n return this.callDiagnosticMetrics.isServiceErrorExpected(serviceErrorCode);\n }\n}\n\nexport default Metrics;\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAKA,IAAAA,UAAA,GAAAC,OAAA;AAEA,IAAAC,sBAAA,GAAAC,sBAAA,CAAAF,OAAA;AAWA,IAAAG,+BAAA,GAAAD,sBAAA,CAAAF,OAAA;AACA,IAAAI,uBAAA,GAAAJ,OAAA;AACA,IAAAK,MAAA,GAAAL,OAAA;AAAoD,IAAAM,MAAA;AApBpD;AACA;AACA;AAEA;AAAA,SAAAC,aAAAC,OAAA,QAAAC,yBAAA,GAAAC,yBAAA,oBAAAC,qBAAA,QAAAC,KAAA,OAAAC,gBAAA,CAAAC,OAAA,EAAAN,OAAA,GAAAO,MAAA,MAAAN,yBAAA,QAAAO,SAAA,OAAAH,gBAAA,CAAAC,OAAA,QAAAG,WAAA,EAAAF,MAAA,GAAAG,kBAAA,CAAAN,KAAA,EAAAO,SAAA,EAAAH,SAAA,YAAAD,MAAA,GAAAH,KAAA,CAAAQ,KAAA,OAAAD,SAAA,gBAAAE,2BAAA,CAAAP,OAAA,QAAAC,MAAA;AAAA,SAAAL,0BAAA,eAAAY,OAAA,qBAAAJ,kBAAA,oBAAAA,kBAAA,CAAAK,IAAA,2BAAAC,KAAA,oCAAAC,OAAA,CAAAC,SAAA,CAAAC,OAAA,CAAAC,IAAA,CAAAV,kBAAA,CAAAO,OAAA,8CAAAI,CAAA;AAkBA;AACA;AACA;AACA;AAHA,IAIMC,OAAO,0BAAAC,YAAA;EAAA,IAAAC,UAAA,CAAAlB,OAAA,EAAAgB,OAAA,EAAAC,YAAA;EAAA,IAAAE,MAAA,GAAA1B,YAAA,CAAAuB,OAAA;EASX;AACF;AACA;AACA;AACA;AACA;AACA;EACE,SAAAA,QAAA,EAAqB;IAAA,IAAAI,KAAA;IAAA,IAAAC,gBAAA,CAAArB,OAAA,QAAAgB,OAAA;IAAA,SAAAM,IAAA,GAAAjB,SAAA,CAAAkB,MAAA,EAANC,IAAI,OAAAC,KAAA,CAAAH,IAAA,GAAAI,IAAA,MAAAA,IAAA,GAAAJ,IAAA,EAAAI,IAAA;MAAJF,IAAI,CAAAE,IAAA,IAAArB,SAAA,CAAAqB,IAAA;IAAA;IACjBN,KAAA,GAAAD,MAAA,CAAAL,IAAA,CAAAR,KAAA,CAAAa,MAAA,SAAAQ,MAAA,CAASH,IAAI;;IAEb;IAfF;IAAA,IAAAI,gBAAA,CAAA5B,OAAA,MAAA6B,uBAAA,CAAA7B,OAAA,EAAAoB,KAAA;IAEA;IAAA,IAAAQ,gBAAA,CAAA5B,OAAA,MAAA6B,uBAAA,CAAA7B,OAAA,EAAAoB,KAAA;IAcEA,KAAA,CAAKU,uBAAuB,GAAG,IAAIC,uCAAuB,CAAC,CAAC,CAAC,EAAE;MAACC,MAAM,EAAEZ,KAAA,CAAKa;IAAK,CAAC,CAAC;IACpFb,KAAA,CAAKc,OAAO,CAAC,CAAC;IAAC,OAAAd,KAAA;EACjB;;EAEA;AACF;AACA;EAFE,IAAAe,aAAA,CAAAnC,OAAA,EAAAgB,OAAA;IAAAoB,GAAA;IAAAC,KAAA,EAGA,SAAAH,QAAA,EAAkB;MAAA,IAAAI,MAAA;MAChB;MACA,IAAI,CAACL,KAAK,CAACM,IAAI,CAAC,OAAO,EAAE,YAAM;QAC7B;QACAD,MAAI,CAACE,qBAAqB,GAAG,IAAIC,8BAAqB,CAAC,CAAC,CAAC,EAAE;UAACT,MAAM,EAAEM,MAAI,CAACL;QAAK,CAAC,CAAC;MAClF,CAAC,CAAC;IACJ;;IAEA;AACF;AACA;AACA;EAHE;IAAAG,GAAA;IAAAC,KAAA,EAIA,SAAAK,oBAAAC,IAAA,EAQG;MAAA,IAPDC,IAAI,GAAAD,IAAA,CAAJC,IAAI;QACJC,OAAO,GAAAF,IAAA,CAAPE,OAAO;QACPC,OAAO,GAAAH,IAAA,CAAPG,OAAO;MAMP,IAAIF,IAAI,KAAK,+BAA+B,EAAE;QAC5C,IAAI,CAACd,uBAAuB,CAACiB,eAAe,CAAC,CAAC;MAChD,CAAC,MAAM;QACL,IAAI,CAACjB,uBAAuB,CAACkB,aAAa,CAAC;UAACZ,GAAG,EAAEQ;QAAI,CAAC,CAAC;MACzD;IACF;;IAEA;AACF;AACA;AACA;EAHE;IAAAR,GAAA;IAAAC,KAAA,EAIA,SAAAY,sBAAAC,KAAA,EAQG;MAAA,IAPDN,IAAI,GAAAM,KAAA,CAAJN,IAAI;QACJC,OAAO,GAAAK,KAAA,CAAPL,OAAO;QACPC,OAAO,GAAAI,KAAA,CAAPJ,OAAO;MAMP,IAAI,CAAChB,uBAAuB,CAACkB,aAAa,CAAC;QAACZ,GAAG,EAAEQ;MAAI,CAAC,CAAC;MACvD,MAAM,IAAIO,KAAK,CAAC,kBAAkB,CAAC;IACrC;;IAEA;AACF;AACA;AACA;EAHE;IAAAf,GAAA;IAAAC,KAAA,EAIA,SAAAe,uBAAAC,KAAA,EAQG;MAAA,IAPDT,IAAI,GAAAS,KAAA,CAAJT,IAAI;QACJC,OAAO,GAAAQ,KAAA,CAAPR,OAAO;QACPC,OAAO,GAAAO,KAAA,CAAPP,OAAO;MAMP,MAAM,IAAIK,KAAK,CAAC,kBAAkB,CAAC;IACrC;;IAEA;AACF;AACA;AACA;EAHE;IAAAf,GAAA;IAAAC,KAAA,EAIA,SAAAiB,UAAAC,KAAA,EAUG;MAAA,IATDX,IAAI,GAAAW,KAAA,CAAJX,IAAI;QACJC,OAAO,GAAAU,KAAA,CAAPV,OAAO;QACPC,OAAO,GAAAS,KAAA,CAAPT,OAAO;MAQP,IAAI,CAAChB,uBAAuB,CAACkB,aAAa,CAAC;QAACZ,GAAG,EAAEQ;MAAI,CAAC,CAAC;MACvD,IAAI,CAACJ,qBAAqB,CAACc,SAAS,CAAC;QAACV,IAAI,EAAJA,IAAI;QAAEC,OAAO,EAAPA,OAAO;QAAEC,OAAO,EAAPA;MAAO,CAAC,CAAC;IAChE;;IAEA;AACF;AACA;AACA;EAHE;IAAAV,GAAA;IAAAC,KAAA,EAIA,SAAAmB,mBAAAC,KAAA,EAQG;MAAA,IAPDb,IAAI,GAAAa,KAAA,CAAJb,IAAI;QACJC,OAAO,GAAAY,KAAA,CAAPZ,OAAO;QACPC,OAAO,GAAAW,KAAA,CAAPX,OAAO;MAMP,MAAM,IAAIK,KAAK,CAAC,kBAAkB,CAAC;IACrC;;IAEA;AACF;AACA;AACA;AACA;EAJE;IAAAf,GAAA;IAAAC,KAAA,EAKA,SAAAqB,kBAAAC,KAAA,EAQiB;MAAA,IAPff,IAAI,GAAAe,KAAA,CAAJf,IAAI;QACJC,OAAO,GAAAc,KAAA,CAAPd,OAAO;QACPC,OAAO,GAAAa,KAAA,CAAPb,OAAO;MAMP,IAAI,CAAC,IAAI,CAAChB,uBAAuB,IAAI,CAAC,IAAI,CAACU,qBAAqB,EAAE;QAChE;QACA,IAAI,CAACP,KAAK,CAAC2B,MAAM,CAACC,GAAG,wFAAAlC,MAAA,CACoEiB,IAAI,CAC7F,CAAC;QAED,OAAOkB,QAAA,CAAA9D,OAAA,CAAQ+D,OAAO,CAAC,CAAC;MAC1B;MACA,IAAI,CAACjC,uBAAuB,CAACkB,aAAa,CAAC;QACzCZ,GAAG,EAAEQ,IAAI;QACTE,OAAO,EAAE;UAACkB,SAAS,EAAElB,OAAO,aAAPA,OAAO,uBAAPA,OAAO,CAAEkB;QAAS;MACzC,CAAC,CAAC;MAEF,OAAO,IAAI,CAACxB,qBAAqB,CAACkB,iBAAiB,CAAC;QAACd,IAAI,EAAJA,IAAI;QAAEC,OAAO,EAAPA,OAAO;QAAEC,OAAO,EAAPA;MAAO,CAAC,CAAC;IAC/E;;IAEA;AACF;AACA;AACA;AACA;EAJE;IAAAV,GAAA;IAAAC,KAAA,EAKA,SAAA4B,uBAA8BC,UAAkB,EAAE;MAAA,IAAAC,MAAA;MAChD;MACA,OAAO,IAAI,CAAClC,KAAK,CACdmC,OAAO,CAAC;QACPC,MAAM,EAAE,MAAM;QACdC,GAAG,EAAE,SAAS;QACdC,QAAQ,EAAE,eAAe;QACzBC,OAAO,EAAE;UACP,mBAAmB,EAAEN;QACvB,CAAC;QACDO,IAAI,EAAE,CAAC,CAAC;QACRC,EAAE,EAAE;UACFC,KAAK,EAAE;QACT;MACF,CAAC,CAAC,CACDC,IAAI,CAAC,UAACC,GAAG,EAAK;QACb;QACAV,MAAI,CAAClC,KAAK,CAAC2B,MAAM,CAACC,GAAG,2DAA2D,CAAC;QAEjF,OAAOgB,GAAG;MACZ,CAAC,CAAC,CACDC,KAAK,CAAC,UAACC,GAAG,EAAK;QACd;QACAZ,MAAI,CAACP,MAAM,CAACoB,KAAK,iEAAArD,MAAA,CAEP,IAAAsD,kCAA2B,EAACF,GAAG,CAAC,CAC1C,CAAC;QAED,OAAOjB,QAAA,CAAA9D,OAAA,CAAQkF,MAAM,CAACH,GAAG,CAAC;MAC5B,CAAC,CAAC;IACN;;IAEA;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EArBE;IAAA3C,GAAA;IAAAC,KAAA;MAAA,IAAA8C,oCAAA,OAAAC,kBAAA,CAAApF,OAAA,gBAAAqF,YAAA,CAAArF,OAAA,CAAAsF,IAAA,CAsBA,SAAAC,QAAAC,KAAA;QAAA,IAAA5C,IAAA,EAAAC,OAAA,EAAAC,OAAA;QAAA,OAAAuC,YAAA,CAAArF,OAAA,CAAAyF,IAAA,UAAAC,SAAAC,QAAA;UAAA,kBAAAA,QAAA,CAAAC,IAAA,GAAAD,QAAA,CAAAE,IAAA;YAAA;cACEjD,IAAI,GAAA4C,KAAA,CAAJ5C,IAAI,EACJC,OAAO,GAAA2C,KAAA,CAAP3C,OAAO,EACPC,OAAO,GAAA0C,KAAA,CAAP1C,OAAO;cAAA,OAAA6C,QAAA,CAAAG,MAAA,WAMA,IAAI,CAACtD,qBAAqB,CAACuD,mCAAmC,CAAC;gBACpEnD,IAAI,EAAJA,IAAI;gBACJC,OAAO,EAAPA,OAAO;gBACPC,OAAO,EAAPA;cACF,CAAC,CAAC;YAAA;YAAA;cAAA,OAAA6C,QAAA,CAAAK,IAAA;UAAA;QAAA,GAAAT,OAAA;MAAA,CACH;MAAA,SAAAQ,oCAAAE,EAAA;QAAA,OAAAd,oCAAA,CAAA7E,KAAA,OAAAD,SAAA;MAAA;MAAA,OAAA0F,mCAAA;IAAA;IAED;AACF;AACA;AACA;AACA;AACA;AACA;IANE;EAAA;IAAA3D,GAAA;IAAAC,KAAA,EAQA,SAAA6D,yBAAgCpD,OAAY,EAAgB;MAC1D;MACA,OAAO,IAAI,CAACb,KAAK,CAACkE,kBAAkB,CAAC,IAAAC,wCAAgB,EAACtD,OAAO,CAAC,CAAC;IACjE;;IAEA;AACF;AACA;AACA;AACA;EAJE;IAAAV,GAAA;IAAAC,KAAA,EAKA,SAAAgE,uBAA8BC,gBAAwB,EAAW;MAC/D,OAAO,IAAI,CAAC9D,qBAAqB,CAAC6D,sBAAsB,CAACC,gBAAgB,CAAC;IAC5E;EAAC;EAAA,OAAAtF,OAAA;AAAA,EAxPmBuF,sBAAW;AAAA/G,MAAA,GAA3BwB,OAAO;AACX;AAAA,IAAAY,gBAAA,CAAA5B,OAAA,EADIgB,OAAO;AAAA,IAAAwF,QAAA,GAAAC,OAAA,CAAAzG,OAAA,GA2PEgB,OAAO"}
@@ -44,11 +44,20 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
44
44
  /**
45
45
  * Store precomputed latency value
46
46
  * @param key - key
47
- * @param value -value
47
+ * @param value - value
48
+ * @param overwrite - overwrite existing value or add it
48
49
  * @throws
49
50
  * @returns
50
51
  */
51
- saveLatency(key: PreComputedLatencies, value: number): void;
52
+ saveLatency(key: PreComputedLatencies, value: number, overwrite?: boolean): void;
53
+ /**
54
+ * Measure latency for a request
55
+ * @param key - key
56
+ * @param callback - callback for which you would like to measure latency
57
+ * @param overwrite - overwite existing value or add to it
58
+ * @returns
59
+ */
60
+ measureLatency(callback: () => Promise<any>, key: PreComputedLatencies, overwrite?: boolean): Promise<any>;
52
61
  /**
53
62
  * Store only the first timestamp value for the given key
54
63
  * @param key - key
@@ -80,6 +89,11 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
80
89
  * @returns - latency
81
90
  */
82
91
  getShowInterstitialTime(): number;
92
+ /**
93
+ * getU2CTime
94
+ * @returns - latency
95
+ */
96
+ getU2CTime(): number;
83
97
  /**
84
98
  * Device Register Time
85
99
  * @returns - latency
@@ -95,11 +109,6 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
95
109
  * @returns - latency
96
110
  */
97
111
  getJoinReqResp(): number;
98
- /**
99
- * Locus Join Response Sent Received
100
- * @returns - latency
101
- */
102
- getJoinRespSentReceived(): any;
103
112
  /**
104
113
  * Time taken to do turn discovery
105
114
  * @returns - latency
@@ -201,4 +210,9 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
201
210
  * Video setup delay transmit
202
211
  */
203
212
  getVideoJoinRespTxStart(): number;
213
+ /**
214
+ * Total latency for all other app api requests.
215
+ * Excludes meeting info, because it's measured separately.
216
+ */
217
+ getOtherAppApiReqResp(): number;
204
218
  }
@@ -87,18 +87,12 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
87
87
  browser?: string;
88
88
  browserVersion?: string;
89
89
  clientType?: "MEETING_CENTER" | "EVENT_CENTER" | "TRAINING_CENTER" | "TEAMS_CLIENT" | "TEAMS_DEVICE" | "TEAMS_SHARE" | "SIP" | "RECORDING" | "CLOUD_AWARE_SIP" | "TEAMS_WXC_CLIENT" | "WXC_CLIENT" | "WXC_DEVICE" | "WEBEX_JS_SDK" | "VOICEA_CLIENT" | "CISCO_SIP_GW" | "WEBEX_SDK" | "CPAAS_THIRD_PARTY_SDK" | "WXC_THIRD_PARTY" | "WXCC";
90
- subClientType?: "TEAMS_DEVICE" | "DESKTOP_APP" | "DESKTOP_APP_VDI" | "DEVICE_CURRENT" | "DEVICE_LEGACY_2020" | "HOLOGRAM_HEADSET_APP" | "HVDI_APP" | "MOBILE_APP" | "MOBILE_NETWORK" | "VDI_APP" | "WEB_APP";
91
- clientVersion?: string; /**
92
- * Returns the login type of the current user
93
- * @returns one of 'login-ci','unverified-guest', null
94
- */
90
+ subClientType?: "TEAMS_DEVICE" | "DESKTOP_APP" | "DESKTOP_APP_VDI" | "DEVICE_CURRENT" | "DEVICE_LEGACY_2020" | "HOLOGRAM_HEADSET_APP" | "HVDI_APP" | "MIXED" | "MOBILE_APP" | "MOBILE_NETWORK" | "PAGE" | "VDI_APP" | "WEB_APP";
91
+ clientVersion?: string;
95
92
  clientVersionStatus?: "CURRENT" | "LEGACY" | "UNSUPPORTED";
96
93
  localClientVersion?: string;
97
94
  modelNumber?: string;
98
- joinFirstUpdateLater?: "ep-enabled" | "sp-enabled" | "not-enabled"; /**
99
- * Returns if the meeting has converged architecture enabled
100
- * @param options.meetingId
101
- */
95
+ joinFirstUpdateLater?: "ep-enabled" | "sp-enabled" | "not-enabled";
102
96
  standbyUsed?: boolean;
103
97
  prefetchDocShowUsed?: boolean;
104
98
  fastJoinUsed?: boolean;
@@ -5,11 +5,11 @@ import '@webex/internal-plugin-device';
5
5
  import config from './config';
6
6
  import NewMetrics from './new-metrics';
7
7
  import * as Utils from './utils';
8
- import { ClientEvent, ClientEventLeaveReason, SubmitBehavioralEvent, SubmitClientEvent, SubmitInternalEvent, SubmitOperationalEvent, SubmitMQE } from './metrics.types';
8
+ import { ClientEvent, ClientEventLeaveReason, SubmitBehavioralEvent, SubmitClientEvent, SubmitInternalEvent, SubmitOperationalEvent, SubmitMQE, PreComputedLatencies } from './metrics.types';
9
9
  import * as CALL_DIAGNOSTIC_CONFIG from './call-diagnostic/config';
10
10
  import * as CallDiagnosticUtils from './call-diagnostic/call-diagnostic-metrics.util';
11
11
  import CallDiagnosticMetrics from './call-diagnostic/call-diagnostic-metrics';
12
12
  import CallDiagnosticLatencies from './call-diagnostic/call-diagnostic-metrics-latencies';
13
13
  export { default, getOSNameInternal } from './metrics';
14
14
  export { config, CALL_DIAGNOSTIC_CONFIG, NewMetrics, Utils, CallDiagnosticUtils, CallDiagnosticLatencies, CallDiagnosticMetrics, };
15
- export type { ClientEvent, ClientEventLeaveReason, SubmitBehavioralEvent, SubmitClientEvent, SubmitInternalEvent, SubmitMQE, SubmitOperationalEvent, };
15
+ export type { ClientEvent, ClientEventLeaveReason, SubmitBehavioralEvent, SubmitClientEvent, SubmitInternalEvent, SubmitMQE, SubmitOperationalEvent, PreComputedLatencies, };
@@ -102,4 +102,4 @@ export type BuildClientEventFetchRequestOptions = (args: {
102
102
  payload?: RecursivePartial<ClientEvent['payload']>;
103
103
  options?: SubmitClientEventOptions;
104
104
  }) => Promise<any>;
105
- export type PreComputedLatencies = 'internal.client.pageJMT' | 'internal.download.time' | 'internal.click.to.interstitial' | 'internal.call.init.join.req';
105
+ export type PreComputedLatencies = 'internal.client.pageJMT' | 'internal.download.time' | 'internal.click.to.interstitial' | 'internal.get.u2c.time' | 'internal.call.init.join.req' | 'internal.other.app.api.time';
package/package.json CHANGED
@@ -26,23 +26,23 @@
26
26
  "@webex/eslint-config-legacy": "0.0.0",
27
27
  "@webex/jest-config-legacy": "0.0.0",
28
28
  "@webex/legacy-tools": "0.0.0",
29
- "@webex/test-helper-chai": "3.0.0-next.3",
30
- "@webex/test-helper-mocha": "3.0.0-next.3",
31
- "@webex/test-helper-mock-webex": "3.0.0-next.3",
32
- "@webex/test-helper-test-users": "3.0.0-next.3",
29
+ "@webex/test-helper-chai": "3.0.0-next.5",
30
+ "@webex/test-helper-mocha": "3.0.0-next.5",
31
+ "@webex/test-helper-mock-webex": "3.0.0-next.5",
32
+ "@webex/test-helper-test-users": "3.0.0-next.5",
33
33
  "eslint": "^8.24.0",
34
34
  "prettier": "^2.7.1",
35
35
  "sinon": "^9.2.4"
36
36
  },
37
37
  "dependencies": {
38
- "@webex/common": "3.0.0-next.3",
39
- "@webex/common-timers": "3.0.0-next.3",
40
- "@webex/event-dictionary-ts": "^1.0.1329",
41
- "@webex/internal-plugin-device": "3.0.0-next.3",
42
- "@webex/internal-plugin-metrics": "3.0.0-next.3",
43
- "@webex/test-helper-chai": "3.0.0-next.3",
44
- "@webex/test-helper-mock-webex": "3.0.0-next.3",
45
- "@webex/webex-core": "3.0.0-next.3",
38
+ "@webex/common": "3.0.0-next.5",
39
+ "@webex/common-timers": "3.0.0-next.5",
40
+ "@webex/event-dictionary-ts": "^1.0.1387",
41
+ "@webex/internal-plugin-device": "3.0.0-next.5",
42
+ "@webex/internal-plugin-metrics": "3.0.0-next.5",
43
+ "@webex/test-helper-chai": "3.0.0-next.5",
44
+ "@webex/test-helper-mock-webex": "3.0.0-next.5",
45
+ "@webex/webex-core": "3.0.0-next.5",
46
46
  "ip-anonymize": "^0.1.0",
47
47
  "lodash": "^4.17.21",
48
48
  "uuid": "^3.3.2"
@@ -55,5 +55,5 @@
55
55
  "test:style": "eslint ./src/**/*.*",
56
56
  "test:unit": "webex-legacy-tools test --unit --runner mocha"
57
57
  },
58
- "version": "3.0.0-next.3"
58
+ "version": "3.0.0-next.5"
59
59
  }
@@ -92,12 +92,33 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
92
92
  /**
93
93
  * Store precomputed latency value
94
94
  * @param key - key
95
- * @param value -value
95
+ * @param value - value
96
+ * @param overwrite - overwrite existing value or add it
96
97
  * @throws
97
98
  * @returns
98
99
  */
99
- public saveLatency(key: PreComputedLatencies, value: number) {
100
- this.precomputedLatencies.set(key, value);
100
+ public saveLatency(key: PreComputedLatencies, value: number, overwrite = true) {
101
+ const existingValue = overwrite ? 0 : this.precomputedLatencies.get(key) || 0;
102
+ this.precomputedLatencies.set(key, value + existingValue);
103
+ }
104
+
105
+ /**
106
+ * Measure latency for a request
107
+ * @param key - key
108
+ * @param callback - callback for which you would like to measure latency
109
+ * @param overwrite - overwite existing value or add to it
110
+ * @returns
111
+ */
112
+ public measureLatency(
113
+ callback: () => Promise<any>,
114
+ key: PreComputedLatencies,
115
+ overwrite = false
116
+ ) {
117
+ const start = performance.now();
118
+
119
+ return callback().finally(() => {
120
+ this.saveLatency(key, performance.now() - start, overwrite);
121
+ });
101
122
  }
102
123
 
103
124
  /**
@@ -158,6 +179,16 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
158
179
  );
159
180
  }
160
181
 
182
+ /**
183
+ * getU2CTime
184
+ * @returns - latency
185
+ */
186
+ public getU2CTime() {
187
+ const u2cLatency = this.precomputedLatencies.get('internal.get.u2c.time');
188
+
189
+ return u2cLatency ? Math.floor(u2cLatency) : undefined;
190
+ }
191
+
161
192
  /**
162
193
  * Device Register Time
163
194
  * @returns - latency
@@ -188,15 +219,6 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
188
219
  return this.getDiffBetweenTimestamps('client.locus.join.request', 'client.locus.join.response');
189
220
  }
190
221
 
191
- /**
192
- * Locus Join Response Sent Received
193
- * @returns - latency
194
- */
195
- public getJoinRespSentReceived() {
196
- // TODO: not clear SPARK-440554
197
- return undefined;
198
- }
199
-
200
222
  /**
201
223
  * Time taken to do turn discovery
202
224
  * @returns - latency
@@ -432,4 +454,14 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
432
454
  public getVideoJoinRespTxStart() {
433
455
  return this.getDiffBetweenTimestamps('client.locus.join.response', 'client.media.tx.start');
434
456
  }
457
+
458
+ /**
459
+ * Total latency for all other app api requests.
460
+ * Excludes meeting info, because it's measured separately.
461
+ */
462
+ public getOtherAppApiReqResp() {
463
+ const otherAppApiJMT = this.precomputedLatencies.get('internal.other.app.api.time');
464
+
465
+ return otherAppApiJMT > 0 ? Math.floor(otherAppApiJMT) : undefined;
466
+ }
435
467
  }
@@ -293,11 +293,17 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
293
293
  if (this.webex.internal) {
294
294
  // @ts-ignore
295
295
  const {device} = this.webex.internal;
296
+ const {installationId} = device.config || {};
297
+
296
298
  identifiers.userId = device.userId || preLoginId;
297
299
  identifiers.deviceId = device.url;
298
300
  identifiers.orgId = device.orgId;
299
301
  // @ts-ignore
300
302
  identifiers.locusUrl = this.webex.internal.services.get('locus');
303
+
304
+ if (installationId) {
305
+ identifiers.machineId = installationId;
306
+ }
301
307
  }
302
308
 
303
309
  if (meeting?.locusInfo?.fullState) {
@@ -244,6 +244,9 @@ export const prepareDiagnosticMetricItem = (webex: any, item: any) => {
244
244
  case 'client.webexapp.launched':
245
245
  joinTimes.downloadTime = cdl.getDownloadTimeJMT();
246
246
  break;
247
+ case 'client.login.end':
248
+ joinTimes.otherAppApiReqResp = cdl.getOtherAppApiReqResp();
249
+ break;
247
250
  case 'client.interstitial-window.launched':
248
251
  joinTimes.meetingInfoReqResp = cdl.getMeetingInfoReqResp();
249
252
  joinTimes.clickToInterstitial = cdl.getClickToInterstitial();
@@ -253,13 +256,13 @@ export const prepareDiagnosticMetricItem = (webex: any, item: any) => {
253
256
  joinTimes.meetingInfoReqResp = cdl.getMeetingInfoReqResp();
254
257
  joinTimes.showInterstitialTime = cdl.getShowInterstitialTime();
255
258
  joinTimes.registerWDMDeviceJMT = cdl.getRegisterWDMDeviceJMT();
259
+ joinTimes.getU2CTime = cdl.getU2CTime();
256
260
  break;
257
261
 
258
262
  case 'client.locus.join.response':
259
263
  joinTimes.meetingInfoReqResp = cdl.getMeetingInfoReqResp();
260
264
  joinTimes.callInitJoinReq = cdl.getCallInitJoinReq();
261
265
  joinTimes.joinReqResp = cdl.getJoinReqResp();
262
- joinTimes.joinReqSentReceived = cdl.getJoinRespSentReceived();
263
266
  joinTimes.pageJmt = cdl.getPageJMT();
264
267
  joinTimes.clickToInterstitial = cdl.getClickToInterstitial();
265
268
  joinTimes.interstitialToJoinOK = cdl.getInterstitialToJoinOK();
package/src/index.ts CHANGED
@@ -18,6 +18,7 @@ import {
18
18
  SubmitInternalEvent,
19
19
  SubmitOperationalEvent,
20
20
  SubmitMQE,
21
+ PreComputedLatencies,
21
22
  } from './metrics.types';
22
23
  import * as CALL_DIAGNOSTIC_CONFIG from './call-diagnostic/config';
23
24
  import * as CallDiagnosticUtils from './call-diagnostic/call-diagnostic-metrics.util';
@@ -51,4 +52,5 @@ export type {
51
52
  SubmitInternalEvent,
52
53
  SubmitMQE,
53
54
  SubmitOperationalEvent,
55
+ PreComputedLatencies,
54
56
  };
@@ -165,4 +165,6 @@ export type PreComputedLatencies =
165
165
  | 'internal.client.pageJMT'
166
166
  | 'internal.download.time'
167
167
  | 'internal.click.to.interstitial'
168
- | 'internal.call.init.join.req';
168
+ | 'internal.get.u2c.time'
169
+ | 'internal.call.init.join.req'
170
+ | 'internal.other.app.api.time';
@@ -43,6 +43,8 @@ class Metrics extends WebexPlugin {
43
43
  constructor(...args) {
44
44
  super(...args);
45
45
 
46
+ // @ts-ignore
47
+ this.callDiagnosticLatencies = new CallDiagnosticLatencies({}, {parent: this.webex});
46
48
  this.onReady();
47
49
  }
48
50
 
@@ -54,8 +56,6 @@ class Metrics extends WebexPlugin {
54
56
  this.webex.once('ready', () => {
55
57
  // @ts-ignore
56
58
  this.callDiagnosticMetrics = new CallDiagnosticMetrics({}, {parent: this.webex});
57
- // @ts-ignore
58
- this.callDiagnosticLatencies = new CallDiagnosticLatencies({}, {parent: this.webex});
59
59
  });
60
60
  }
61
61
 
@@ -131,6 +131,9 @@ describe('plugin-metrics', () => {
131
131
  webex.internal.newMetrics.callDiagnosticLatencies.getDiffBetweenTimestamps = sinon
132
132
  .stub()
133
133
  .returns(10);
134
+ webex.internal.newMetrics.callDiagnosticLatencies.getU2CTime = sinon
135
+ .stub()
136
+ .returns(20);
134
137
  const promise = webex.internal.newMetrics.callDiagnosticMetrics.submitToCallDiagnostics(
135
138
  //@ts-ignore
136
139
  {event: {name: 'client.call.initiated'}}
@@ -147,6 +150,7 @@ describe('plugin-metrics', () => {
147
150
  meetingInfoReqResp: 10,
148
151
  registerWDMDeviceJMT: 10,
149
152
  showInterstitialTime: 10,
153
+ getU2CTime: 20
150
154
  },
151
155
  });
152
156
  assert.lengthOf(
@@ -159,9 +163,6 @@ describe('plugin-metrics', () => {
159
163
  webex.internal.newMetrics.callDiagnosticLatencies.getDiffBetweenTimestamps = sinon
160
164
  .stub()
161
165
  .returns(10);
162
- webex.internal.newMetrics.callDiagnosticLatencies.getJoinRespSentReceived = sinon
163
- .stub()
164
- .returns(20);
165
166
  webex.internal.newMetrics.callDiagnosticLatencies.getPageJMT = sinon.stub().returns(30);
166
167
  webex.internal.newMetrics.callDiagnosticLatencies.getClientJMT = sinon.stub().returns(5);
167
168
  webex.internal.newMetrics.callDiagnosticLatencies.getClickToInterstitial = sinon
@@ -191,7 +192,6 @@ describe('plugin-metrics', () => {
191
192
  clickToInterstitial: 10,
192
193
  interstitialToJoinOK: 10,
193
194
  joinReqResp: 10,
194
- joinReqSentReceived: 20,
195
195
  meetingInfoReqResp: 10,
196
196
  pageJmt: 30,
197
197
  totalJmt: 20,
@@ -41,11 +41,41 @@ describe('internal-plugin-metrics', () => {
41
41
  assert.deepEqual(cdl.latencyTimestamps.get('client.alert.displayed'), now.getTime());
42
42
  });
43
43
 
44
- it('should save latency correctly', () => {
44
+ it('should save latency correctly by default and overwrites', () => {
45
45
  assert.deepEqual(cdl.precomputedLatencies.size, 0);
46
46
  cdl.saveLatency('internal.client.pageJMT', 10);
47
47
  assert.deepEqual(cdl.precomputedLatencies.size, 1);
48
48
  assert.deepEqual(cdl.precomputedLatencies.get('internal.client.pageJMT'), 10);
49
+ cdl.saveLatency('internal.client.pageJMT', 20);
50
+ assert.deepEqual(cdl.precomputedLatencies.size, 1);
51
+ assert.deepEqual(cdl.precomputedLatencies.get('internal.client.pageJMT'), 20);
52
+ });
53
+
54
+ it('should overwrite latency when overwrite is true', () => {
55
+ assert.deepEqual(cdl.precomputedLatencies.size, 0);
56
+ cdl.saveLatency('internal.client.pageJMT', 10, true);
57
+ assert.deepEqual(cdl.precomputedLatencies.size, 1);
58
+ assert.deepEqual(cdl.precomputedLatencies.get('internal.client.pageJMT'), 10);
59
+ cdl.saveLatency('internal.client.pageJMT', 20, true);
60
+ assert.deepEqual(cdl.precomputedLatencies.size, 1);
61
+ assert.deepEqual(cdl.precomputedLatencies.get('internal.client.pageJMT'), 20);
62
+ });
63
+
64
+ it('should save latency correctly when overwrite is false', () => {
65
+ assert.deepEqual(cdl.precomputedLatencies.size, 0);
66
+ cdl.saveLatency('internal.client.pageJMT', 10, false);
67
+ assert.deepEqual(cdl.precomputedLatencies.size, 1);
68
+ assert.deepEqual(cdl.precomputedLatencies.get('internal.client.pageJMT'), 10);
69
+ });
70
+
71
+ it('should save latency correctly when overwrite is false and there is existing value', () => {
72
+ assert.deepEqual(cdl.precomputedLatencies.size, 0);
73
+ cdl.saveLatency('internal.client.pageJMT', 10);
74
+ assert.deepEqual(cdl.precomputedLatencies.size, 1);
75
+ assert.deepEqual(cdl.precomputedLatencies.get('internal.client.pageJMT'), 10);
76
+ cdl.saveLatency('internal.client.pageJMT', 10, false);
77
+ assert.deepEqual(cdl.precomputedLatencies.size, 1);
78
+ assert.deepEqual(cdl.precomputedLatencies.get('internal.client.pageJMT'), 20);
49
79
  });
50
80
 
51
81
  it('should save only first timestamp correctly', () => {
@@ -111,6 +141,71 @@ describe('internal-plugin-metrics', () => {
111
141
  assert.deepEqual(cdl.getMeetingInfoReqResp(), 10);
112
142
  });
113
143
 
144
+ describe('measureLatency', () => {
145
+ let clock;
146
+ let saveLatencySpy;
147
+
148
+ beforeEach(() => {
149
+ clock = sinon.useFakeTimers();
150
+
151
+ saveLatencySpy = sinon.stub(cdl, 'saveLatency');
152
+ });
153
+
154
+ afterEach(() => {
155
+ clock.restore();
156
+ sinon.restore();
157
+ });
158
+
159
+ it('checks measureLatency with overwrite false', async () => {
160
+ const key = 'internal.client.pageJMT';
161
+ const overwrite = false;
162
+ const callbackStub = sinon.stub().callsFake(() => {
163
+ clock.tick(50);
164
+ return Promise.resolve('test');
165
+ });
166
+
167
+ const promise = cdl.measureLatency(callbackStub, 'internal.client.pageJMT', overwrite);
168
+
169
+ const resolvedValue = await promise;
170
+ assert.deepEqual(resolvedValue, 'test');
171
+ assert.calledOnceWithExactly(callbackStub);
172
+ assert.calledOnceWithExactly(saveLatencySpy, key, 50, overwrite)
173
+ });
174
+
175
+ it('checks measureLatency with overwrite true', async () => {
176
+ const key = 'internal.download.time';
177
+ const overwrite = true;
178
+ const callbackStub = sinon.stub().callsFake(() => {
179
+ clock.tick(20);
180
+ return Promise.resolve('test123');
181
+ });
182
+
183
+ const promise = cdl.measureLatency(callbackStub, 'internal.download.time', overwrite);
184
+
185
+ const resolvedValue = await promise;
186
+ assert.deepEqual(resolvedValue, 'test123');
187
+ assert.calledOnceWithExactly(callbackStub);
188
+ assert.calledOnceWithExactly(saveLatencySpy, key, 20, overwrite)
189
+ });
190
+
191
+ it('checks measureLatency when callBack rejects', async () => {
192
+ const key = 'internal.client.pageJMT';
193
+ const overwrite = true;
194
+ const error = new Error('some error');
195
+ const callbackStub = sinon.stub().callsFake(() => {
196
+ clock.tick(50);
197
+ return Promise.reject(error);
198
+ });
199
+
200
+ const promise = cdl.measureLatency(callbackStub, 'internal.client.pageJMT', overwrite);
201
+
202
+ const rejectedValue = await assert.isRejected(promise);
203
+ assert.deepEqual(rejectedValue, error);
204
+ assert.calledOnceWithExactly(callbackStub);
205
+ assert.calledOnceWithExactly(saveLatencySpy, key, 50, overwrite)
206
+ });
207
+ });
208
+
114
209
  describe('saveTimestamp', () => {
115
210
  afterEach(() => {
116
211
  sinon.restore();
@@ -512,9 +607,51 @@ describe('internal-plugin-metrics', () => {
512
607
  assert.deepEqual(cdl.getInterstitialToMediaOKJMT(), 10);
513
608
  });
514
609
 
610
+ it('calculates getU2CTime correctly', () => {
611
+ it('returns undefined when no precomputed value available', () => {
612
+ assert.deepEqual(cdl.getU2CTime(), undefined);
613
+ });
614
+
615
+ it('returns the correct value', () => {
616
+ cdl.saveLatency('internal.get.u2c.time', 123);
617
+
618
+ assert.deepEqual(cdl.getU2CTime(), 123);
619
+ });
620
+
621
+ it('returns the correct whole number', () => {
622
+ cdl.saveLatency('internal.get.u2c.time', 321.44);
623
+
624
+ assert.deepEqual(cdl.getU2CTime(), 321);
625
+ });
626
+ });
627
+
515
628
  it('calculates getDownloadTimeJMT correctly', () => {
516
629
  cdl.saveLatency('internal.download.time', 1000);
517
630
  assert.deepEqual(cdl.getDownloadTimeJMT(), 1000);
518
631
  });
632
+
633
+ describe('getOtherAppApiReqResp', () => {
634
+ it('returns undefined when no precomputed value available', () => {
635
+ assert.deepEqual(cdl.getOtherAppApiReqResp(), undefined);
636
+ });
637
+
638
+ it('returns undefined if it is less than 0', () => {
639
+ cdl.saveLatency('internal.other.app.api.time', 0);
640
+
641
+ assert.deepEqual(cdl.getOtherAppApiReqResp(), undefined);
642
+ });
643
+
644
+ it('returns the correct value', () => {
645
+ cdl.saveLatency('internal.other.app.api.time', 123);
646
+
647
+ assert.deepEqual(cdl.getOtherAppApiReqResp(), 123);
648
+ });
649
+
650
+ it('returns the correct whole number', () => {
651
+ cdl.saveLatency('internal.other.app.api.time', 321.44);
652
+
653
+ assert.deepEqual(cdl.getOtherAppApiReqResp(), 321);
654
+ });
655
+ });
519
656
  });
520
657
  });
@@ -302,6 +302,11 @@ describe('internal-plugin-metrics', () => {
302
302
 
303
303
  describe('#getIdentifiers', () => {
304
304
  it('should build identifiers correctly', () => {
305
+ webex.internal.device = {
306
+ ...webex.internal.device,
307
+ config: {installationId: 'installationId'},
308
+ };
309
+
305
310
  const res = cd.getIdentifiers({
306
311
  mediaConnections: [
307
312
  {mediaAgentAlias: 'mediaAgentAlias', mediaAgentGroupId: 'mediaAgentGroupId'},
@@ -315,6 +320,7 @@ describe('internal-plugin-metrics', () => {
315
320
  locusId: 'url',
316
321
  locusStartTime: 'lastActive',
317
322
  locusUrl: 'locus/url',
323
+ machineId: 'installationId',
318
324
  mediaAgentAlias: 'mediaAgentAlias',
319
325
  mediaAgentGroupId: 'mediaAgentGroupId',
320
326
  orgId: 'orgId',
@@ -301,6 +301,11 @@ describe('internal-plugin-metrics', () => {
301
301
 
302
302
  [
303
303
  ['client.exit.app', {}],
304
+ ['client.login.end', {
305
+ joinTimes: {
306
+ otherAppApiReqResp: undefined,
307
+ }
308
+ }],
304
309
  ['client.webexapp.launched', {
305
310
  joinTimes: {
306
311
  downloadTime: undefined,
@@ -322,6 +327,7 @@ describe('internal-plugin-metrics', () => {
322
327
  showInterstitialTime: undefined,
323
328
  meetingInfoReqResp: undefined,
324
329
  registerWDMDeviceJMT: undefined,
330
+ getU2CTime: undefined
325
331
  },
326
332
  },
327
333
  ],
@@ -332,7 +338,6 @@ describe('internal-plugin-metrics', () => {
332
338
  meetingInfoReqResp: undefined,
333
339
  callInitJoinReq: undefined,
334
340
  joinReqResp: undefined,
335
- joinReqSentReceived: undefined,
336
341
  pageJmt: undefined,
337
342
  clickToInterstitial: undefined,
338
343
  interstitialToJoinOK: undefined,