@webex/internal-plugin-metrics 3.12.0-webex-services-ready.4 → 3.13.0-next.1

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 (77) hide show
  1. package/.repo-context.json +466 -0
  2. package/.sdd/manifest.json +626 -0
  3. package/AGENTS.md +208 -0
  4. package/README.md +274 -0
  5. package/dist/call-diagnostic/call-diagnostic-metrics.js +155 -94
  6. package/dist/call-diagnostic/call-diagnostic-metrics.js.map +1 -1
  7. package/dist/call-diagnostic/config.js +3 -1
  8. package/dist/call-diagnostic/config.js.map +1 -1
  9. package/dist/config.js +7 -0
  10. package/dist/config.js.map +1 -1
  11. package/dist/index.js +10 -1
  12. package/dist/index.js.map +1 -1
  13. package/dist/metrics.js +118 -5
  14. package/dist/metrics.js.map +1 -1
  15. package/dist/metrics.types.js.map +1 -1
  16. package/dist/network-telemetry.js +610 -0
  17. package/dist/network-telemetry.js.map +1 -0
  18. package/dist/new-metrics.js +47 -11
  19. package/dist/new-metrics.js.map +1 -1
  20. package/dist/privacy-and-security-permission-enricher/constants.js +18 -0
  21. package/dist/privacy-and-security-permission-enricher/constants.js.map +1 -0
  22. package/dist/privacy-and-security-permission-enricher/index.js +143 -0
  23. package/dist/privacy-and-security-permission-enricher/index.js.map +1 -0
  24. package/dist/privacy-and-security-permission-enricher/types.js +7 -0
  25. package/dist/privacy-and-security-permission-enricher/types.js.map +1 -0
  26. package/dist/privacy-and-security-permission-enricher/utils.js +71 -0
  27. package/dist/privacy-and-security-permission-enricher/utils.js.map +1 -0
  28. package/dist/types/call-diagnostic/call-diagnostic-metrics.d.ts +12 -3
  29. package/dist/types/call-diagnostic/config.d.ts +2 -0
  30. package/dist/types/config.d.ts +8 -0
  31. package/dist/types/index.d.ts +2 -2
  32. package/dist/types/metrics.types.d.ts +7 -3
  33. package/dist/types/network-telemetry.d.ts +108 -0
  34. package/dist/types/new-metrics.d.ts +13 -1
  35. package/dist/types/privacy-and-security-permission-enricher/constants.d.ts +6 -0
  36. package/dist/types/privacy-and-security-permission-enricher/index.d.ts +40 -0
  37. package/dist/types/privacy-and-security-permission-enricher/types.d.ts +14 -0
  38. package/dist/types/privacy-and-security-permission-enricher/utils.d.ts +5 -0
  39. package/dist/types/unhandled-exception-telemetry/index.d.ts +60 -0
  40. package/dist/types/unhandled-exception-telemetry/utils.d.ts +6 -0
  41. package/dist/unhandled-exception-telemetry/index.js +331 -0
  42. package/dist/unhandled-exception-telemetry/index.js.map +1 -0
  43. package/dist/unhandled-exception-telemetry/utils.js +105 -0
  44. package/dist/unhandled-exception-telemetry/utils.js.map +1 -0
  45. package/docs/adr/index.md +27 -0
  46. package/docs/architecture.md +437 -0
  47. package/docs/getting-started.md +131 -0
  48. package/docs/index.md +52 -0
  49. package/docs/specs/README.md +88 -0
  50. package/package.json +11 -11
  51. package/schemas/repo-context.schema.json +796 -0
  52. package/src/call-diagnostic/call-diagnostic-metrics.ts +100 -30
  53. package/src/call-diagnostic/config.ts +2 -0
  54. package/src/call-diagnostic/docs/README.md +535 -0
  55. package/src/config.js +7 -0
  56. package/src/docs/README.md +703 -0
  57. package/src/index.ts +11 -0
  58. package/src/metrics.js +123 -5
  59. package/src/metrics.types.ts +13 -3
  60. package/src/network-telemetry.ts +757 -0
  61. package/src/new-metrics.ts +44 -2
  62. package/src/privacy-and-security-permission-enricher/constants.ts +33 -0
  63. package/src/privacy-and-security-permission-enricher/docs/README.md +356 -0
  64. package/src/privacy-and-security-permission-enricher/index.ts +142 -0
  65. package/src/privacy-and-security-permission-enricher/types.ts +21 -0
  66. package/src/privacy-and-security-permission-enricher/utils.ts +82 -0
  67. package/src/rtcMetrics/docs/README.md +447 -0
  68. package/src/unhandled-exception-telemetry/docs/README.md +536 -0
  69. package/src/unhandled-exception-telemetry/index.ts +404 -0
  70. package/src/unhandled-exception-telemetry/utils.ts +101 -0
  71. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics.ts +485 -21
  72. package/test/unit/spec/metrics.js +14 -5
  73. package/test/unit/spec/network-telemetry.ts +610 -0
  74. package/test/unit/spec/new-metrics.ts +190 -48
  75. package/test/unit/spec/privacy-and-security-permission-enricher.ts +318 -0
  76. package/test/unit/spec/unhandled-exception-telemetry/utils.ts +109 -0
  77. package/test/unit/spec/unhandled-exception-telemetry.ts +689 -0
package/src/index.ts CHANGED
@@ -2,6 +2,8 @@
2
2
  * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
3
3
  */
4
4
 
5
+ /* eslint-disable valid-jsdoc */
6
+
5
7
  import {registerInternalPlugin} from '@webex/webex-core';
6
8
 
7
9
  import Metrics from './metrics';
@@ -21,6 +23,7 @@ import {
21
23
  PreComputedLatencies,
22
24
  SubmitFeatureEvent,
23
25
  LocusSyncLatencyEventName,
26
+ PrivacyAndSecurityPermission,
24
27
  } from './metrics.types';
25
28
  import * as CALL_DIAGNOSTIC_CONFIG from './call-diagnostic/config';
26
29
  import * as CallDiagnosticUtils from './call-diagnostic/call-diagnostic-metrics.util';
@@ -34,6 +37,13 @@ import PreLoginMetrics from './prelogin-metrics';
34
37
 
35
38
  registerInternalPlugin('metrics', Metrics, {
36
39
  config,
40
+ /**
41
+ * Stops network telemetry before SDK logout.
42
+ * @returns
43
+ */
44
+ onBeforeLogout() {
45
+ return this.stopNetworkTelemetry();
46
+ },
37
47
  });
38
48
 
39
49
  registerInternalPlugin('newMetrics', NewMetrics, {
@@ -70,4 +80,5 @@ export type {
70
80
  PreComputedLatencies,
71
81
  SubmitFeatureEvent,
72
82
  LocusSyncLatencyEventName,
83
+ PrivacyAndSecurityPermission,
73
84
  };
package/src/metrics.js CHANGED
@@ -1,4 +1,5 @@
1
1
  /* eslint-disable default-param-last */
2
+ /* eslint-disable valid-jsdoc */
2
3
 
3
4
  /*!
4
5
  * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
@@ -11,6 +12,7 @@ import {OS_NAME, OSMap, CLIENT_NAME} from './config';
11
12
  import Batcher from './batcher';
12
13
  import ClientMetricsBatcher from './client-metrics-batcher';
13
14
  import ClientMetricsPreloginBatcher from './client-metrics-prelogin-batcher';
15
+ import {createNetworkTelemetryCollector} from './network-telemetry';
14
16
 
15
17
  const {getOSName, getOSVersion, getBrowserName, getBrowserVersion} = BrowserDetection();
16
18
 
@@ -43,6 +45,119 @@ const Metrics = WebexPlugin.extend({
43
45
 
44
46
  namespace: 'Metrics',
45
47
 
48
+ /**
49
+ * Registers SDK request outcome monitoring.
50
+ * @param args
51
+ * @returns
52
+ */
53
+ initialize(...args) {
54
+ WebexPlugin.prototype.initialize.call(this, ...args);
55
+
56
+ // Metrics may also be constructed as a standalone plugin. Request events are
57
+ // available only when it is attached to a Webex instance.
58
+ if (!this.parent && !this.collection) {
59
+ return;
60
+ }
61
+
62
+ const initializeNetworkTelemetry = () => {
63
+ if (
64
+ this.networkTelemetry ||
65
+ this.webex?.config?.metrics?.networkTelemetry?.enabled !== true
66
+ ) {
67
+ return;
68
+ }
69
+
70
+ this.networkTelemetry = createNetworkTelemetryCollector({
71
+ intervalMs: this.webex.config.metrics.networkTelemetry.intervalMs,
72
+ submitMetric: this.submitNetworkTelemetryMetric.bind(this),
73
+ onSubmissionFailure: this.handleNetworkTelemetrySubmissionFailure.bind(this),
74
+ });
75
+ this.listenTo(this.webex, 'request:start', this.recordNetworkRequestStart);
76
+ this.listenTo(this.webex, 'request:success', this.recordNetworkRequestSuccess);
77
+ this.listenTo(this.webex, 'request:failure', this.recordNetworkRequestFailure);
78
+ };
79
+
80
+ // Ampersand initializes children before WebexCore.initialize() populates
81
+ // webex.config. Run immediately for already-configured hosts (including
82
+ // MockWebex), and listen for the real core's post-initialization notification.
83
+ this.listenToOnce(this.webex, 'change:config', initializeNetworkTelemetry);
84
+ initializeNetworkTelemetry();
85
+ },
86
+
87
+ /**
88
+ * Records an SDK request being sent in the current reporting window.
89
+ * @param options
90
+ * @returns
91
+ */
92
+ recordNetworkRequestStart(options) {
93
+ this.networkTelemetry.recordRequest(options);
94
+ },
95
+
96
+ /**
97
+ * Records a successful SDK request for the current reporting window.
98
+ * @param options
99
+ * @returns
100
+ */
101
+ recordNetworkRequestSuccess(options) {
102
+ this.networkTelemetry.recordResponse(options);
103
+ },
104
+
105
+ /**
106
+ * Records a failed SDK request for the current reporting window.
107
+ * @param options
108
+ * @param reason
109
+ * @returns
110
+ */
111
+ recordNetworkRequestFailure(options, reason) {
112
+ this.networkTelemetry.recordFailure(options, reason);
113
+ },
114
+
115
+ /**
116
+ * Submits the current network telemetry window immediately.
117
+ * @returns
118
+ */
119
+ flushNetworkTelemetry() {
120
+ if (!this.networkTelemetry) {
121
+ return Promise.resolve();
122
+ }
123
+
124
+ return this.networkTelemetry.flush();
125
+ },
126
+
127
+ /**
128
+ * Submits a completed network telemetry window through client metrics.
129
+ * @param name
130
+ * @param properties
131
+ * @returns
132
+ */
133
+ submitNetworkTelemetryMetric(name, properties) {
134
+ return this.submitClientMetrics(name, properties);
135
+ },
136
+
137
+ /**
138
+ * Logs a network telemetry submission failure without affecting SDK requests.
139
+ * @returns
140
+ */
141
+ handleNetworkTelemetrySubmissionFailure() {
142
+ this.webex.logger?.warn('metrics: failed to submit network request summary telemetry');
143
+ },
144
+
145
+ /**
146
+ * Stops network telemetry collection and submission.
147
+ * @returns
148
+ */
149
+ stopNetworkTelemetry() {
150
+ if (!this.networkTelemetry) {
151
+ return Promise.resolve();
152
+ }
153
+
154
+ this.stopListening(this.webex, 'request:start', this.recordNetworkRequestStart);
155
+ this.stopListening(this.webex, 'request:success', this.recordNetworkRequestSuccess);
156
+ this.stopListening(this.webex, 'request:failure', this.recordNetworkRequestFailure);
157
+
158
+ return this.networkTelemetry.stop();
159
+ },
160
+
46
161
  submit(key, value) {
47
162
  return this.batcher.request({key, ...value});
48
163
  },
@@ -60,17 +175,20 @@ const Metrics = WebexPlugin.extend({
60
175
  const payload = {metricName: eventName};
61
176
  // @ts-ignore
62
177
  const providedClientVersion = this.webex.meetings?.config?.metrics?.clientVersion;
178
+ const {appName, appVersion} = this.webex.config;
179
+ // Browser location is unavailable when the SDK runs in Node.js.
180
+ // eslint-disable-next-line no-undef
181
+ const browserLocation = typeof window !== 'undefined' ? window.location : undefined;
63
182
 
64
183
  payload.tags = {
65
184
  ...props.tags,
185
+ app_name: appName ?? 'unknown',
186
+ app_url: browserLocation?.origin || browserLocation?.hostname || 'non-browser',
187
+ app_version: appVersion ?? 'unknown',
66
188
  browser: getBrowserName(),
67
189
  os: getOSNameInternal(),
68
190
  appVersion: providedClientVersion,
69
-
70
- // Node does not like this so we need to check if it exists or not
71
- // eslint-disable-next-line no-undef
72
- domain:
73
- typeof window !== 'undefined' ? window.location.hostname || 'non-browser' : 'non-browser', // Check what else we could measure
191
+ domain: browserLocation?.hostname || 'non-browser',
74
192
  };
75
193
 
76
194
  payload.fields = {
@@ -23,6 +23,15 @@ export type ClientUserNameInput = NonNullable<RawClientEvent['userNameInput']>;
23
23
 
24
24
  export type ClientEmailInput = NonNullable<RawClientEvent['emailInput']>;
25
25
 
26
+ export type PrivacyAndSecurityPermission = NonNullable<
27
+ RawClientEvent['privacyAndSecurityPermission']
28
+ >;
29
+
30
+ export type PrivacyAndSecurityPermissionResource = keyof PrivacyAndSecurityPermission;
31
+
32
+ export type PrivacyAndSecurityPermissionState =
33
+ PrivacyAndSecurityPermission[PrivacyAndSecurityPermissionResource];
34
+
26
35
  export type BrowserLaunchMethodType = NonNullable<
27
36
  RawEvent['origin']['clientInfo']
28
37
  >['browserLaunchMethod'];
@@ -133,6 +142,7 @@ export type SubmitClientEventOptions = {
133
142
  browserLaunchMethod?: BrowserLaunchMethodType;
134
143
  webexConferenceIdStr?: string;
135
144
  globalMeetingId?: string;
145
+ locusCluster?: string;
136
146
  joinFlowVersion?: MetricEventJoinFlowVersion;
137
147
  meetingJoinPhase?: MetricEventMeetingJoinPhase;
138
148
  triggeredTime?: string;
@@ -262,10 +272,10 @@ export type ClientType = NonNullable<RawEvent['origin']['clientInfo']>['clientTy
262
272
  export type SubClientType = NonNullable<RawEvent['origin']['clientInfo']>['subClientType'];
263
273
  export type NetworkType = NonNullable<RawEvent['origin']>['networkType'];
264
274
 
265
- export type ClientSubServiceType = ClientEvent['payload']['webexSubServiceType'];
275
+ export type ClientSubServiceType = NonNullable<ClientEvent['payload']>['webexSubServiceType'];
266
276
  export type ClientEventPayload = RecursivePartial<ClientEvent['payload']>;
267
- export type ClientEventLeaveReason = ClientEvent['payload']['leaveReason'];
268
- export type ClientEventPayloadError = ClientEvent['payload']['errors'];
277
+ export type ClientEventLeaveReason = NonNullable<ClientEvent['payload']>['leaveReason'];
278
+ export type ClientEventPayloadError = NonNullable<ClientEvent['payload']>['errors'];
269
279
 
270
280
  export type ClientFeatureEventPayload = RecursivePartial<FeatureEvent['payload']>;
271
281