@webex/internal-plugin-metrics 3.12.0-next.5 → 3.12.0-next.51
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/README.md +274 -0
- package/dist/automated-user.js +19 -0
- package/dist/automated-user.js.map +1 -0
- package/dist/batcher.js +3 -0
- package/dist/batcher.js.map +1 -1
- package/dist/call-diagnostic/call-diagnostic-metrics-latencies.js +635 -62
- package/dist/call-diagnostic/call-diagnostic-metrics-latencies.js.map +1 -1
- package/dist/call-diagnostic/call-diagnostic-metrics.js +188 -78
- package/dist/call-diagnostic/call-diagnostic-metrics.js.map +1 -1
- package/dist/call-diagnostic/call-diagnostic-metrics.util.js +5 -0
- package/dist/call-diagnostic/call-diagnostic-metrics.util.js.map +1 -1
- package/dist/call-diagnostic/config.js +16 -3
- package/dist/call-diagnostic/config.js.map +1 -1
- package/dist/config.js +8 -0
- package/dist/config.js.map +1 -1
- package/dist/index.js +25 -1
- package/dist/index.js.map +1 -1
- package/dist/metrics.js +118 -5
- package/dist/metrics.js.map +1 -1
- package/dist/metrics.types.js +4 -0
- package/dist/metrics.types.js.map +1 -1
- package/dist/network-telemetry.js +610 -0
- package/dist/network-telemetry.js.map +1 -0
- package/dist/new-metrics.js +63 -17
- package/dist/new-metrics.js.map +1 -1
- package/dist/privacy-and-security-permission-enricher/constants.js +18 -0
- package/dist/privacy-and-security-permission-enricher/constants.js.map +1 -0
- package/dist/privacy-and-security-permission-enricher/index.js +143 -0
- package/dist/privacy-and-security-permission-enricher/index.js.map +1 -0
- package/dist/privacy-and-security-permission-enricher/types.js +7 -0
- package/dist/privacy-and-security-permission-enricher/types.js.map +1 -0
- package/dist/privacy-and-security-permission-enricher/utils.js +71 -0
- package/dist/privacy-and-security-permission-enricher/utils.js.map +1 -0
- package/dist/types/automated-user.d.ts +2 -0
- package/dist/types/call-diagnostic/call-diagnostic-metrics-latencies.d.ts +208 -5
- package/dist/types/call-diagnostic/call-diagnostic-metrics.d.ts +73 -14
- package/dist/types/call-diagnostic/config.d.ts +4 -0
- package/dist/types/config.d.ts +9 -0
- package/dist/types/index.d.ts +5 -3
- package/dist/types/metrics.types.d.ts +7 -2
- package/dist/types/network-telemetry.d.ts +108 -0
- package/dist/types/new-metrics.d.ts +17 -1
- package/dist/types/privacy-and-security-permission-enricher/constants.d.ts +6 -0
- package/dist/types/privacy-and-security-permission-enricher/index.d.ts +40 -0
- package/dist/types/privacy-and-security-permission-enricher/types.d.ts +14 -0
- package/dist/types/privacy-and-security-permission-enricher/utils.d.ts +5 -0
- package/dist/types/unhandled-exception-telemetry/index.d.ts +60 -0
- package/dist/types/unhandled-exception-telemetry/utils.d.ts +6 -0
- package/dist/unhandled-exception-telemetry/index.js +330 -0
- package/dist/unhandled-exception-telemetry/index.js.map +1 -0
- package/dist/unhandled-exception-telemetry/utils.js +105 -0
- package/dist/unhandled-exception-telemetry/utils.js.map +1 -0
- package/package.json +12 -11
- package/src/automated-user.ts +16 -0
- package/src/batcher.js +4 -0
- package/src/call-diagnostic/call-diagnostic-metrics-latencies.ts +781 -71
- package/src/call-diagnostic/call-diagnostic-metrics.ts +119 -16
- package/src/call-diagnostic/call-diagnostic-metrics.util.ts +5 -0
- package/src/call-diagnostic/config.ts +14 -0
- package/src/config.js +8 -0
- package/src/index.ts +16 -0
- package/src/metrics.js +123 -5
- package/src/metrics.types.ts +25 -3
- package/src/network-telemetry.ts +757 -0
- package/src/new-metrics.ts +56 -6
- package/src/privacy-and-security-permission-enricher/constants.ts +33 -0
- package/src/privacy-and-security-permission-enricher/index.ts +142 -0
- package/src/privacy-and-security-permission-enricher/types.ts +21 -0
- package/src/privacy-and-security-permission-enricher/utils.ts +82 -0
- package/src/unhandled-exception-telemetry/index.ts +403 -0
- package/src/unhandled-exception-telemetry/utils.ts +101 -0
- package/test/unit/spec/automated-user.ts +43 -0
- package/test/unit/spec/batcher.js +43 -0
- package/test/unit/spec/call-diagnostic/call-diagnostic-metrics-batcher.ts +14 -2
- package/test/unit/spec/call-diagnostic/call-diagnostic-metrics-latencies.ts +1424 -293
- package/test/unit/spec/call-diagnostic/call-diagnostic-metrics.ts +906 -159
- package/test/unit/spec/call-diagnostic/call-diagnostic-metrics.util.ts +27 -0
- package/test/unit/spec/metrics.js +14 -5
- package/test/unit/spec/network-telemetry.ts +610 -0
- package/test/unit/spec/new-metrics.ts +203 -50
- package/test/unit/spec/prelogin-metrics-batcher.ts +71 -36
- package/test/unit/spec/privacy-and-security-permission-enricher.ts +318 -0
- package/test/unit/spec/unhandled-exception-telemetry/utils.ts +109 -0
- package/test/unit/spec/unhandled-exception-telemetry.ts +688 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_constants","require","_utils","ownKeys","e","r","t","_Object$keys","_Object$getOwnPropertySymbols","o","filter","_Object$getOwnPropertyDescriptor","enumerable","push","apply","_objectSpread","arguments","length","Object","forEach","_defineProperty2","default","_Object$getOwnPropertyDescriptors","_Object$defineProperties","_Object$defineProperty","PERMISSION_ENRICHMENT_RULES","exports","events","CAMERA_AND_MICROPHONE_PERMISSION_EVENTS","resolve","resources","terminal","MEDIA_TX_PERMISSION_EVENTS","payload","resolveMediaResources","CONTENT_SHARE_PERMISSION_EVENTS","resolveContentShareResources","FINAL_PERMISSION_EVENTS","resolvePermissionEnrichmentPolicy","name","_PERMISSION_ENRICHMEN","_PERMISSION_ENRICHMEN2","find","_ref","has","NO_PERMISSION_ENRICHMENT","PrivacyAndSecurityPermissionEnricher","onEnrichmentError","_classCallCheck2","_map","_createClass2","key","value","setPermission","permission","projectPrivacyAndSecurityPermission","enrich","_ref2","scope","policy","_this$lastReported$ge","privacyAndSecurityPermission","undefined","lastReported","set","get","projectedPermission","changedPermission","getChangedPermission","error","delete"],"sources":["index.ts"],"sourcesContent":["import type {ClientEventPayload, PrivacyAndSecurityPermission} from '../metrics.types';\nimport {\n CAMERA_AND_MICROPHONE_PERMISSION_EVENTS,\n CONTENT_SHARE_PERMISSION_EVENTS,\n FINAL_PERMISSION_EVENTS,\n MEDIA_TX_PERMISSION_EVENTS,\n NO_PERMISSION_ENRICHMENT,\n} from './constants';\nimport type {\n PermissionEnrichmentContext,\n PermissionEnrichmentPolicy,\n PermissionEnrichmentRule,\n} from './types';\nimport {\n getChangedPermission,\n projectPrivacyAndSecurityPermission,\n resolveContentShareResources,\n resolveMediaResources,\n} from './utils';\n\nexport const PERMISSION_ENRICHMENT_RULES = [\n {\n events: CAMERA_AND_MICROPHONE_PERMISSION_EVENTS,\n resolve: () => ({resources: ['camera', 'microphone'], terminal: false}),\n },\n {\n events: MEDIA_TX_PERMISSION_EVENTS,\n resolve: (payload) => ({resources: resolveMediaResources(payload), terminal: false}),\n },\n {\n events: CONTENT_SHARE_PERMISSION_EVENTS,\n resolve: (payload) => ({\n resources: resolveContentShareResources(payload),\n terminal: false,\n }),\n },\n {\n events: FINAL_PERMISSION_EVENTS,\n resolve: () => ({resources: ['camera', 'microphone', 'contentShare'], terminal: true}),\n },\n] satisfies readonly PermissionEnrichmentRule[];\n\nconst resolvePermissionEnrichmentPolicy = (\n name: PermissionEnrichmentContext['name'],\n payload?: ClientEventPayload\n): PermissionEnrichmentPolicy =>\n PERMISSION_ENRICHMENT_RULES.find(({events}) => events.has(name))?.resolve(payload) ??\n NO_PERMISSION_ENRICHMENT;\n\n/**\n * Enriches eligible client events with relevant browser permission changes.\n */\nexport default class PrivacyAndSecurityPermissionEnricher {\n private permission?: PrivacyAndSecurityPermission;\n\n private lastReported = new Map<string, PrivacyAndSecurityPermission>();\n\n private readonly onEnrichmentError: (error: unknown) => void;\n\n /**\n * Creates a permission enricher.\n * @param {Function} onEnrichmentError permission enrichment error handler\n */\n constructor(onEnrichmentError: (error: unknown) => void) {\n this.onEnrichmentError = onEnrichmentError;\n }\n\n /**\n * Stores the latest normalized browser permission state.\n * @param {PrivacyAndSecurityPermission} permission permission snapshot\n * @returns {void}\n */\n public setPermission(permission: PrivacyAndSecurityPermission): void {\n this.permission = projectPrivacyAndSecurityPermission(permission, [\n 'camera',\n 'microphone',\n 'contentShare',\n ]);\n }\n\n /**\n * Returns the original payload or a copy enriched with relevant permission changes.\n * @param {PermissionEnrichmentContext} context event context and permission history scope\n * @returns {ClientEventPayload | undefined}\n */\n public enrich({\n name,\n payload,\n scope,\n }: PermissionEnrichmentContext): ClientEventPayload | undefined {\n const policy = resolvePermissionEnrichmentPolicy(name, payload);\n\n try {\n if (payload?.privacyAndSecurityPermission !== undefined) {\n // An explicitly supplied permission payload is authoritative for this event.\n if (!policy.terminal) {\n this.lastReported.set(scope, {\n ...this.lastReported.get(scope),\n ...(payload.privacyAndSecurityPermission as PrivacyAndSecurityPermission),\n });\n }\n\n return payload;\n }\n\n if (policy.resources.length === 0) {\n return payload;\n }\n\n const projectedPermission = this.permission\n ? projectPrivacyAndSecurityPermission(this.permission, policy.resources)\n : undefined;\n\n if (!projectedPermission) {\n return payload;\n }\n\n if (policy.terminal) {\n return {...payload, privacyAndSecurityPermission: projectedPermission};\n }\n\n const lastReported = this.lastReported.get(scope) ?? {};\n const changedPermission = getChangedPermission(projectedPermission, lastReported);\n\n if (!changedPermission) {\n return payload;\n }\n\n this.lastReported.set(scope, {...lastReported, ...changedPermission});\n\n return {...payload, privacyAndSecurityPermission: changedPermission};\n } catch (error) {\n this.onEnrichmentError(error);\n\n return payload;\n } finally {\n if (policy.terminal) {\n this.lastReported.delete(scope);\n }\n }\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":[],"sources":["types.ts"],"sourcesContent":["import type {\n ClientEvent,\n ClientEventPayload,\n PrivacyAndSecurityPermissionResource,\n} from '../metrics.types';\n\nexport type PermissionEnrichmentPolicy = {\n resources: readonly PrivacyAndSecurityPermissionResource[];\n terminal: boolean;\n};\n\nexport type PermissionEnrichmentRule = {\n events: ReadonlySet<ClientEvent['name']>;\n resolve: (payload?: ClientEventPayload) => PermissionEnrichmentPolicy;\n};\n\nexport type PermissionEnrichmentContext = {\n name: ClientEvent['name'];\n payload?: ClientEventPayload;\n scope: string;\n};\n"],"mappings":"","ignoreList":[]}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _Object$keys2 = require("@babel/runtime-corejs2/core-js/object/keys");
|
|
4
|
+
var _Object$getOwnPropertySymbols = require("@babel/runtime-corejs2/core-js/object/get-own-property-symbols");
|
|
5
|
+
var _Object$getOwnPropertyDescriptor = require("@babel/runtime-corejs2/core-js/object/get-own-property-descriptor");
|
|
6
|
+
var _Object$getOwnPropertyDescriptors = require("@babel/runtime-corejs2/core-js/object/get-own-property-descriptors");
|
|
7
|
+
var _Object$defineProperties = require("@babel/runtime-corejs2/core-js/object/define-properties");
|
|
8
|
+
var _Object$defineProperty = require("@babel/runtime-corejs2/core-js/object/define-property");
|
|
9
|
+
var _interopRequireDefault = require("@babel/runtime-corejs2/helpers/interopRequireDefault");
|
|
10
|
+
_Object$defineProperty(exports, "__esModule", {
|
|
11
|
+
value: true
|
|
12
|
+
});
|
|
13
|
+
exports.resolveMediaResources = exports.resolveContentShareResources = exports.projectPrivacyAndSecurityPermission = exports.getChangedPermission = void 0;
|
|
14
|
+
var _keys = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/object/keys"));
|
|
15
|
+
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/defineProperty"));
|
|
16
|
+
var _lodash = require("lodash");
|
|
17
|
+
function ownKeys(e, r) { var t = _Object$keys2(e); if (_Object$getOwnPropertySymbols) { var o = _Object$getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return _Object$getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
18
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : _Object$getOwnPropertyDescriptors ? _Object$defineProperties(e, _Object$getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { _Object$defineProperty(e, r, _Object$getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
19
|
+
var resolveMediaResources = exports.resolveMediaResources = function resolveMediaResources(payload) {
|
|
20
|
+
switch (payload === null || payload === void 0 ? void 0 : payload.mediaType) {
|
|
21
|
+
case 'audio':
|
|
22
|
+
return ['microphone'];
|
|
23
|
+
case 'video':
|
|
24
|
+
return ['camera'];
|
|
25
|
+
case 'share':
|
|
26
|
+
return ['contentShare'];
|
|
27
|
+
default:
|
|
28
|
+
return [];
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
var resolveContentShareResources = exports.resolveContentShareResources = function resolveContentShareResources(payload) {
|
|
32
|
+
if ((payload === null || payload === void 0 ? void 0 : payload.mediaType) !== 'share') {
|
|
33
|
+
return [];
|
|
34
|
+
}
|
|
35
|
+
return ['contentShare'];
|
|
36
|
+
};
|
|
37
|
+
var copyPermissionState = function copyPermissionState(source, target, resource) {
|
|
38
|
+
switch (resource) {
|
|
39
|
+
case 'camera':
|
|
40
|
+
if (source.camera) {
|
|
41
|
+
target.camera = _objectSpread({}, source.camera);
|
|
42
|
+
}
|
|
43
|
+
break;
|
|
44
|
+
case 'microphone':
|
|
45
|
+
if (source.microphone) {
|
|
46
|
+
target.microphone = _objectSpread({}, source.microphone);
|
|
47
|
+
}
|
|
48
|
+
break;
|
|
49
|
+
case 'contentShare':
|
|
50
|
+
if (source.contentShare) {
|
|
51
|
+
target.contentShare = _objectSpread({}, source.contentShare);
|
|
52
|
+
}
|
|
53
|
+
break;
|
|
54
|
+
default:
|
|
55
|
+
break;
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
var projectPrivacyAndSecurityPermission = exports.projectPrivacyAndSecurityPermission = function projectPrivacyAndSecurityPermission(permission, resources) {
|
|
59
|
+
var projectedPermission = {};
|
|
60
|
+
resources.forEach(function (resource) {
|
|
61
|
+
copyPermissionState(permission, projectedPermission, resource);
|
|
62
|
+
});
|
|
63
|
+
return (0, _keys.default)(projectedPermission).length > 0 ? projectedPermission : undefined;
|
|
64
|
+
};
|
|
65
|
+
var getChangedPermission = exports.getChangedPermission = function getChangedPermission(current, previous) {
|
|
66
|
+
var changedResources = (0, _keys.default)(current).filter(function (resource) {
|
|
67
|
+
return !(0, _lodash.isEqual)(current[resource], previous[resource]);
|
|
68
|
+
});
|
|
69
|
+
return projectPrivacyAndSecurityPermission(current, changedResources);
|
|
70
|
+
};
|
|
71
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_lodash","require","ownKeys","e","r","t","_Object$keys2","_Object$getOwnPropertySymbols","o","filter","_Object$getOwnPropertyDescriptor","enumerable","push","apply","_objectSpread","arguments","length","Object","forEach","_defineProperty2","default","_Object$getOwnPropertyDescriptors","_Object$defineProperties","_Object$defineProperty","resolveMediaResources","exports","payload","mediaType","resolveContentShareResources","copyPermissionState","source","target","resource","camera","microphone","contentShare","projectPrivacyAndSecurityPermission","permission","resources","projectedPermission","_keys","undefined","getChangedPermission","current","previous","changedResources","isEqual"],"sources":["utils.ts"],"sourcesContent":["import {isEqual} from 'lodash';\n\nimport type {\n ClientEventPayload,\n PrivacyAndSecurityPermission,\n PrivacyAndSecurityPermissionResource,\n} from '../metrics.types';\n\nexport const resolveMediaResources = (\n payload?: ClientEventPayload\n): PrivacyAndSecurityPermissionResource[] => {\n switch (payload?.mediaType) {\n case 'audio':\n return ['microphone'];\n case 'video':\n return ['camera'];\n case 'share':\n return ['contentShare'];\n default:\n return [];\n }\n};\n\nexport const resolveContentShareResources = (\n payload?: ClientEventPayload\n): PrivacyAndSecurityPermissionResource[] => {\n if (payload?.mediaType !== 'share') {\n return [];\n }\n\n return ['contentShare'];\n};\n\nconst copyPermissionState = (\n source: PrivacyAndSecurityPermission,\n target: PrivacyAndSecurityPermission,\n resource: PrivacyAndSecurityPermissionResource\n): void => {\n switch (resource) {\n case 'camera':\n if (source.camera) {\n target.camera = {...source.camera};\n }\n break;\n case 'microphone':\n if (source.microphone) {\n target.microphone = {...source.microphone};\n }\n break;\n case 'contentShare':\n if (source.contentShare) {\n target.contentShare = {...source.contentShare};\n }\n break;\n default:\n break;\n }\n};\n\nexport const projectPrivacyAndSecurityPermission = (\n permission: PrivacyAndSecurityPermission,\n resources: readonly PrivacyAndSecurityPermissionResource[]\n): PrivacyAndSecurityPermission | undefined => {\n const projectedPermission: PrivacyAndSecurityPermission = {};\n\n resources.forEach((resource) => {\n copyPermissionState(permission, projectedPermission, resource);\n });\n\n return Object.keys(projectedPermission).length > 0 ? projectedPermission : undefined;\n};\n\nexport const getChangedPermission = (\n current: PrivacyAndSecurityPermission,\n previous: PrivacyAndSecurityPermission\n): PrivacyAndSecurityPermission | undefined => {\n const changedResources = (Object.keys(current) as PrivacyAndSecurityPermissionResource[]).filter(\n (resource) => !isEqual(current[resource], previous[resource])\n );\n\n return projectPrivacyAndSecurityPermission(current, changedResources);\n};\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,5 +1,35 @@
|
|
|
1
1
|
import { WebexPlugin } from '@webex/webex-core';
|
|
2
2
|
import { MetricEventNames, PreComputedLatencies } from '../metrics.types';
|
|
3
|
+
type SaveTimestampOptions = {
|
|
4
|
+
meetingId?: string;
|
|
5
|
+
dataSetName?: string;
|
|
6
|
+
trackingId?: string;
|
|
7
|
+
};
|
|
8
|
+
type SaveLatencyOptions = {
|
|
9
|
+
accumulate?: boolean;
|
|
10
|
+
meetingId?: string;
|
|
11
|
+
dataSetName?: string;
|
|
12
|
+
};
|
|
13
|
+
type LocusSyncLatencyRecord = {
|
|
14
|
+
meetingId: string;
|
|
15
|
+
dataSetName: string;
|
|
16
|
+
randomBackoffTime: number;
|
|
17
|
+
trackingId?: string;
|
|
18
|
+
syncStart?: number;
|
|
19
|
+
hashTreeRequest?: number;
|
|
20
|
+
hashTreeResponse?: number;
|
|
21
|
+
syncRequest?: number;
|
|
22
|
+
syncResponse?: number;
|
|
23
|
+
messageReceived?: number;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Container for the latencies tracked for a single meeting. Locus sync is currently the only
|
|
27
|
+
* meeting-specific latency we track, but this wrapper lets us add other latency records in the
|
|
28
|
+
* future without changing the shape of `meetingLatencies`.
|
|
29
|
+
*/
|
|
30
|
+
type MeetingLatencyRecord = {
|
|
31
|
+
locusSync: LocusSyncLatencyRecord;
|
|
32
|
+
};
|
|
3
33
|
/**
|
|
4
34
|
* @description Helper class to store latencies timestamp and to calculate various latencies for CA.
|
|
5
35
|
* @exports
|
|
@@ -8,8 +38,12 @@ import { MetricEventNames, PreComputedLatencies } from '../metrics.types';
|
|
|
8
38
|
export default class CallDiagnosticLatencies extends WebexPlugin {
|
|
9
39
|
latencyTimestamps: Map<MetricEventNames, number>;
|
|
10
40
|
precomputedLatencies: Map<PreComputedLatencies, number>;
|
|
41
|
+
meetingLatencies: Map<string, MeetingLatencyRecord[]>;
|
|
11
42
|
private meetingId?;
|
|
12
43
|
private MAX_INTEGER;
|
|
44
|
+
private LOCUS_SYNC_SKEW_THRESHOLD_MS;
|
|
45
|
+
private LOCUS_SYNC_PENDING_RECORD_TTL_MS;
|
|
46
|
+
private LOCUS_SYNC_MAX_RECORDS_PER_DATASET;
|
|
13
47
|
/**
|
|
14
48
|
* @constructor
|
|
15
49
|
*/
|
|
@@ -18,6 +52,164 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
|
|
|
18
52
|
* Clear timestamps
|
|
19
53
|
*/
|
|
20
54
|
clearTimestamps(): void;
|
|
55
|
+
/**
|
|
56
|
+
* Clear tracked Locus sync latency state for a dataset.
|
|
57
|
+
*
|
|
58
|
+
* When a `trackingId` is supplied only the single record matching it is dropped, mirroring the
|
|
59
|
+
* native client which discards the individual in-progress record on a sync error (by syncId).
|
|
60
|
+
* When no `trackingId` is supplied every record for the dataset is dropped (legacy behavior).
|
|
61
|
+
*
|
|
62
|
+
* @param dataSetName dataset name
|
|
63
|
+
* @param meetingId meeting id
|
|
64
|
+
* @param trackingId optional sync tracking id to drop a single record instead of the whole dataset
|
|
65
|
+
*/
|
|
66
|
+
clearLocusSyncLatency(dataSetName: string, meetingId: string, trackingId?: string): void;
|
|
67
|
+
/**
|
|
68
|
+
* Calculates Locus sync latency values from stored milestone timestamps.
|
|
69
|
+
* @param meetingId meeting id
|
|
70
|
+
* @param trackingId sync tracking id used to match the record
|
|
71
|
+
* @returns sync latency metrics
|
|
72
|
+
*/
|
|
73
|
+
getLocusSyncLatency(meetingId: string, trackingId: string): {
|
|
74
|
+
totalTime: number;
|
|
75
|
+
syncMessageReceiveTime?: number;
|
|
76
|
+
syncResponseTime?: number;
|
|
77
|
+
randomBackoffTime: number;
|
|
78
|
+
hashtreePrepTime: number;
|
|
79
|
+
hashtreeResponseTime: number;
|
|
80
|
+
syncPrepTime: number;
|
|
81
|
+
};
|
|
82
|
+
/**
|
|
83
|
+
* Records the time the LLM state-update message for a Locus sync arrived. This is the milestone
|
|
84
|
+
* that gates the client.locus.sync.complete metric: the metric is emitted only for flows where
|
|
85
|
+
* the update came over LLM (aligned with the agreed requirement that body/http-only syncs do not
|
|
86
|
+
* emit). The record is matched by meeting id + tracking id, regardless of which other milestones
|
|
87
|
+
* are present yet, so the real arrival time is captured even if the /sync response has not landed.
|
|
88
|
+
* @param meetingId meeting id
|
|
89
|
+
* @param trackingId sync tracking id used to match the pending record
|
|
90
|
+
* @returns void
|
|
91
|
+
*/
|
|
92
|
+
recordLocusSyncMessageReceived(meetingId: string, trackingId: string): void;
|
|
93
|
+
/**
|
|
94
|
+
* Complete and remove the Locus sync latency record for a meeting + tracking id.
|
|
95
|
+
*
|
|
96
|
+
* Both milestones are required, in any arrival order: the metric is emitted only once BOTH the
|
|
97
|
+
* matching LLM broadcast (messageReceived) AND the /sync response have arrived. The LLM broadcast
|
|
98
|
+
* confirms the client that issued the /sync received the resulting state update for its tracking
|
|
99
|
+
* id (so sync cancel, or a sync storm where the final broadcast echoed another client's tracking
|
|
100
|
+
* id, never emit); the /sync response is always waited for too, since the LLM message can arrive
|
|
101
|
+
* before the HTTP response. If either milestone is missing the record is kept so the other can
|
|
102
|
+
* still arrive; it is only consumed when the metric is actually emitted.
|
|
103
|
+
* @param meetingId meeting id
|
|
104
|
+
* @param trackingId sync tracking id used to match the pending record
|
|
105
|
+
* @returns completed sync latency metric payload, or undefined when not completed
|
|
106
|
+
*/
|
|
107
|
+
completeLocusSyncLatency(meetingId: string, trackingId: string): {
|
|
108
|
+
dataSet: string;
|
|
109
|
+
syncLatency: {
|
|
110
|
+
totalTime: number;
|
|
111
|
+
syncMessageReceiveTime?: number;
|
|
112
|
+
syncResponseTime?: number;
|
|
113
|
+
randomBackoffTime: number;
|
|
114
|
+
hashtreePrepTime: number;
|
|
115
|
+
hashtreeResponseTime: number;
|
|
116
|
+
syncPrepTime: number;
|
|
117
|
+
};
|
|
118
|
+
};
|
|
119
|
+
/**
|
|
120
|
+
* Helper to calculate end - start for Locus sync milestones.
|
|
121
|
+
* @param record tracked milestone timestamps
|
|
122
|
+
* @param a start milestone
|
|
123
|
+
* @param b end milestone
|
|
124
|
+
* @returns latency
|
|
125
|
+
*/
|
|
126
|
+
private getDiffBetweenLocusSyncTimestamps;
|
|
127
|
+
/**
|
|
128
|
+
* Get the timestamp that starts the sync prep segment.
|
|
129
|
+
* @param record tracked milestone timestamps
|
|
130
|
+
* @returns sync prep start milestone
|
|
131
|
+
*/
|
|
132
|
+
private getLocusSyncPrepStart;
|
|
133
|
+
/**
|
|
134
|
+
* Round and clamp Locus sync latency values.
|
|
135
|
+
* @param latency latency value
|
|
136
|
+
* @returns rounded latency
|
|
137
|
+
*/
|
|
138
|
+
private getClampedLocusSyncLatency;
|
|
139
|
+
/**
|
|
140
|
+
* Finds a Locus sync latency record for a meeting using a predicate run against each stored
|
|
141
|
+
* locusSync record.
|
|
142
|
+
* @param meetingId meeting id
|
|
143
|
+
* @param predicate matcher run against each locusSync record
|
|
144
|
+
* @param options.searchFromLatest when true, iterate from the most recently added record first
|
|
145
|
+
* @returns matching Locus sync latency record
|
|
146
|
+
*/
|
|
147
|
+
private findLocusSyncRecord;
|
|
148
|
+
/**
|
|
149
|
+
* Get the Locus sync latency record for a meeting and tracking id.
|
|
150
|
+
* @param meetingId meeting id
|
|
151
|
+
* @param trackingId /sync response tracking id
|
|
152
|
+
* @returns matching Locus sync latency record
|
|
153
|
+
*/
|
|
154
|
+
private getLocusSyncLatencyRecord;
|
|
155
|
+
/**
|
|
156
|
+
* Remove the Locus sync latency record for a meeting and tracking id.
|
|
157
|
+
* @param meetingId meeting id
|
|
158
|
+
* @param trackingId sync tracking id used to match the record
|
|
159
|
+
* @returns void
|
|
160
|
+
*/
|
|
161
|
+
private removeLocusSyncLatencyRecord;
|
|
162
|
+
/**
|
|
163
|
+
* Prune stale never-completed Locus sync latency records for the same dataset as the record that
|
|
164
|
+
* just changed. Records are dropped when they have been pending longer than the TTL, or to keep
|
|
165
|
+
* the number of records per dataset under the safety cap (oldest pending candidates first).
|
|
166
|
+
* @param records current records for the meeting
|
|
167
|
+
* @param changedRecord the record that was just updated, used as the reference point
|
|
168
|
+
* @returns the records to keep
|
|
169
|
+
*/
|
|
170
|
+
private pruneStaleLocusSyncLatencyRecords;
|
|
171
|
+
/**
|
|
172
|
+
* Get the most recent milestone timestamp stored on a Locus sync latency record, checking
|
|
173
|
+
* milestones from latest to earliest so the newest available one is returned.
|
|
174
|
+
* @param record tracked milestone timestamps
|
|
175
|
+
* @returns latest milestone timestamp, or undefined when none are set
|
|
176
|
+
*/
|
|
177
|
+
private getLatestLocusSyncTimestamp;
|
|
178
|
+
/**
|
|
179
|
+
* Persist the Locus sync latency records for a meeting, deleting the meeting entry when no
|
|
180
|
+
* records remain. When pruneOptions is provided, stale records are pruned before saving.
|
|
181
|
+
* @param meetingId meeting id
|
|
182
|
+
* @param records records to save
|
|
183
|
+
* @param pruneOptions when provided, triggers stale record pruning relative to changedRecord
|
|
184
|
+
* @returns void
|
|
185
|
+
*/
|
|
186
|
+
private setMeetingLatencyRecords;
|
|
187
|
+
/**
|
|
188
|
+
* Get the latest Locus sync latency record waiting for sync.start.
|
|
189
|
+
* @param meetingId meeting id
|
|
190
|
+
* @param dataSetName dataset name
|
|
191
|
+
* @returns latest pending Locus sync latency record
|
|
192
|
+
*/
|
|
193
|
+
private getLatestPendingLocusSyncLatencyRecord;
|
|
194
|
+
/**
|
|
195
|
+
* Store random backoff latency for the current or next Locus sync latency record.
|
|
196
|
+
* @param meetingId meeting id
|
|
197
|
+
* @param dataSetName dataset name
|
|
198
|
+
* @param randomBackoffTime random backoff latency value
|
|
199
|
+
* @returns void
|
|
200
|
+
*/
|
|
201
|
+
private saveLocusSyncBackoffLatency;
|
|
202
|
+
/**
|
|
203
|
+
* Checks if metric event name is a Locus sync latency milestone.
|
|
204
|
+
* @param key event name
|
|
205
|
+
* @returns whether event is Locus sync latency milestone
|
|
206
|
+
*/
|
|
207
|
+
private isLocusSyncLatencyEvent;
|
|
208
|
+
/**
|
|
209
|
+
* Stores a Locus sync latency milestone timestamp.
|
|
210
|
+
* @param options options
|
|
211
|
+
*/
|
|
212
|
+
private saveLocusSyncLatencyTimestamp;
|
|
21
213
|
/**
|
|
22
214
|
* Associate current latencies with a meeting id
|
|
23
215
|
* @param meetingId
|
|
@@ -39,19 +231,20 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
|
|
|
39
231
|
saveTimestamp({ key, value, options, }: {
|
|
40
232
|
key: MetricEventNames;
|
|
41
233
|
value?: number;
|
|
42
|
-
options?:
|
|
43
|
-
meetingId?: string;
|
|
44
|
-
};
|
|
234
|
+
options?: SaveTimestampOptions;
|
|
45
235
|
}): void;
|
|
46
236
|
/**
|
|
47
237
|
* Store precomputed latency value
|
|
48
238
|
* @param key - key
|
|
49
239
|
* @param value - value
|
|
50
|
-
* @param
|
|
240
|
+
* @param options - store options (a legacy boolean `accumulate` flag is also accepted)
|
|
241
|
+
* @param options.accumulate - when it is true, it overwrites existing value with sum of the current value and the new measurement otherwise just store the new measurement
|
|
242
|
+
* @param options.meetingId - meeting id, only used for Locus sync latency records
|
|
243
|
+
* @param options.dataSetName - dataset name, only used for Locus sync latency records
|
|
51
244
|
* @throws
|
|
52
245
|
* @returns
|
|
53
246
|
*/
|
|
54
|
-
saveLatency(key: PreComputedLatencies, value: number,
|
|
247
|
+
saveLatency(key: PreComputedLatencies, value: number, options?: SaveLatencyOptions): void;
|
|
55
248
|
/**
|
|
56
249
|
* Measure latency for a request
|
|
57
250
|
* @param callback - callback for which you would like to measure latency
|
|
@@ -149,6 +342,15 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
|
|
|
149
342
|
* @returns - latency
|
|
150
343
|
*/
|
|
151
344
|
getStayLobbyTime(): number;
|
|
345
|
+
/**
|
|
346
|
+
* Stay lobby time capped by a certain timestamp.
|
|
347
|
+
* This is to handle the case where the target end timestamp could happen before the lobby is exited,
|
|
348
|
+
* for example media-engine.ready or client.ice.end
|
|
349
|
+
* This is supposed to be called AFTER the end timestamp happens
|
|
350
|
+
* @param endTimestampKey name of the target end event
|
|
351
|
+
* @returns - latency
|
|
352
|
+
*/
|
|
353
|
+
getStayLobbyTimeCappedBy(endTimestampKey: MetricEventNames): number;
|
|
152
354
|
/**
|
|
153
355
|
* Page JMT
|
|
154
356
|
* @returns - latency
|
|
@@ -258,3 +460,4 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
|
|
|
258
460
|
*/
|
|
259
461
|
getOtherAppApiReqResp(): number;
|
|
260
462
|
}
|
|
463
|
+
export {};
|
|
@@ -27,7 +27,7 @@ type GetIdentifiersOptions = {
|
|
|
27
27
|
export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
28
28
|
private callDiagnosticEventsBatcher;
|
|
29
29
|
private preLoginMetricsBatcher;
|
|
30
|
-
private logger;
|
|
30
|
+
private get logger();
|
|
31
31
|
private hasLoggedBrowserSerial;
|
|
32
32
|
private device;
|
|
33
33
|
private delayedClientEvents;
|
|
@@ -36,6 +36,8 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
36
36
|
private isMercuryConnected;
|
|
37
37
|
private eventLimitTracker;
|
|
38
38
|
private eventLimitWarningsLogged;
|
|
39
|
+
private isTelemetryOptOutManual;
|
|
40
|
+
private isTelemetryOptOutAutomatic;
|
|
39
41
|
validator: (options: {
|
|
40
42
|
type: 'mqe' | 'ce';
|
|
41
43
|
event: Event;
|
|
@@ -53,6 +55,29 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
53
55
|
* @returns one of 'login-ci','unverified-guest', null
|
|
54
56
|
*/
|
|
55
57
|
getCurLoginType(): "unverified-guest" | "login-ci";
|
|
58
|
+
/**
|
|
59
|
+
* Returns the user activation state reported from the browser's navigator.userActivation API
|
|
60
|
+
* @returns object with hasBeenActive and isActive booleans, or undefined if unavailable
|
|
61
|
+
*/
|
|
62
|
+
getUserActivation(): {
|
|
63
|
+
hasBeenActive: boolean;
|
|
64
|
+
isActive: boolean;
|
|
65
|
+
} | undefined;
|
|
66
|
+
/**
|
|
67
|
+
* Returns the telemetryOptOut value of the current user
|
|
68
|
+
* @returns one of 'manual', 'automatic', undefined
|
|
69
|
+
*/
|
|
70
|
+
getTelemetryOptOut(): "manual" | "automatic";
|
|
71
|
+
/**
|
|
72
|
+
* Sets the manual telemetry opt-out status for the current user
|
|
73
|
+
* @param value - boolean value indicating manual telemetry opt-out status
|
|
74
|
+
*/
|
|
75
|
+
setIsTelemetryOptOutManual(value: boolean): void;
|
|
76
|
+
/**
|
|
77
|
+
* Sets the automatic telemetry opt-out status for the current user
|
|
78
|
+
* @param value - boolean value indicating automatic telemetry opt-out status
|
|
79
|
+
*/
|
|
80
|
+
setIsTelemetryOptOutAutomatic(value: boolean): void;
|
|
56
81
|
/**
|
|
57
82
|
* Returns if the meeting has converged architecture enabled
|
|
58
83
|
* @param options.meetingId
|
|
@@ -84,6 +109,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
84
109
|
userAgent: string;
|
|
85
110
|
buildType?: "debug" | "test" | "prod" | "tap" | "analyzer-test";
|
|
86
111
|
upgradeChannel?: string;
|
|
112
|
+
upgradeSource?: string;
|
|
87
113
|
instanceId?: string;
|
|
88
114
|
networkType: "wifi" | "ethernet" | "cellular" | "unknown";
|
|
89
115
|
localIP?: string;
|
|
@@ -106,6 +132,8 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
106
132
|
urlProtocolLaunchMethod?: "manual" | "auto" | "extension-fallback";
|
|
107
133
|
browser?: string;
|
|
108
134
|
browserVersion?: string;
|
|
135
|
+
isSupportedBrowserFamily?: boolean;
|
|
136
|
+
isOutdatedBrowserVersion?: boolean;
|
|
109
137
|
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" | "TEAMS_PHONE" | "WEBEX_RELAY";
|
|
110
138
|
subClientType?: "TEAMS_DEVICE" | "SIP" | "AUTOMOTIVE_APP" | "BROWSER_EXTENSION" | "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" | "PHONE_NOVUM" | "PHONE_ESPRESSO" | "PHONE_BUMBLEBEE" | "SIP_PSTN";
|
|
111
139
|
schedulingClientType?: "TEAMS_CLIENT" | "GOOGLE_ADDON" | "PT" | "PUBLIC_API" | "UNIFIED_PAGE" | "WEBEX_PAGE" | "GOOGLE_NOTIFICATION_CALENDAR" | "MSFT_NOTIFICATION_ADDIN" | "MSFT_NOTIFICATION_CALENDAR" | "OUTLOOK_ADDIN";
|
|
@@ -113,6 +141,10 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
113
141
|
clientVersionStatus?: "CURRENT" | "LEGACY" | "UNSUPPORTED";
|
|
114
142
|
localClientVersion?: string;
|
|
115
143
|
launcherVersion?: string;
|
|
144
|
+
installerVersion?: string;
|
|
145
|
+
installerMajorVersion?: number;
|
|
146
|
+
installerMinorVersion?: number;
|
|
147
|
+
installerRevision?: number;
|
|
116
148
|
modelNumber?: string;
|
|
117
149
|
joinFirstUpdateLater?: "ep-enabled" | "sp-enabled" | "not-enabled";
|
|
118
150
|
standbyUsed?: boolean;
|
|
@@ -137,11 +169,12 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
137
169
|
architecture: "unknown" | "intel32" | "intel64" | "amd32" | "amd64" | "arm32" | "arm64" | "armv9" | "armv8" | "armv7" | "armv6" | "x86_64" | "x86_32";
|
|
138
170
|
staticPerformance?: string;
|
|
139
171
|
clockSpeedGigaHertz?: number;
|
|
140
|
-
additionalProperties?:
|
|
172
|
+
additionalProperties?: never;
|
|
141
173
|
};
|
|
142
174
|
shareType?: "cb-normal-share" | "ce-airplay-share" | "ce-direct-share" | "ce-gui-loopback-share" | "ce-input-source-share" | "ce-input-source-share-hdmi" | "ce-input-source-share-usbc" | "ce-jpg-share" | "ce-miracast-share" | "mcs-normal-share" | "mcs-normal-audio-share" | "mcs-hfps-share" | "mcs-hfps-audio-share";
|
|
143
175
|
videoDisplayMode?: "grid-view" | "active-speaker-view";
|
|
144
|
-
videoLayoutType?: "stack" | "stackWithShare" | "sideBySide" | "sideBySideWithShare" | "grid" | "floatingActive" | "floatingThumbnail" | "floatingGrid" | "overlay" | "focus" | "prominent" | "focusWithShare" | "prominentWithShare" | "equal" | "equalWithShare" | "largeGallery";
|
|
176
|
+
videoLayoutType?: "auto" | "stack" | "stackWithShare" | "sideBySide" | "sideBySideWithShare" | "grid" | "floatingActive" | "floatingThumbnail" | "floatingGrid" | "overlay" | "focus" | "prominent" | "focusWithShare" | "prominentWithShare" | "equal" | "equalWithShare" | "largeGallery" | "autoWithShare";
|
|
177
|
+
appliedLayout?: "auto" | "stack" | "stackWithShare" | "sideBySide" | "sideBySideWithShare" | "grid" | "floatingActive" | "floatingThumbnail" | "floatingGrid" | "overlay" | "focus" | "prominent" | "focusWithShare" | "prominentWithShare" | "equal" | "equalWithShare" | "largeGallery" | "autoWithShare";
|
|
145
178
|
videoRenderType?: "wme" | "client_d3d" | "client_gdi";
|
|
146
179
|
vdiInfo?: {};
|
|
147
180
|
is64BitsClient?: boolean;
|
|
@@ -153,14 +186,31 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
153
186
|
vendorId?: string;
|
|
154
187
|
staticPerformanceLevel?: string;
|
|
155
188
|
staticPerformanceScore?: number;
|
|
156
|
-
|
|
189
|
+
preInstalledTime?: string;
|
|
190
|
+
preInstalledType?: "installer" | "launcher" | "app";
|
|
191
|
+
preInstalledVersion?: string;
|
|
192
|
+
additionalProperties?: never;
|
|
193
|
+
};
|
|
194
|
+
installerInfo?: {
|
|
195
|
+
packageSuffix?: string;
|
|
196
|
+
packageArch?: string;
|
|
197
|
+
launchId?: string;
|
|
198
|
+
packageCount?: number;
|
|
199
|
+
totalSize?: number;
|
|
200
|
+
additionalProperties?: never;
|
|
157
201
|
};
|
|
158
202
|
emmVendorId?: string;
|
|
159
203
|
isHybridMedia?: boolean;
|
|
160
204
|
originData?: {};
|
|
161
205
|
serviceVersion?: string;
|
|
162
|
-
additionalProperties?:
|
|
206
|
+
additionalProperties?: never;
|
|
163
207
|
};
|
|
208
|
+
/**
|
|
209
|
+
* Returns the signed-in user's CI ID derived from credentials tokens.
|
|
210
|
+
* Used as a fallback when no device is registered.
|
|
211
|
+
* @returns the userId, or undefined if it can't be determined
|
|
212
|
+
*/
|
|
213
|
+
private getUserIdFromCredentials;
|
|
164
214
|
/**
|
|
165
215
|
* Gather identifier details for call diagnostic payload.
|
|
166
216
|
* @throws Error if initialization fails.
|
|
@@ -172,6 +222,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
172
222
|
participantId?: string;
|
|
173
223
|
breakoutGroupId?: string;
|
|
174
224
|
breakoutMoveId?: string;
|
|
225
|
+
breakoutTrackingId?: string;
|
|
175
226
|
breakoutSessionId?: string;
|
|
176
227
|
browserId?: string;
|
|
177
228
|
ciExchangeTokenUrl?: string;
|
|
@@ -183,7 +234,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
183
234
|
imiAppId: string;
|
|
184
235
|
sessionId: string;
|
|
185
236
|
sessionInstanceId: string;
|
|
186
|
-
additionalProperties?:
|
|
237
|
+
additionalProperties?: never;
|
|
187
238
|
};
|
|
188
239
|
csdmDeviceUrl?: string;
|
|
189
240
|
destinationBreakoutSessionId?: string;
|
|
@@ -200,6 +251,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
200
251
|
callId?: string;
|
|
201
252
|
pairCallId?: string;
|
|
202
253
|
llmWebsocketUrl?: string;
|
|
254
|
+
locusCluster?: string;
|
|
203
255
|
locusId?: string;
|
|
204
256
|
locusJoinUrl?: string;
|
|
205
257
|
locusSessionId?: string;
|
|
@@ -217,6 +269,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
217
269
|
msteamsTenantGuid?: string;
|
|
218
270
|
msteamsConferenceId?: string;
|
|
219
271
|
msteamsMeetingId?: string;
|
|
272
|
+
mtid?: string;
|
|
220
273
|
oauth2ClientId?: string;
|
|
221
274
|
orgId?: string;
|
|
222
275
|
provisionalCorrelationId?: string;
|
|
@@ -227,7 +280,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
227
280
|
sipSessionId?: {
|
|
228
281
|
local?: string;
|
|
229
282
|
remote?: string;
|
|
230
|
-
additionalProperties?:
|
|
283
|
+
additionalProperties?: never;
|
|
231
284
|
};
|
|
232
285
|
sipUri?: string;
|
|
233
286
|
subConfId?: string;
|
|
@@ -255,13 +308,14 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
255
308
|
idForEndpointAB?: string;
|
|
256
309
|
customerOrgId?: string;
|
|
257
310
|
correlationId: string;
|
|
258
|
-
additionalProperties?:
|
|
311
|
+
additionalProperties?: never;
|
|
259
312
|
} | {
|
|
260
313
|
aggregatedBreakoutMoveId?: string;
|
|
261
314
|
attendeeId?: string;
|
|
262
315
|
participantId?: string;
|
|
263
316
|
breakoutGroupId?: string;
|
|
264
317
|
breakoutMoveId?: string;
|
|
318
|
+
breakoutTrackingId?: string;
|
|
265
319
|
breakoutSessionId?: string;
|
|
266
320
|
browserId?: string;
|
|
267
321
|
ciExchangeTokenUrl?: string;
|
|
@@ -273,7 +327,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
273
327
|
imiAppId: string;
|
|
274
328
|
sessionId: string;
|
|
275
329
|
sessionInstanceId: string;
|
|
276
|
-
additionalProperties?:
|
|
330
|
+
additionalProperties?: never;
|
|
277
331
|
};
|
|
278
332
|
csdmDeviceUrl?: string;
|
|
279
333
|
destinationBreakoutSessionId?: string;
|
|
@@ -290,6 +344,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
290
344
|
callId?: string;
|
|
291
345
|
pairCallId?: string;
|
|
292
346
|
llmWebsocketUrl?: string;
|
|
347
|
+
locusCluster?: string;
|
|
293
348
|
locusId?: string;
|
|
294
349
|
locusJoinUrl?: string;
|
|
295
350
|
locusSessionId?: string;
|
|
@@ -307,6 +362,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
307
362
|
msteamsTenantGuid?: string;
|
|
308
363
|
msteamsConferenceId?: string;
|
|
309
364
|
msteamsMeetingId?: string;
|
|
365
|
+
mtid?: string;
|
|
310
366
|
oauth2ClientId?: string;
|
|
311
367
|
orgId?: string;
|
|
312
368
|
provisionalCorrelationId?: string;
|
|
@@ -317,7 +373,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
317
373
|
sipSessionId?: {
|
|
318
374
|
local?: string;
|
|
319
375
|
remote?: string;
|
|
320
|
-
additionalProperties?:
|
|
376
|
+
additionalProperties?: never;
|
|
321
377
|
};
|
|
322
378
|
sipUri?: string;
|
|
323
379
|
subConfId?: string;
|
|
@@ -345,13 +401,14 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
345
401
|
idForEndpointAB?: string;
|
|
346
402
|
customerOrgId?: string;
|
|
347
403
|
correlationId: string;
|
|
348
|
-
additionalProperties?:
|
|
404
|
+
additionalProperties?: never;
|
|
349
405
|
} | {
|
|
350
406
|
aggregatedBreakoutMoveId?: string;
|
|
351
407
|
attendeeId?: string;
|
|
352
408
|
participantId?: string;
|
|
353
409
|
breakoutGroupId?: string;
|
|
354
410
|
breakoutMoveId?: string;
|
|
411
|
+
breakoutTrackingId?: string;
|
|
355
412
|
breakoutSessionId?: string;
|
|
356
413
|
browserId?: string;
|
|
357
414
|
ciExchangeTokenUrl?: string;
|
|
@@ -363,7 +420,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
363
420
|
imiAppId: string;
|
|
364
421
|
sessionId: string;
|
|
365
422
|
sessionInstanceId: string;
|
|
366
|
-
additionalProperties?:
|
|
423
|
+
additionalProperties?: never;
|
|
367
424
|
};
|
|
368
425
|
csdmDeviceUrl?: string;
|
|
369
426
|
destinationBreakoutSessionId?: string;
|
|
@@ -380,6 +437,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
380
437
|
callId?: string;
|
|
381
438
|
pairCallId?: string;
|
|
382
439
|
llmWebsocketUrl?: string;
|
|
440
|
+
locusCluster?: string;
|
|
383
441
|
locusId?: string;
|
|
384
442
|
locusJoinUrl?: string;
|
|
385
443
|
locusSessionId?: string;
|
|
@@ -397,6 +455,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
397
455
|
msteamsTenantGuid?: string;
|
|
398
456
|
msteamsConferenceId?: string;
|
|
399
457
|
msteamsMeetingId?: string;
|
|
458
|
+
mtid?: string;
|
|
400
459
|
oauth2ClientId?: string;
|
|
401
460
|
orgId?: string;
|
|
402
461
|
provisionalCorrelationId?: string;
|
|
@@ -407,7 +466,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
407
466
|
sipSessionId?: {
|
|
408
467
|
local?: string;
|
|
409
468
|
remote?: string;
|
|
410
|
-
additionalProperties?:
|
|
469
|
+
additionalProperties?: never;
|
|
411
470
|
};
|
|
412
471
|
sipUri?: string;
|
|
413
472
|
subConfId?: string;
|
|
@@ -435,7 +494,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
435
494
|
idForEndpointAB?: string;
|
|
436
495
|
customerOrgId?: string;
|
|
437
496
|
correlationId: string;
|
|
438
|
-
additionalProperties?:
|
|
497
|
+
additionalProperties?: never;
|
|
439
498
|
};
|
|
440
499
|
/**
|
|
441
500
|
* Create diagnostic event, which can hold client event, feature event or MQE event data.
|