@webex/internal-plugin-metrics 3.0.0-beta.3 → 3.0.0-beta.300

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 (69) hide show
  1. package/README.md +1 -3
  2. package/dist/batcher.js +5 -23
  3. package/dist/batcher.js.map +1 -1
  4. package/dist/call-diagnostic/call-diagnostic-metrics-batcher.js +66 -0
  5. package/dist/call-diagnostic/call-diagnostic-metrics-batcher.js.map +1 -0
  6. package/dist/call-diagnostic/call-diagnostic-metrics-latencies.js +456 -0
  7. package/dist/call-diagnostic/call-diagnostic-metrics-latencies.js.map +1 -0
  8. package/dist/call-diagnostic/call-diagnostic-metrics.js +798 -0
  9. package/dist/call-diagnostic/call-diagnostic-metrics.js.map +1 -0
  10. package/dist/call-diagnostic/call-diagnostic-metrics.util.js +337 -0
  11. package/dist/call-diagnostic/call-diagnostic-metrics.util.js.map +1 -0
  12. package/dist/call-diagnostic/config.js +604 -0
  13. package/dist/call-diagnostic/config.js.map +1 -0
  14. package/dist/client-metrics-batcher.js +3 -8
  15. package/dist/client-metrics-batcher.js.map +1 -1
  16. package/dist/config.js +23 -6
  17. package/dist/config.js.map +1 -1
  18. package/dist/index.js +31 -10
  19. package/dist/index.js.map +1 -1
  20. package/dist/metrics.js +43 -80
  21. package/dist/metrics.js.map +1 -1
  22. package/dist/metrics.types.js +7 -0
  23. package/dist/metrics.types.js.map +1 -0
  24. package/dist/new-metrics.js +333 -0
  25. package/dist/new-metrics.js.map +1 -0
  26. package/dist/types/batcher.d.ts +2 -0
  27. package/dist/types/call-diagnostic/call-diagnostic-metrics-batcher.d.ts +2 -0
  28. package/dist/types/call-diagnostic/call-diagnostic-metrics-latencies.d.ts +194 -0
  29. package/dist/types/call-diagnostic/call-diagnostic-metrics.d.ts +405 -0
  30. package/dist/types/call-diagnostic/call-diagnostic-metrics.util.d.ts +96 -0
  31. package/dist/types/call-diagnostic/config.d.ts +171 -0
  32. package/dist/types/client-metrics-batcher.d.ts +2 -0
  33. package/dist/types/config.d.ts +36 -0
  34. package/dist/types/index.d.ts +13 -0
  35. package/dist/types/metrics.d.ts +3 -0
  36. package/dist/types/metrics.types.d.ts +103 -0
  37. package/dist/types/new-metrics.d.ts +139 -0
  38. package/dist/types/utils.d.ts +6 -0
  39. package/dist/utils.js +27 -0
  40. package/dist/utils.js.map +1 -0
  41. package/package.json +13 -8
  42. package/src/batcher.js +34 -26
  43. package/src/call-diagnostic/call-diagnostic-metrics-batcher.ts +83 -0
  44. package/src/call-diagnostic/call-diagnostic-metrics-latencies.ts +414 -0
  45. package/src/call-diagnostic/call-diagnostic-metrics.ts +863 -0
  46. package/src/call-diagnostic/call-diagnostic-metrics.util.ts +362 -0
  47. package/src/call-diagnostic/config.ts +660 -0
  48. package/src/client-metrics-batcher.js +4 -4
  49. package/src/config.js +26 -5
  50. package/src/index.ts +43 -0
  51. package/src/metrics.js +44 -58
  52. package/src/metrics.types.ts +159 -0
  53. package/src/new-metrics.ts +317 -0
  54. package/src/utils.ts +17 -0
  55. package/test/unit/spec/batcher.js +28 -15
  56. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics-batcher.ts +465 -0
  57. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics-latencies.ts +477 -0
  58. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics.ts +1943 -0
  59. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics.util.ts +565 -0
  60. package/test/unit/spec/client-metrics-batcher.js +28 -15
  61. package/test/unit/spec/metrics.js +86 -116
  62. package/test/unit/spec/new-metrics.ts +269 -0
  63. package/test/unit/spec/utils.ts +22 -0
  64. package/tsconfig.json +6 -0
  65. package/dist/call-diagnostic-events-batcher.js +0 -70
  66. package/dist/call-diagnostic-events-batcher.js.map +0 -1
  67. package/src/call-diagnostic-events-batcher.js +0 -62
  68. package/src/index.js +0 -17
  69. package/test/unit/spec/call-diagnostic-events-batcher.js +0 -180
package/src/config.js CHANGED
@@ -8,15 +8,36 @@ export const CLIENT_NAME = 'webex-js-sdk';
8
8
  export default {
9
9
  device: {
10
10
  preDiscoveryServices: {
11
- metricsServiceUrl: process.env.METRICS_SERVICE_URL || 'https://metrics-a.wbx2.com/metrics/api/v1',
12
- metrics: process.env.METRICS_SERVICE_URL || 'https://metrics-a.wbx2.com/metrics/api/v1'
13
- }
11
+ metricsServiceUrl:
12
+ process.env.METRICS_SERVICE_URL || 'https://metrics-a.wbx2.com/metrics/api/v1',
13
+ metrics: process.env.METRICS_SERVICE_URL || 'https://metrics-a.wbx2.com/metrics/api/v1',
14
+ },
14
15
  },
15
16
  metrics: {
16
17
  appType: inBrowser ? 'browser' : 'nodejs',
17
18
  batcherWait: 500,
18
19
  batcherMaxCalls: 50,
19
20
  batcherMaxWait: 1500,
20
- batcherRetryPlateau: 32000
21
- }
21
+ batcherRetryPlateau: 32000,
22
+ waitForServiceTimeout: 15,
23
+ },
24
+ };
25
+
26
+ export const OS_NAME = {
27
+ WINDOWS: 'windows',
28
+ MAC: 'mac',
29
+ IOS: 'ios',
30
+ ANDROID: 'android',
31
+ CHROME: 'chrome',
32
+ LINUX: 'linux',
33
+ OTHERS: 'other',
34
+ };
35
+
36
+ export const OSMap = {
37
+ 'Chrome OS': OS_NAME.CHROME,
38
+ macOS: OS_NAME.MAC,
39
+ Windows: OS_NAME.WINDOWS,
40
+ iOS: OS_NAME.IOS,
41
+ Android: OS_NAME.ANDROID,
42
+ Linux: OS_NAME.LINUX,
22
43
  };
package/src/index.ts ADDED
@@ -0,0 +1,43 @@
1
+ /*!
2
+ * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
3
+ */
4
+
5
+ import '@webex/internal-plugin-device';
6
+
7
+ import {registerInternalPlugin} from '@webex/webex-core';
8
+
9
+ import Metrics from './metrics';
10
+ import config from './config';
11
+ import NewMetrics from './new-metrics';
12
+ import * as Utils from './utils';
13
+ import {
14
+ ClientEvent,
15
+ ClientEventLeaveReason,
16
+ SubmitBehavioralEvent,
17
+ SubmitClientEvent,
18
+ SubmitInternalEvent,
19
+ SubmitOperationalEvent,
20
+ SubmitMQE,
21
+ } from './metrics.types';
22
+ import * as CALL_DIAGNOSTIC_CONFIG from './call-diagnostic/config';
23
+ import * as CallDiagnosticUtils from './call-diagnostic/call-diagnostic-metrics.util';
24
+
25
+ registerInternalPlugin('metrics', Metrics, {
26
+ config,
27
+ });
28
+
29
+ registerInternalPlugin('newMetrics', NewMetrics, {
30
+ config,
31
+ });
32
+
33
+ export {default, getOSNameInternal} from './metrics';
34
+ export {config, CALL_DIAGNOSTIC_CONFIG, NewMetrics, Utils, CallDiagnosticUtils};
35
+ export type {
36
+ ClientEvent,
37
+ ClientEventLeaveReason,
38
+ SubmitBehavioralEvent,
39
+ SubmitClientEvent,
40
+ SubmitInternalEvent,
41
+ SubmitMQE,
42
+ SubmitOperationalEvent,
43
+ };
package/src/metrics.js CHANGED
@@ -1,28 +1,24 @@
1
+ /* eslint-disable default-param-last */
2
+
1
3
  /*!
2
4
  * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
3
5
  */
4
6
 
5
7
  import {WebexPlugin} from '@webex/webex-core';
6
8
  import {BrowserDetection} from '@webex/common';
9
+ import {OS_NAME, OSMap, CLIENT_NAME} from './config';
7
10
 
8
- import {CLIENT_NAME} from './config';
9
11
  import Batcher from './batcher';
10
12
  import ClientMetricsBatcher from './client-metrics-batcher';
11
- import CallDiagnosticEventsBatcher from './call-diagnostic-events-batcher';
12
13
 
13
- const {
14
- getOSName,
15
- getOSVersion,
16
- getBrowserName,
17
- getBrowserVersion
18
- } = BrowserDetection();
14
+ const {getOSName, getOSVersion, getBrowserName, getBrowserVersion} = BrowserDetection();
15
+
16
+ export function getOSNameInternal() {
17
+ return OSMap[getOSName()] ?? OS_NAME.OTHERS;
18
+ }
19
19
 
20
20
  function getSparkUserAgent(webex) {
21
- const {
22
- appName,
23
- appVersion,
24
- appPlatform
25
- } = webex?.config ?? {};
21
+ const {appName, appVersion, appPlatform} = webex?.config ?? {};
26
22
 
27
23
  let sparkUserAgent = CLIENT_NAME;
28
24
 
@@ -37,29 +33,25 @@ function getSparkUserAgent(webex) {
37
33
  return sparkUserAgent;
38
34
  }
39
35
 
40
-
41
36
  const Metrics = WebexPlugin.extend({
42
37
  children: {
43
38
  batcher: Batcher,
44
39
  clientMetricsBatcher: ClientMetricsBatcher,
45
- callDiagnosticEventsBatcher: CallDiagnosticEventsBatcher
46
40
  },
47
41
 
48
42
  namespace: 'Metrics',
49
43
 
50
44
  submit(key, value) {
51
- return this.batcher.request(Object.assign({key}, value));
45
+ return this.batcher.request({key, ...value});
52
46
  },
53
47
 
54
-
55
48
  /**
56
- * This corresponds to #sendSemiStructured() in the deprecated metrics handler
49
+ * Returns the payload for submitting client metrics.
57
50
  * @param {string} eventName
58
- * @param {Object} props
59
- * @param {string} preLoginId
60
- * @returns {Object} HttpResponse object
51
+ * @param {any} props
52
+ * @returns {any} - the payload
61
53
  */
62
- submitClientMetrics(eventName, props = {}, preLoginId) {
54
+ getClientMetricsPayload(eventName, props) {
63
55
  if (!eventName) {
64
56
  throw Error('Missing behavioral metric name. Please provide one');
65
57
  }
@@ -68,49 +60,38 @@ const Metrics = WebexPlugin.extend({
68
60
  payload.tags = {
69
61
  ...props.tags,
70
62
  browser: getBrowserName(),
71
- os: getOSName(),
63
+ os: getOSNameInternal(),
72
64
 
73
65
  // Node does not like this so we need to check if it exists or not
74
66
  // eslint-disable-next-line no-undef
75
- domain: typeof window !== 'undefined' ? window.location.hostname || 'non-browser' : 'non-browser', // Check what else we could measure
76
- client_id: this.webex.credentials.config.client_id,
77
- user_id: this.webex.internal.device.userId
67
+ domain:
68
+ typeof window !== 'undefined' ? window.location.hostname || 'non-browser' : 'non-browser', // Check what else we could measure
78
69
  };
79
70
 
80
- try {
81
- payload.tags.org_id = this.webex.credentials.getOrgId();
82
- }
83
- catch {
84
- this.logger.info('metrics: unable to get orgId');
85
- }
86
-
87
-
88
71
  payload.fields = {
89
72
  ...props.fields,
90
73
  browser_version: getBrowserVersion(),
91
74
  os_version: getOSVersion(),
92
75
  sdk_version: this.webex.version,
93
76
  platform: 'Web',
94
- spark_user_agent: getSparkUserAgent(this.webex)
77
+ spark_user_agent: getSparkUserAgent(this.webex),
78
+ client_id: this.webex.credentials.config.client_id,
95
79
  };
96
80
 
97
-
98
81
  payload.type = props.type || this.webex.config.metrics.type;
99
82
 
100
-
101
83
  payload.context = {
102
84
  ...props.context,
103
85
  app: {
104
- version: this.webex.version
86
+ version: this.webex.version,
105
87
  },
106
88
  locale: 'en-US',
107
89
  os: {
108
- name: getOSName(),
109
- version: getOSVersion()
110
- }
90
+ name: getOSNameInternal(),
91
+ version: getOSVersion(),
92
+ },
111
93
  };
112
94
 
113
-
114
95
  if (props.eventPayload) {
115
96
  payload.eventPayload = props.eventPayload;
116
97
  }
@@ -119,9 +100,22 @@ const Metrics = WebexPlugin.extend({
119
100
  // is impossible so unable to use Date.now()
120
101
  payload.timestamp = new Date().valueOf();
121
102
 
103
+ return payload;
104
+ },
105
+
106
+ /**
107
+ * This corresponds to #sendSemiStructured() in the deprecated metrics handler
108
+ * @param {string} eventName
109
+ * @param {Object} props
110
+ * @param {string} preLoginId
111
+ * @returns {Object} HttpResponse object
112
+ */
113
+ submitClientMetrics(eventName, props = {}, preLoginId) {
114
+ const payload = this.getClientMetricsPayload(eventName, props);
115
+
122
116
  if (preLoginId) {
123
117
  const _payload = {
124
- metrics: [payload]
118
+ metrics: [payload],
125
119
  };
126
120
 
127
121
  // Do not batch these because pre-login events occur during onboarding, so we will be partially blind
@@ -144,12 +138,12 @@ const Metrics = WebexPlugin.extend({
144
138
  api: 'metrics',
145
139
  resource: 'clientmetrics',
146
140
  headers: {
147
- 'x-prelogin-userid': preLoginId
141
+ 'x-prelogin-userid': preLoginId,
148
142
  },
149
143
  body: {},
150
144
  qs: {
151
- alias: true
152
- }
145
+ alias: true,
146
+ },
153
147
  });
154
148
  },
155
149
 
@@ -161,20 +155,12 @@ const Metrics = WebexPlugin.extend({
161
155
  resource: 'clientmetrics-prelogin',
162
156
  headers: {
163
157
  authorization: token.toString(),
164
- 'x-prelogin-userid': preLoginId
158
+ 'x-prelogin-userid': preLoginId,
165
159
  },
166
- body: payload
167
- }));
160
+ body: payload,
161
+ })
162
+ );
168
163
  },
169
-
170
- submitCallDiagnosticEvents(payload) {
171
- const event = {
172
- type: 'diagnostic-event',
173
- eventPayload: payload
174
- };
175
-
176
- return this.callDiagnosticEventsBatcher.request(event);
177
- }
178
164
  });
179
165
 
180
166
  export default Metrics;
@@ -0,0 +1,159 @@
1
+ import {
2
+ ClientEvent as RawClientEvent,
3
+ Event as RawEvent,
4
+ MediaQualityEvent as RawMediaQualityEvent,
5
+ } from '@webex/event-dictionary-ts';
6
+
7
+ export type Event = Omit<RawEvent, 'event'> & {event: RawClientEvent | RawMediaQualityEvent};
8
+
9
+ export type ClientEventError = NonNullable<RawClientEvent['errors']>[0];
10
+
11
+ export type EnvironmentType = NonNullable<RawEvent['origin']['environment']>;
12
+
13
+ export type NewEnvironmentType = NonNullable<RawEvent['origin']['newEnvironment']>;
14
+
15
+ export type ClientLaunchMethodType = NonNullable<
16
+ RawEvent['origin']['clientInfo']
17
+ >['clientLaunchMethod'];
18
+
19
+ export type SubmitClientEventOptions = {
20
+ meetingId?: string;
21
+ mediaConnections?: any[];
22
+ rawError?: any;
23
+ correlationId?: string;
24
+ preLoginId?: string;
25
+ environment?: EnvironmentType;
26
+ newEnvironmentType?: NewEnvironmentType;
27
+ clientLaunchMethod?: ClientLaunchMethodType;
28
+ webexConferenceIdStr?: string;
29
+ globalMeetingId?: string;
30
+ };
31
+
32
+ export type SubmitMQEOptions = {
33
+ meetingId: string;
34
+ mediaConnections?: any[];
35
+ networkType?: Event['origin']['networkType'];
36
+ webexConferenceIdStr?: string;
37
+ globalMeetingId?: string;
38
+ };
39
+
40
+ export type InternalEvent = {
41
+ name:
42
+ | 'internal.client.meetinginfo.request'
43
+ | 'internal.client.meetinginfo.response'
44
+ | 'internal.reset.join.latencies'
45
+ | 'internal.client.meeting.click.joinbutton'
46
+ | 'internal.host.meeting.participant.admitted'
47
+ | 'internal.client.meeting.interstitial-window.showed'
48
+ | 'internal.client.interstitial-window.click.joinbutton'
49
+ | 'internal.client.add-media.turn-discovery.start'
50
+ | 'internal.client.add-media.turn-discovery.end';
51
+
52
+ payload?: never;
53
+ options?: never;
54
+ };
55
+
56
+ export interface ClientEvent {
57
+ name: RawClientEvent['name'];
58
+ payload?: RawClientEvent;
59
+ options?: SubmitClientEventOptions;
60
+ }
61
+
62
+ export interface BehavioralEvent {
63
+ // TODO: not implemented
64
+ name: 'host.meeting.participant.admitted' | 'sdk.media-flow.started';
65
+ payload?: never;
66
+ options?: never;
67
+ }
68
+
69
+ export interface OperationalEvent {
70
+ // TODO: not implemented
71
+ name: never;
72
+ payload?: never;
73
+ options?: never;
74
+ }
75
+
76
+ export interface FeatureEvent {
77
+ // TODO: not implemented
78
+ name: never;
79
+ payload?: never;
80
+ options?: never;
81
+ }
82
+
83
+ export interface MediaQualityEvent {
84
+ name: RawMediaQualityEvent['name'];
85
+ payload?: RawMediaQualityEvent;
86
+ options: SubmitMQEOptions;
87
+ }
88
+
89
+ export type RecursivePartial<T> = {
90
+ [P in keyof T]?: T[P] extends (infer U)[]
91
+ ? RecursivePartial<U>[]
92
+ : T[P] extends object
93
+ ? RecursivePartial<T[P]>
94
+ : T[P];
95
+ };
96
+
97
+ export type MetricEventNames =
98
+ | InternalEvent['name']
99
+ | ClientEvent['name']
100
+ | BehavioralEvent['name']
101
+ | OperationalEvent['name']
102
+ | FeatureEvent['name']
103
+ | MediaQualityEvent['name'];
104
+
105
+ export type ClientInfo = NonNullable<RawEvent['origin']['clientInfo']>;
106
+ export type ClientType = NonNullable<RawEvent['origin']['clientInfo']>['clientType'];
107
+ export type SubClientType = NonNullable<RawEvent['origin']['clientInfo']>['subClientType'];
108
+ export type NetworkType = NonNullable<RawEvent['origin']>['networkType'];
109
+
110
+ export type ClientEventPayload = RecursivePartial<ClientEvent['payload']>;
111
+ export type ClientEventLeaveReason = ClientEvent['payload']['leaveReason'];
112
+ export type ClientEventPayloadError = ClientEvent['payload']['errors'];
113
+
114
+ export type MediaQualityEventAudioSetupDelayPayload = NonNullable<
115
+ MediaQualityEvent['payload']
116
+ >['audioSetupDelay'];
117
+ export type MediaQualityEventVideoSetupDelayPayload = NonNullable<
118
+ MediaQualityEvent['payload']
119
+ >['videoSetupDelay'];
120
+
121
+ export type SubmitMQEPayload = RecursivePartial<MediaQualityEvent['payload']> & {
122
+ intervals: NonNullable<MediaQualityEvent['payload']>['intervals'];
123
+ };
124
+
125
+ export type SubmitInternalEvent = (args: {
126
+ name: InternalEvent['name'];
127
+ payload?: RecursivePartial<InternalEvent['payload']>;
128
+ options?: any;
129
+ }) => void;
130
+
131
+ export type SubmitBehavioralEvent = (args: {
132
+ name: BehavioralEvent['name'];
133
+ payload?: RecursivePartial<BehavioralEvent['payload']>;
134
+ options?: any;
135
+ }) => void;
136
+
137
+ export type SubmitClientEvent = (args: {
138
+ name: ClientEvent['name'];
139
+ payload?: RecursivePartial<ClientEvent['payload']>;
140
+ options?: SubmitClientEventOptions;
141
+ }) => Promise<any>;
142
+
143
+ export type SubmitOperationalEvent = (args: {
144
+ name: OperationalEvent['name'];
145
+ payload?: RecursivePartial<OperationalEvent['payload']>;
146
+ options?: any;
147
+ }) => void;
148
+
149
+ export type SubmitMQE = (args: {
150
+ name: MediaQualityEvent['name'];
151
+ payload: SubmitMQEPayload;
152
+ options: any;
153
+ }) => void;
154
+
155
+ export type BuildClientEventFetchRequestOptions = (args: {
156
+ name: ClientEvent['name'];
157
+ payload?: RecursivePartial<ClientEvent['payload']>;
158
+ options?: SubmitClientEventOptions;
159
+ }) => Promise<any>;