@webex/internal-plugin-metrics 3.8.0-next.2 → 3.8.0-next.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/call-diagnostic/call-diagnostic-metrics.js +71 -32
- package/dist/call-diagnostic/call-diagnostic-metrics.js.map +1 -1
- package/dist/call-diagnostic/config.js +27 -2
- package/dist/call-diagnostic/config.js.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/metrics.js +1 -1
- package/dist/metrics.types.js.map +1 -1
- package/dist/new-metrics.js +15 -4
- package/dist/new-metrics.js.map +1 -1
- package/dist/types/call-diagnostic/call-diagnostic-metrics.d.ts +17 -22
- package/dist/types/call-diagnostic/config.d.ts +11 -0
- package/dist/types/index.d.ts +2 -2
- package/dist/types/metrics.types.d.ts +7 -1
- package/dist/types/new-metrics.d.ts +10 -3
- package/package.json +12 -12
- package/src/call-diagnostic/call-diagnostic-metrics.ts +66 -42
- package/src/call-diagnostic/config.ts +26 -0
- package/src/index.ts +2 -0
- package/src/metrics.types.ts +8 -1
- package/src/new-metrics.ts +21 -4
- package/test/unit/spec/call-diagnostic/call-diagnostic-metrics.ts +301 -35
- package/test/unit/spec/new-metrics.ts +27 -3
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { StatelessWebexPlugin } from '@webex/webex-core';
|
|
2
|
-
import { Event, ClientType, SubClientType, NetworkType, EnvironmentType, NewEnvironmentType, ClientEvent, SubmitClientEventOptions, MediaQualityEvent, SubmitMQEOptions, SubmitMQEPayload, ClientLaunchMethodType, ClientEventError, ClientEventPayload, ClientSubServiceType, BrowserLaunchMethodType } from '../metrics.types';
|
|
2
|
+
import { Event, ClientType, SubClientType, NetworkType, EnvironmentType, NewEnvironmentType, ClientEvent, SubmitClientEventOptions, MediaQualityEvent, SubmitMQEOptions, SubmitMQEPayload, ClientLaunchMethodType, ClientEventError, ClientEventPayload, ClientSubServiceType, BrowserLaunchMethodType, DelayedClientEvent } from '../metrics.types';
|
|
3
3
|
type GetOriginOptions = {
|
|
4
4
|
clientType: ClientType;
|
|
5
5
|
subClientType: SubClientType;
|
|
@@ -30,6 +30,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
30
30
|
private hasLoggedBrowserSerial;
|
|
31
31
|
private device;
|
|
32
32
|
private delayedClientEvents;
|
|
33
|
+
private eventErrorCache;
|
|
33
34
|
validator: (options: {
|
|
34
35
|
type: 'mqe' | 'ce';
|
|
35
36
|
event: Event;
|
|
@@ -67,7 +68,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
67
68
|
* @returns
|
|
68
69
|
*/
|
|
69
70
|
getOrigin(options: GetOriginOptions, meetingId?: string): {
|
|
70
|
-
name: "endpoint" | "addin" | "antares" | "appapi" | "beech" | "breakout" | "calendar" | "cb" | "cca" | "ccc" | "cloudproxy" | "crc" | "edonus" | "givr" | "hecate" | "hedge" | "hesiod" | "homer" | "superhomer" | "l2sip" | "linus" | "locus" | "mbs" | "mcc" | "mcs" | "mercury" | "mes" | "mjs" | "mmp" | "mygdon" | "ngservice" | "orpheus" | "page" | "poros" | "publicapi" | "rhesos" | "terminus" | "tpgw" | "ucc" | "wdm" | "webexivr" | "meetingcontainer";
|
|
71
|
+
name: "endpoint" | "addin" | "antares" | "appapi" | "beech" | "breakout" | "calendar" | "cb" | "cca" | "ccc" | "cloudproxy" | "crc" | "edonus" | "givr" | "hecate" | "hedge" | "hesiod" | "homer" | "idbroker" | "superhomer" | "l2sip" | "linus" | "locus" | "mbs" | "mcc" | "mcs" | "mercury" | "mes" | "mjs" | "mmp" | "mygdon" | "ngservice" | "orpheus" | "page" | "poros" | "publicapi" | "rhesos" | "terminus" | "tpgw" | "ucc" | "wdm" | "webexivr" | "meetingcontainer";
|
|
71
72
|
userAgent: string;
|
|
72
73
|
buildType?: "debug" | "test" | "prod" | "tap" | "analyzer-test";
|
|
73
74
|
upgradeChannel?: string;
|
|
@@ -87,11 +88,14 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
87
88
|
localNetworkPrefix?: string;
|
|
88
89
|
publicNetworkPrefix?: string;
|
|
89
90
|
browserLaunchMethod?: "url-handler" | "activex" | "npapi" | "extension" | "cwsapi" | "java" | "tfs" | "webacd" | "thinclient" | "switch-to-web" | "switch-to-native";
|
|
90
|
-
clientLaunchMethod?: "url-handler" | "universal-link" | "voice-command" | "notification" | "manual" | "teams-cross-launch" | "mc-cross-launch";
|
|
91
|
+
clientLaunchMethod?: "url-handler" | "universal-link" | "voice-command" | "notification" | "manual" | "teams-cross-launch" | "mc-cross-launch" | "cws" | "launcher" | "cws-launcher";
|
|
91
92
|
browser?: string;
|
|
92
93
|
browserVersion?: string;
|
|
93
|
-
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";
|
|
94
|
-
|
|
94
|
+
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"; /**
|
|
95
|
+
* Constructor
|
|
96
|
+
* @param args
|
|
97
|
+
*/
|
|
98
|
+
subClientType?: "TEAMS_DEVICE" | "AUTOMOTIVE_APP" | "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";
|
|
95
99
|
schedulingClientType?: "TEAMS_CLIENT" | "GOOGLE_ADDON" | "PT" | "PUBLIC_API" | "UNIFIED_PAGE" | "WEBEX_PAGE" | "GOOGLE_NOTIFICATION_CALENDAR" | "MSFT_NOTIFICATION_ADDIN" | "MSFT_NOTIFICATION_CALENDAR" | "OUTLOOK_ADDIN";
|
|
96
100
|
clientVersion?: string;
|
|
97
101
|
clientVersionStatus?: "CURRENT" | "LEGACY" | "UNSUPPORTED";
|
|
@@ -147,6 +151,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
147
151
|
* @param options
|
|
148
152
|
*/
|
|
149
153
|
getIdentifiers(options: GetIdentifiersOptions): {
|
|
154
|
+
aggregatedBreakoutMoveId?: string;
|
|
150
155
|
attendeeId?: string;
|
|
151
156
|
participantId?: string;
|
|
152
157
|
breakoutGroupId?: string;
|
|
@@ -230,6 +235,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
230
235
|
correlationId: string;
|
|
231
236
|
additionalProperties?: false;
|
|
232
237
|
} | {
|
|
238
|
+
aggregatedBreakoutMoveId?: string;
|
|
233
239
|
attendeeId?: string;
|
|
234
240
|
participantId?: string;
|
|
235
241
|
breakoutGroupId?: string;
|
|
@@ -356,26 +362,15 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
356
362
|
payloadOverrides?: any;
|
|
357
363
|
httpStatusCode?: number;
|
|
358
364
|
}): ClientEventError;
|
|
365
|
+
/**
|
|
366
|
+
* Clear the error cache
|
|
367
|
+
*/
|
|
368
|
+
clearErrorCache(): void;
|
|
359
369
|
/**
|
|
360
370
|
* Generate error payload for Client Event
|
|
361
371
|
* @param rawError
|
|
362
372
|
*/
|
|
363
|
-
generateClientEventErrorPayload(rawError: any):
|
|
364
|
-
fatal: boolean;
|
|
365
|
-
category: "other" | "signaling" | "media" | "network" | "expected";
|
|
366
|
-
errorDescription?: string;
|
|
367
|
-
errorCode?: number;
|
|
368
|
-
errorCodeStr?: string;
|
|
369
|
-
httpCode?: number;
|
|
370
|
-
errorCodeExt1?: number;
|
|
371
|
-
errorData?: {};
|
|
372
|
-
rawErrorMessage?: string;
|
|
373
|
-
mediaDeviceErrors?: string;
|
|
374
|
-
shownToUser: boolean;
|
|
375
|
-
serviceErrorCode?: number;
|
|
376
|
-
name: "other" | "locus.response" | "media-engine" | "ice.failed" | "locus.leave" | "client.leave" | "media-device" | "media-sca" | "wxc";
|
|
377
|
-
additionalProperties?: false;
|
|
378
|
-
};
|
|
373
|
+
generateClientEventErrorPayload(rawError: any): any[];
|
|
379
374
|
/**
|
|
380
375
|
* Create client event object for in meeting events
|
|
381
376
|
* @param arg - create args
|
|
@@ -420,7 +415,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
420
415
|
/**
|
|
421
416
|
* Submit Delayed Client Event CA events. Clears delayedClientEvents array after submission.
|
|
422
417
|
*/
|
|
423
|
-
submitDelayedClientEvents(): Promise<any[]> | Promise<void>;
|
|
418
|
+
submitDelayedClientEvents(overrides?: Partial<DelayedClientEvent['options']>): Promise<any[]> | Promise<void>;
|
|
424
419
|
/**
|
|
425
420
|
* Prepare the event and send the request to metrics-a service.
|
|
426
421
|
* @param event
|
|
@@ -99,6 +99,7 @@ export declare const ERROR_DESCRIPTIONS: {
|
|
|
99
99
|
SDP_OFFER_CREATION_ERROR: string;
|
|
100
100
|
SDP_OFFER_CREATION_ERROR_MISSING_CODEC: string;
|
|
101
101
|
WDM_RESTRICTED_REGION: string;
|
|
102
|
+
USER_NOT_ALLOWED_JOIN_WEBINAR: string;
|
|
102
103
|
};
|
|
103
104
|
export declare const SERVICE_ERROR_CODES_TO_CLIENT_ERROR_CODES_MAP: {
|
|
104
105
|
58400: number;
|
|
@@ -108,6 +109,8 @@ export declare const SERVICE_ERROR_CODES_TO_CLIENT_ERROR_CODES_MAP: {
|
|
|
108
109
|
400001: number;
|
|
109
110
|
403004: number;
|
|
110
111
|
403028: number;
|
|
112
|
+
403025: number;
|
|
113
|
+
403125: number;
|
|
111
114
|
403032: number;
|
|
112
115
|
403034: number;
|
|
113
116
|
403036: number;
|
|
@@ -133,6 +136,14 @@ export declare const SERVICE_ERROR_CODES_TO_CLIENT_ERROR_CODES_MAP: {
|
|
|
133
136
|
423012: number;
|
|
134
137
|
423013: number;
|
|
135
138
|
429005: number;
|
|
139
|
+
403021: number;
|
|
140
|
+
403022: number;
|
|
141
|
+
403024: number;
|
|
142
|
+
403137: number;
|
|
143
|
+
423007: number;
|
|
144
|
+
403026: number;
|
|
145
|
+
403037: number;
|
|
146
|
+
403003: number;
|
|
136
147
|
2403001: number;
|
|
137
148
|
2403002: number;
|
|
138
149
|
2403003: number;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import config from './config';
|
|
5
5
|
import NewMetrics from './new-metrics';
|
|
6
6
|
import * as Utils from './utils';
|
|
7
|
-
import { ClientEvent, ClientEventLeaveReason, SubmitBehavioralEvent, SubmitClientEvent, SubmitInternalEvent, SubmitOperationalEvent, SubmitMQE, PreComputedLatencies } from './metrics.types';
|
|
7
|
+
import { ClientEvent, ClientEventLeaveReason, SubmitBehavioralEvent, SubmitClientEvent, SubmitInternalEvent, SubmitOperationalEvent, SubmitBusinessEvent, SubmitMQE, PreComputedLatencies } from './metrics.types';
|
|
8
8
|
import * as CALL_DIAGNOSTIC_CONFIG from './call-diagnostic/config';
|
|
9
9
|
import * as CallDiagnosticUtils from './call-diagnostic/call-diagnostic-metrics.util';
|
|
10
10
|
import CallDiagnosticMetrics from './call-diagnostic/call-diagnostic-metrics';
|
|
@@ -15,4 +15,4 @@ import BusinessMetrics from './business-metrics';
|
|
|
15
15
|
import RtcMetrics from './rtcMetrics';
|
|
16
16
|
export { default, getOSNameInternal } from './metrics';
|
|
17
17
|
export { config, CALL_DIAGNOSTIC_CONFIG, NewMetrics, Utils, CallDiagnosticUtils, CallDiagnosticLatencies, CallDiagnosticMetrics, BehavioralMetrics, OperationalMetrics, BusinessMetrics, RtcMetrics, };
|
|
18
|
-
export type { ClientEvent, ClientEventLeaveReason, SubmitBehavioralEvent, SubmitClientEvent, SubmitInternalEvent, SubmitMQE, SubmitOperationalEvent, PreComputedLatencies, };
|
|
18
|
+
export type { ClientEvent, ClientEventLeaveReason, SubmitBehavioralEvent, SubmitClientEvent, SubmitInternalEvent, SubmitMQE, SubmitOperationalEvent, SubmitBusinessEvent, PreComputedLatencies, };
|
|
@@ -9,7 +9,7 @@ export type ClientLaunchMethodType = NonNullable<RawEvent['origin']['clientInfo'
|
|
|
9
9
|
export type ClientUserNameInput = NonNullable<RawClientEvent['userNameInput']>;
|
|
10
10
|
export type ClientEmailInput = NonNullable<RawClientEvent['emailInput']>;
|
|
11
11
|
export type BrowserLaunchMethodType = NonNullable<RawEvent['origin']['clientInfo']>['browserLaunchMethod'];
|
|
12
|
-
export type MetricEventProduct = 'webex' | 'wxcc_desktop' | 'wxcc_crm';
|
|
12
|
+
export type MetricEventProduct = 'webex' | 'wxcc_desktop' | 'wxcc_crm' | 'wxcc_sdk';
|
|
13
13
|
export type MetricEventAgent = 'user' | 'browser' | 'system' | 'sdk' | 'redux' | 'service' | 'api';
|
|
14
14
|
export type MetricEventVerb = 'abort' | 'accept' | 'activate' | 'apply' | 'answer' | 'authorize' | 'build' | 'cancel' | 'change' | 'click' | 'close' | 'complete' | 'connect' | 'create' | 'deactivate' | 'decrypt' | 'delete' | 'deliver' | 'destroy' | 'disable' | 'disconnect' | 'dismiss' | 'display' | 'download' | 'edit' | 'enable' | 'encrypt' | 'end' | 'expire' | 'fail' | 'fetch' | 'fire' | 'generate' | 'get' | 'hide' | 'hover' | 'ignore' | 'initialize' | 'initiate' | 'invalidate' | 'join' | 'list' | 'load' | 'login' | 'logout' | 'notify' | 'offer' | 'open' | 'press' | 'receive' | 'refer' | 'refresh' | 'register' | 'release' | 'reload' | 'reject' | 'request' | 'reset' | 'resize' | 'respond' | 'retry' | 'revoke' | 'save' | 'search' | 'select' | 'send' | 'set' | 'sign' | 'start' | 'submit' | 'switch' | 'sync' | 'toggle' | 'transfer' | 'unregister' | 'update' | 'upload' | 'use' | 'validate' | 'view' | 'visit' | 'wait' | 'warn' | 'exit';
|
|
15
15
|
export type MetricEventJoinFlowVersion = 'Other' | 'NewFTE';
|
|
@@ -136,6 +136,12 @@ export type SubmitOperationalEvent = (args: {
|
|
|
136
136
|
name: OperationalEvent['metricName'];
|
|
137
137
|
payload: EventPayload;
|
|
138
138
|
}) => void;
|
|
139
|
+
export type SubmitBusinessEvent = (args: {
|
|
140
|
+
name: OperationalEvent['metricName'];
|
|
141
|
+
payload: EventPayload;
|
|
142
|
+
metadata?: EventPayload;
|
|
143
|
+
table?: Table;
|
|
144
|
+
}) => void;
|
|
139
145
|
export type SubmitMQE = (args: {
|
|
140
146
|
name: MediaQualityEvent['name'];
|
|
141
147
|
payload: SubmitMQEPayload;
|
|
@@ -3,7 +3,7 @@ import CallDiagnosticMetrics from './call-diagnostic/call-diagnostic-metrics';
|
|
|
3
3
|
import BehavioralMetrics from './behavioral-metrics';
|
|
4
4
|
import OperationalMetrics from './operational-metrics';
|
|
5
5
|
import BusinessMetrics from './business-metrics';
|
|
6
|
-
import { RecursivePartial, MetricEventProduct, MetricEventAgent, MetricEventVerb, ClientEvent, FeatureEvent, EventPayload, MediaQualityEvent, InternalEvent, SubmitClientEventOptions, Table } from './metrics.types';
|
|
6
|
+
import { RecursivePartial, MetricEventProduct, MetricEventAgent, MetricEventVerb, ClientEvent, FeatureEvent, EventPayload, MediaQualityEvent, InternalEvent, SubmitClientEventOptions, Table, DelayedClientEvent } from './metrics.types';
|
|
7
7
|
import CallDiagnosticLatencies from './call-diagnostic/call-diagnostic-metrics-latencies';
|
|
8
8
|
/**
|
|
9
9
|
* Metrics plugin to centralize all types of metrics.
|
|
@@ -22,6 +22,10 @@ declare class Metrics extends WebexPlugin {
|
|
|
22
22
|
* Whether or not to delay the submission of client events.
|
|
23
23
|
*/
|
|
24
24
|
delaySubmitClientEvents: boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Overrides for delayed client events. E.g. if you want to override the correlationId for all delayed client events, you can set this to { correlationId: 'newCorrelationId' }
|
|
27
|
+
*/
|
|
28
|
+
delayedClientEventsOverrides: Partial<DelayedClientEvent['options']>;
|
|
25
29
|
/**
|
|
26
30
|
* Constructor
|
|
27
31
|
* @param args
|
|
@@ -178,8 +182,11 @@ declare class Metrics extends WebexPlugin {
|
|
|
178
182
|
* Sets the value of delaySubmitClientEvents. If set to true, client events will be delayed until submitDelayedClientEvents is called. If
|
|
179
183
|
* set to false, delayed client events will be submitted.
|
|
180
184
|
*
|
|
181
|
-
* @param {
|
|
185
|
+
* @param {object} options - {shouldDelay: A boolean value indicating whether to delay the submission of client events, overrides: An object containing overrides for the client events}
|
|
182
186
|
*/
|
|
183
|
-
setDelaySubmitClientEvents(shouldDelay
|
|
187
|
+
setDelaySubmitClientEvents({ shouldDelay, overrides, }: {
|
|
188
|
+
shouldDelay: boolean;
|
|
189
|
+
overrides?: Partial<DelayedClientEvent['options']>;
|
|
190
|
+
}): Promise<any[]> | Promise<void>;
|
|
184
191
|
}
|
|
185
192
|
export default Metrics;
|
package/package.json
CHANGED
|
@@ -26,22 +26,22 @@
|
|
|
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.8.0-next.
|
|
30
|
-
"@webex/test-helper-mocha": "3.8.0-next.
|
|
31
|
-
"@webex/test-helper-mock-webex": "3.8.0-next.
|
|
32
|
-
"@webex/test-helper-test-users": "3.8.0-next.
|
|
29
|
+
"@webex/test-helper-chai": "3.8.0-next.21",
|
|
30
|
+
"@webex/test-helper-mocha": "3.8.0-next.21",
|
|
31
|
+
"@webex/test-helper-mock-webex": "3.8.0-next.21",
|
|
32
|
+
"@webex/test-helper-test-users": "3.8.0-next.21",
|
|
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.8.0-next.
|
|
39
|
-
"@webex/common-timers": "3.8.0-next.
|
|
40
|
-
"@webex/event-dictionary-ts": "^1.0.
|
|
41
|
-
"@webex/internal-plugin-metrics": "3.8.0-next.
|
|
42
|
-
"@webex/test-helper-chai": "3.8.0-next.
|
|
43
|
-
"@webex/test-helper-mock-webex": "3.8.0-next.
|
|
44
|
-
"@webex/webex-core": "3.8.0-next.
|
|
38
|
+
"@webex/common": "3.8.0-next.21",
|
|
39
|
+
"@webex/common-timers": "3.8.0-next.21",
|
|
40
|
+
"@webex/event-dictionary-ts": "^1.0.1753",
|
|
41
|
+
"@webex/internal-plugin-metrics": "3.8.0-next.21",
|
|
42
|
+
"@webex/test-helper-chai": "3.8.0-next.21",
|
|
43
|
+
"@webex/test-helper-mock-webex": "3.8.0-next.21",
|
|
44
|
+
"@webex/webex-core": "3.8.0-next.21",
|
|
45
45
|
"ip-anonymize": "^0.1.0",
|
|
46
46
|
"lodash": "^4.17.21",
|
|
47
47
|
"uuid": "^3.3.2"
|
|
@@ -54,5 +54,5 @@
|
|
|
54
54
|
"test:style": "eslint ./src/**/*.*",
|
|
55
55
|
"test:unit": "webex-legacy-tools test --unit --runner mocha"
|
|
56
56
|
},
|
|
57
|
-
"version": "3.8.0-next.
|
|
57
|
+
"version": "3.8.0-next.21"
|
|
58
58
|
}
|
|
@@ -97,6 +97,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
97
97
|
private hasLoggedBrowserSerial: boolean;
|
|
98
98
|
private device: any;
|
|
99
99
|
private delayedClientEvents: DelayedClientEvent[] = [];
|
|
100
|
+
private eventErrorCache: WeakMap<any, any> = new WeakMap();
|
|
100
101
|
|
|
101
102
|
// the default validator before piping an event to the batcher
|
|
102
103
|
// this function can be overridden by the user
|
|
@@ -166,23 +167,17 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
166
167
|
if (meetingInfo?.webexScheduled && !meetingInfo?.enableEvent && !meetingInfo?.pmr) {
|
|
167
168
|
return WEBEX_SUB_SERVICE_TYPES.SCHEDULED_MEETING;
|
|
168
169
|
}
|
|
169
|
-
|
|
170
|
-
if
|
|
171
|
-
|
|
172
|
-
meetingInfo?.
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
) {
|
|
176
|
-
return WEBEX_SUB_SERVICE_TYPES.WEBINAR;
|
|
170
|
+
|
|
171
|
+
// if ConvergedArchitecture enable and isConvergedWebinarWebcast -- then webcast
|
|
172
|
+
if (meetingInfo?.enableConvergedArchitecture && meetingInfo?.enableEvent) {
|
|
173
|
+
return meetingInfo?.isConvergedWebinarWebcast
|
|
174
|
+
? WEBEX_SUB_SERVICE_TYPES.WEBCAST
|
|
175
|
+
: WEBEX_SUB_SERVICE_TYPES.WEBINAR;
|
|
177
176
|
}
|
|
178
|
-
|
|
179
|
-
if
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
!meetingInfo?.pmr &&
|
|
183
|
-
meetingInfo?.isConvergedWebinarWebcast
|
|
184
|
-
) {
|
|
185
|
-
return WEBEX_SUB_SERVICE_TYPES.WEBCAST;
|
|
177
|
+
|
|
178
|
+
// if Scheduled, enable event, not pmr - then Webinar
|
|
179
|
+
if (meetingInfo?.webexScheduled && meetingInfo?.enableEvent && !meetingInfo?.pmr) {
|
|
180
|
+
return WEBEX_SUB_SERVICE_TYPES.WEBINAR;
|
|
186
181
|
}
|
|
187
182
|
}
|
|
188
183
|
|
|
@@ -561,16 +556,31 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
561
556
|
return undefined;
|
|
562
557
|
}
|
|
563
558
|
|
|
559
|
+
/**
|
|
560
|
+
* Clear the error cache
|
|
561
|
+
*/
|
|
562
|
+
clearErrorCache() {
|
|
563
|
+
this.eventErrorCache = new WeakMap();
|
|
564
|
+
}
|
|
565
|
+
|
|
564
566
|
/**
|
|
565
567
|
* Generate error payload for Client Event
|
|
566
568
|
* @param rawError
|
|
567
569
|
*/
|
|
568
570
|
generateClientEventErrorPayload(rawError: any) {
|
|
571
|
+
const cachedError = this.eventErrorCache.get(rawError);
|
|
572
|
+
|
|
573
|
+
if (cachedError) {
|
|
574
|
+
return [cachedError, true];
|
|
575
|
+
}
|
|
576
|
+
|
|
569
577
|
const rawErrorMessage = rawError.message;
|
|
570
578
|
const httpStatusCode = rawError.statusCode;
|
|
579
|
+
let payload;
|
|
580
|
+
|
|
571
581
|
if (rawError.name) {
|
|
572
582
|
if (isBrowserMediaErrorName(rawError.name)) {
|
|
573
|
-
|
|
583
|
+
payload = this.getErrorPayloadForClientErrorCode({
|
|
574
584
|
serviceErrorCode: undefined,
|
|
575
585
|
clientErrorCode: BROWSER_MEDIA_ERROR_NAME_TO_CLIENT_ERROR_CODES_MAP[rawError.name],
|
|
576
586
|
serviceErrorName: rawError.name,
|
|
@@ -580,11 +590,11 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
580
590
|
}
|
|
581
591
|
}
|
|
582
592
|
|
|
583
|
-
if (isSdpOfferCreationError(rawError)) {
|
|
593
|
+
if (isSdpOfferCreationError(rawError) && !payload) {
|
|
584
594
|
// error code is 30005, but that's not specific enough. we also need to check error.cause.type
|
|
585
595
|
const causeType = rawError.cause?.type;
|
|
586
596
|
|
|
587
|
-
|
|
597
|
+
payload = this.getErrorPayloadForClientErrorCode({
|
|
588
598
|
serviceErrorCode: undefined,
|
|
589
599
|
clientErrorCode:
|
|
590
600
|
SDP_OFFER_CREATION_ERROR_MAP[causeType] || SDP_OFFER_CREATION_ERROR_MAP.GENERAL,
|
|
@@ -602,8 +612,8 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
602
612
|
|
|
603
613
|
if (serviceErrorCode) {
|
|
604
614
|
const clientErrorCode = SERVICE_ERROR_CODES_TO_CLIENT_ERROR_CODES_MAP[serviceErrorCode];
|
|
605
|
-
if (clientErrorCode) {
|
|
606
|
-
|
|
615
|
+
if (clientErrorCode && !payload) {
|
|
616
|
+
payload = this.getErrorPayloadForClientErrorCode({
|
|
607
617
|
clientErrorCode,
|
|
608
618
|
serviceErrorCode,
|
|
609
619
|
rawErrorMessage,
|
|
@@ -612,8 +622,8 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
612
622
|
}
|
|
613
623
|
|
|
614
624
|
// by default, if it is locus error, return new locus err
|
|
615
|
-
if (isLocusServiceErrorCode(serviceErrorCode)) {
|
|
616
|
-
|
|
625
|
+
if (isLocusServiceErrorCode(serviceErrorCode) && !payload) {
|
|
626
|
+
payload = this.getErrorPayloadForClientErrorCode({
|
|
617
627
|
clientErrorCode: NEW_LOCUS_ERROR_CLIENT_CODE,
|
|
618
628
|
serviceErrorCode,
|
|
619
629
|
rawErrorMessage,
|
|
@@ -622,8 +632,8 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
622
632
|
}
|
|
623
633
|
}
|
|
624
634
|
|
|
625
|
-
if (isMeetingInfoServiceError(rawError)) {
|
|
626
|
-
|
|
635
|
+
if (isMeetingInfoServiceError(rawError) && !payload) {
|
|
636
|
+
payload = this.getErrorPayloadForClientErrorCode({
|
|
627
637
|
clientErrorCode: MEETING_INFO_LOOKUP_ERROR_CLIENT_CODE,
|
|
628
638
|
serviceErrorCode,
|
|
629
639
|
rawErrorMessage,
|
|
@@ -631,8 +641,8 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
631
641
|
});
|
|
632
642
|
}
|
|
633
643
|
|
|
634
|
-
if (isNetworkError(rawError)) {
|
|
635
|
-
|
|
644
|
+
if (isNetworkError(rawError) && !payload) {
|
|
645
|
+
payload = this.getErrorPayloadForClientErrorCode({
|
|
636
646
|
clientErrorCode: NETWORK_ERROR,
|
|
637
647
|
serviceErrorCode,
|
|
638
648
|
payloadOverrides: rawError.payloadOverrides,
|
|
@@ -641,8 +651,8 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
641
651
|
});
|
|
642
652
|
}
|
|
643
653
|
|
|
644
|
-
if (isUnauthorizedError(rawError)) {
|
|
645
|
-
|
|
654
|
+
if (isUnauthorizedError(rawError) && !payload) {
|
|
655
|
+
payload = this.getErrorPayloadForClientErrorCode({
|
|
646
656
|
clientErrorCode: AUTHENTICATION_FAILED_CODE,
|
|
647
657
|
serviceErrorCode,
|
|
648
658
|
payloadOverrides: rawError.payloadOverrides,
|
|
@@ -651,15 +661,22 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
651
661
|
});
|
|
652
662
|
}
|
|
653
663
|
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
664
|
+
if (!payload) {
|
|
665
|
+
// otherwise return unkown error but passing serviceErrorCode and serviceErrorName so that we know the issue
|
|
666
|
+
payload = this.getErrorPayloadForClientErrorCode({
|
|
667
|
+
clientErrorCode: UNKNOWN_ERROR,
|
|
668
|
+
serviceErrorCode: serviceErrorCode || UNKNOWN_ERROR,
|
|
669
|
+
serviceErrorName: rawError?.name,
|
|
670
|
+
payloadOverrides: rawError.payloadOverrides,
|
|
671
|
+
rawErrorMessage,
|
|
672
|
+
httpStatusCode,
|
|
673
|
+
});
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
// cache the payload for future use
|
|
677
|
+
this.eventErrorCache.set(rawError, payload);
|
|
678
|
+
|
|
679
|
+
return [payload, false];
|
|
663
680
|
}
|
|
664
681
|
|
|
665
682
|
/**
|
|
@@ -742,6 +759,10 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
742
759
|
if (joinFlowVersion) {
|
|
743
760
|
clientEventObject.joinFlowVersion = joinFlowVersion;
|
|
744
761
|
}
|
|
762
|
+
const meetingJoinedTime = meeting.isoLocalClientMeetingJoinTime;
|
|
763
|
+
if (meetingJoinedTime) {
|
|
764
|
+
clientEventObject.meetingJoinedTime = meetingJoinedTime;
|
|
765
|
+
}
|
|
745
766
|
|
|
746
767
|
if (options.meetingJoinPhase) {
|
|
747
768
|
clientEventObject.meetingJoinPhase = options.meetingJoinPhase;
|
|
@@ -836,14 +857,14 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
836
857
|
const errors: ClientEventPayloadError = [];
|
|
837
858
|
|
|
838
859
|
if (rawError) {
|
|
839
|
-
const generatedError = this.generateClientEventErrorPayload(rawError);
|
|
860
|
+
const [generatedError, cached] = this.generateClientEventErrorPayload(rawError);
|
|
840
861
|
if (generatedError) {
|
|
841
862
|
errors.push(generatedError);
|
|
842
863
|
}
|
|
843
864
|
this.logger.log(
|
|
844
865
|
CALL_DIAGNOSTIC_LOG_IDENTIFIER,
|
|
845
866
|
'CallDiagnosticMetrics: @prepareClientEvent. Generated errors:',
|
|
846
|
-
`generatedError: ${JSON.stringify(generatedError)}`
|
|
867
|
+
`generatedError (cached: ${cached}): ${JSON.stringify(generatedError)}`
|
|
847
868
|
);
|
|
848
869
|
}
|
|
849
870
|
|
|
@@ -921,7 +942,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
921
942
|
/**
|
|
922
943
|
* Submit Delayed Client Event CA events. Clears delayedClientEvents array after submission.
|
|
923
944
|
*/
|
|
924
|
-
public submitDelayedClientEvents() {
|
|
945
|
+
public submitDelayedClientEvents(overrides?: Partial<DelayedClientEvent['options']>) {
|
|
925
946
|
this.logger.log(
|
|
926
947
|
CALL_DIAGNOSTIC_LOG_IDENTIFIER,
|
|
927
948
|
'CallDiagnosticMetrics: @submitDelayedClientEvents. Submitting delayed client events.'
|
|
@@ -932,7 +953,10 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
932
953
|
}
|
|
933
954
|
|
|
934
955
|
const promises = this.delayedClientEvents.map((delayedSubmitClientEventParams) => {
|
|
935
|
-
|
|
956
|
+
const {name, payload, options} = delayedSubmitClientEventParams;
|
|
957
|
+
const optionsWithOverrides: DelayedClientEvent['options'] = {...options, ...overrides};
|
|
958
|
+
|
|
959
|
+
return this.submitClientEvent({name, payload, options: optionsWithOverrides});
|
|
936
960
|
});
|
|
937
961
|
|
|
938
962
|
this.delayedClientEvents = [];
|
|
@@ -133,6 +133,7 @@ export const ERROR_DESCRIPTIONS = {
|
|
|
133
133
|
SDP_OFFER_CREATION_ERROR: 'SdpOfferCreationError',
|
|
134
134
|
SDP_OFFER_CREATION_ERROR_MISSING_CODEC: 'SdpOfferCreationErrorMissingCodec',
|
|
135
135
|
WDM_RESTRICTED_REGION: 'WdmRestrictedRegion',
|
|
136
|
+
USER_NOT_ALLOWED_JOIN_WEBINAR: 'UserNotAllowedJoinWebinar',
|
|
136
137
|
};
|
|
137
138
|
|
|
138
139
|
export const SERVICE_ERROR_CODES_TO_CLIENT_ERROR_CODES_MAP = {
|
|
@@ -151,6 +152,10 @@ export const SERVICE_ERROR_CODES_TO_CLIENT_ERROR_CODES_MAP = {
|
|
|
151
152
|
403004: 4005,
|
|
152
153
|
// Wrong password. Meeting is not allow to access since password error
|
|
153
154
|
403028: 4005,
|
|
155
|
+
// meeting is not allow to access since require panelist password
|
|
156
|
+
403025: 4005,
|
|
157
|
+
// wrong password. Meeting is not allow to access since panelist password error
|
|
158
|
+
403125: 4005,
|
|
154
159
|
// Wrong or expired permission. Meeting is not allow to access since permissionToken error or expire
|
|
155
160
|
403032: 4005,
|
|
156
161
|
// Meeting is required login for current user
|
|
@@ -202,6 +207,22 @@ export const SERVICE_ERROR_CODES_TO_CLIENT_ERROR_CODES_MAP = {
|
|
|
202
207
|
423013: 4005,
|
|
203
208
|
// Too many requests access
|
|
204
209
|
429005: 4100,
|
|
210
|
+
// Webinar: Meeting registration is required
|
|
211
|
+
403021: 4104,
|
|
212
|
+
// Webinar: Meeting registration is still pending
|
|
213
|
+
403022: 4104,
|
|
214
|
+
// Webinar: Meeting registration have been rejected
|
|
215
|
+
403024: 4104,
|
|
216
|
+
// Webinar: Registration ID verified failure
|
|
217
|
+
403137: 4104,
|
|
218
|
+
// Webinar: Registration ID input too many time,please input captcha code
|
|
219
|
+
423007: 4104,
|
|
220
|
+
// Webinar: Need to join meeting via webcast
|
|
221
|
+
403026: 4104,
|
|
222
|
+
// Webinar: Meeting join required registration ID
|
|
223
|
+
403037: 4104,
|
|
224
|
+
// Not reach JBH, can't join meeting
|
|
225
|
+
403003: 4101,
|
|
205
226
|
|
|
206
227
|
// ---- Locus ------
|
|
207
228
|
// FREE_USER_MAX_PARTICIPANTS_EXCEEDED
|
|
@@ -666,6 +687,11 @@ export const CLIENT_ERROR_CODE_TO_ERROR_PAYLOAD: Record<number, Partial<ClientEv
|
|
|
666
687
|
category: 'expected',
|
|
667
688
|
fatal: true,
|
|
668
689
|
},
|
|
690
|
+
4104: {
|
|
691
|
+
errorDescription: ERROR_DESCRIPTIONS.USER_NOT_ALLOWED_JOIN_WEBINAR,
|
|
692
|
+
category: 'expected',
|
|
693
|
+
fatal: true,
|
|
694
|
+
},
|
|
669
695
|
2729: {
|
|
670
696
|
errorDescription: ERROR_DESCRIPTIONS.NO_MEDIA_FOUND,
|
|
671
697
|
category: 'expected',
|
package/src/index.ts
CHANGED
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
SubmitClientEvent,
|
|
16
16
|
SubmitInternalEvent,
|
|
17
17
|
SubmitOperationalEvent,
|
|
18
|
+
SubmitBusinessEvent,
|
|
18
19
|
SubmitMQE,
|
|
19
20
|
PreComputedLatencies,
|
|
20
21
|
} from './metrics.types';
|
|
@@ -58,5 +59,6 @@ export type {
|
|
|
58
59
|
SubmitInternalEvent,
|
|
59
60
|
SubmitMQE,
|
|
60
61
|
SubmitOperationalEvent,
|
|
62
|
+
SubmitBusinessEvent,
|
|
61
63
|
PreComputedLatencies,
|
|
62
64
|
};
|
package/src/metrics.types.ts
CHANGED
|
@@ -24,7 +24,7 @@ export type BrowserLaunchMethodType = NonNullable<
|
|
|
24
24
|
RawEvent['origin']['clientInfo']
|
|
25
25
|
>['browserLaunchMethod'];
|
|
26
26
|
|
|
27
|
-
export type MetricEventProduct = 'webex' | 'wxcc_desktop' | 'wxcc_crm';
|
|
27
|
+
export type MetricEventProduct = 'webex' | 'wxcc_desktop' | 'wxcc_crm' | 'wxcc_sdk';
|
|
28
28
|
|
|
29
29
|
export type MetricEventAgent = 'user' | 'browser' | 'system' | 'sdk' | 'redux' | 'service' | 'api';
|
|
30
30
|
|
|
@@ -287,6 +287,13 @@ export type SubmitOperationalEvent = (args: {
|
|
|
287
287
|
payload: EventPayload;
|
|
288
288
|
}) => void;
|
|
289
289
|
|
|
290
|
+
export type SubmitBusinessEvent = (args: {
|
|
291
|
+
name: OperationalEvent['metricName'];
|
|
292
|
+
payload: EventPayload;
|
|
293
|
+
metadata?: EventPayload;
|
|
294
|
+
table?: Table;
|
|
295
|
+
}) => void;
|
|
296
|
+
|
|
290
297
|
export type SubmitMQE = (args: {
|
|
291
298
|
name: MediaQualityEvent['name'];
|
|
292
299
|
payload: SubmitMQEPayload;
|
package/src/new-metrics.ts
CHANGED
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
InternalEvent,
|
|
23
23
|
SubmitClientEventOptions,
|
|
24
24
|
Table,
|
|
25
|
+
DelayedClientEvent,
|
|
25
26
|
} from './metrics.types';
|
|
26
27
|
import CallDiagnosticLatencies from './call-diagnostic/call-diagnostic-metrics-latencies';
|
|
27
28
|
import {setMetricTimings} from './call-diagnostic/call-diagnostic-metrics.util';
|
|
@@ -50,6 +51,11 @@ class Metrics extends WebexPlugin {
|
|
|
50
51
|
*/
|
|
51
52
|
delaySubmitClientEvents = false;
|
|
52
53
|
|
|
54
|
+
/**
|
|
55
|
+
* Overrides for delayed client events. E.g. if you want to override the correlationId for all delayed client events, you can set this to { correlationId: 'newCorrelationId' }
|
|
56
|
+
*/
|
|
57
|
+
delayedClientEventsOverrides: Partial<DelayedClientEvent['options']> = {};
|
|
58
|
+
|
|
53
59
|
/**
|
|
54
60
|
* Constructor
|
|
55
61
|
* @param args
|
|
@@ -74,6 +80,10 @@ class Metrics extends WebexPlugin {
|
|
|
74
80
|
// @ts-ignore
|
|
75
81
|
this.callDiagnosticMetrics = new CallDiagnosticMetrics({}, {parent: this.webex});
|
|
76
82
|
this.isReady = true;
|
|
83
|
+
this.setDelaySubmitClientEvents({
|
|
84
|
+
shouldDelay: this.delaySubmitClientEvents,
|
|
85
|
+
overrides: this.delayedClientEventsOverrides,
|
|
86
|
+
});
|
|
77
87
|
});
|
|
78
88
|
}
|
|
79
89
|
|
|
@@ -404,13 +414,20 @@ class Metrics extends WebexPlugin {
|
|
|
404
414
|
* Sets the value of delaySubmitClientEvents. If set to true, client events will be delayed until submitDelayedClientEvents is called. If
|
|
405
415
|
* set to false, delayed client events will be submitted.
|
|
406
416
|
*
|
|
407
|
-
* @param {
|
|
417
|
+
* @param {object} options - {shouldDelay: A boolean value indicating whether to delay the submission of client events, overrides: An object containing overrides for the client events}
|
|
408
418
|
*/
|
|
409
|
-
public setDelaySubmitClientEvents(
|
|
419
|
+
public setDelaySubmitClientEvents({
|
|
420
|
+
shouldDelay,
|
|
421
|
+
overrides,
|
|
422
|
+
}: {
|
|
423
|
+
shouldDelay: boolean;
|
|
424
|
+
overrides?: Partial<DelayedClientEvent['options']>;
|
|
425
|
+
}) {
|
|
410
426
|
this.delaySubmitClientEvents = shouldDelay;
|
|
427
|
+
this.delayedClientEventsOverrides = overrides || {};
|
|
411
428
|
|
|
412
|
-
if (!shouldDelay) {
|
|
413
|
-
return this.callDiagnosticMetrics.submitDelayedClientEvents();
|
|
429
|
+
if (this.isReady && !shouldDelay) {
|
|
430
|
+
return this.callDiagnosticMetrics.submitDelayedClientEvents(overrides);
|
|
414
431
|
}
|
|
415
432
|
|
|
416
433
|
return Promise.resolve();
|