@webex/internal-plugin-metrics 3.5.0-next.1 → 3.5.0-next.10

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 (47) hide show
  1. package/dist/business-metrics.js +114 -7
  2. package/dist/business-metrics.js.map +1 -1
  3. package/dist/call-diagnostic/call-diagnostic-metrics-latencies.js +1 -1
  4. package/dist/call-diagnostic/call-diagnostic-metrics-latencies.js.map +1 -1
  5. package/dist/call-diagnostic/call-diagnostic-metrics.js +15 -9
  6. package/dist/call-diagnostic/call-diagnostic-metrics.js.map +1 -1
  7. package/dist/call-diagnostic/call-diagnostic-metrics.util.js +7 -2
  8. package/dist/call-diagnostic/call-diagnostic-metrics.util.js.map +1 -1
  9. package/dist/call-diagnostic/config.js +13 -3
  10. package/dist/call-diagnostic/config.js.map +1 -1
  11. package/dist/index.js +7 -0
  12. package/dist/index.js.map +1 -1
  13. package/dist/metrics.js +1 -1
  14. package/dist/metrics.types.js.map +1 -1
  15. package/dist/new-metrics.js +4 -2
  16. package/dist/new-metrics.js.map +1 -1
  17. package/dist/rtcMetrics/constants.js +11 -0
  18. package/dist/rtcMetrics/constants.js.map +1 -0
  19. package/dist/rtcMetrics/index.js +202 -0
  20. package/dist/rtcMetrics/index.js.map +1 -0
  21. package/dist/types/business-metrics.d.ts +32 -4
  22. package/dist/types/call-diagnostic/call-diagnostic-metrics.d.ts +6 -1
  23. package/dist/types/call-diagnostic/config.d.ts +3 -0
  24. package/dist/types/index.d.ts +2 -1
  25. package/dist/types/metrics.types.d.ts +1 -0
  26. package/dist/types/new-metrics.d.ts +4 -3
  27. package/dist/types/rtcMetrics/constants.d.ts +4 -0
  28. package/dist/types/rtcMetrics/index.d.ts +71 -0
  29. package/package.json +11 -11
  30. package/src/business-metrics.ts +92 -4
  31. package/src/call-diagnostic/call-diagnostic-metrics-latencies.ts +1 -1
  32. package/src/call-diagnostic/call-diagnostic-metrics.ts +13 -9
  33. package/src/call-diagnostic/call-diagnostic-metrics.util.ts +11 -5
  34. package/src/call-diagnostic/config.ts +12 -0
  35. package/src/index.ts +2 -0
  36. package/src/metrics.types.ts +2 -0
  37. package/src/new-metrics.ts +11 -2
  38. package/src/rtcMetrics/constants.ts +3 -0
  39. package/src/rtcMetrics/index.ts +186 -0
  40. package/test/unit/spec/business/business-metrics.ts +63 -1
  41. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics-batcher.ts +2 -1
  42. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics-latencies.ts +4 -6
  43. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics.ts +275 -34
  44. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics.util.ts +7 -3
  45. package/test/unit/spec/new-metrics.ts +18 -3
  46. package/test/unit/spec/prelogin-metrics-batcher.ts +3 -1
  47. package/test/unit/spec/rtcMetrics/index.ts +155 -0
@@ -0,0 +1,202 @@
1
+ "use strict";
2
+
3
+ var _typeof = require("@babel/runtime-corejs2/helpers/typeof");
4
+ var _WeakMap = require("@babel/runtime-corejs2/core-js/weak-map");
5
+ var _Object$defineProperty = require("@babel/runtime-corejs2/core-js/object/define-property");
6
+ var _Object$getOwnPropertyDescriptor = require("@babel/runtime-corejs2/core-js/object/get-own-property-descriptor");
7
+ var _interopRequireDefault = require("@babel/runtime-corejs2/helpers/interopRequireDefault");
8
+ _Object$defineProperty(exports, "__esModule", {
9
+ value: true
10
+ });
11
+ exports.default = void 0;
12
+ var _stringify = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/json/stringify"));
13
+ var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/classCallCheck"));
14
+ var _createClass2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/createClass"));
15
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/defineProperty"));
16
+ var _uuid = _interopRequireDefault(require("uuid"));
17
+ var CallDiagnosticUtils = _interopRequireWildcard(require("../call-diagnostic/call-diagnostic-metrics.util"));
18
+ var _constants = _interopRequireDefault(require("./constants"));
19
+ function _getRequireWildcardCache(e) { if ("function" != typeof _WeakMap) return null; var r = new _WeakMap(), t = new _WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
20
+ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = _Object$defineProperty && _Object$getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? _Object$getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? _Object$defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
21
+ /* eslint-disable class-methods-use-this */
22
+
23
+ var parseJsonPayload = function parseJsonPayload(payload) {
24
+ try {
25
+ if (payload && payload[0]) {
26
+ return JSON.parse(payload[0]);
27
+ }
28
+ return null;
29
+ } catch (_) {
30
+ return null;
31
+ }
32
+ };
33
+
34
+ /**
35
+ * Rtc Metrics
36
+ */
37
+ var RtcMetrics = exports.default = /*#__PURE__*/function () {
38
+ /**
39
+ * Initialize the interval.
40
+ *
41
+ * @param {object} webex - The main `webex` object.
42
+ * @param {string} meetingId - The meeting id.
43
+ * @param {string} correlationId - The correlation id.
44
+ */
45
+ function RtcMetrics(webex, meetingId, correlationId) {
46
+ (0, _classCallCheck2.default)(this, RtcMetrics);
47
+ /**
48
+ * Array of MetricData items to be sent to the metrics service.
49
+ */
50
+ (0, _defineProperty2.default)(this, "metricsQueue", []);
51
+ (0, _defineProperty2.default)(this, "intervalId", void 0);
52
+ (0, _defineProperty2.default)(this, "webex", void 0);
53
+ (0, _defineProperty2.default)(this, "meetingId", void 0);
54
+ (0, _defineProperty2.default)(this, "correlationId", void 0);
55
+ (0, _defineProperty2.default)(this, "connectionId", void 0);
56
+ (0, _defineProperty2.default)(this, "shouldSendMetricsOnNextStatsReport", void 0);
57
+ // `window` is used to prevent typescript from returning a NodeJS.Timer.
58
+ this.intervalId = window.setInterval(this.sendMetricsInQueue.bind(this), 30 * 1000);
59
+ this.meetingId = meetingId;
60
+ this.webex = webex;
61
+ this.correlationId = correlationId;
62
+ this.resetConnection();
63
+ }
64
+
65
+ /**
66
+ * Check to see if the metrics queue has any items.
67
+ *
68
+ * @returns {void}
69
+ */
70
+ (0, _createClass2.default)(RtcMetrics, [{
71
+ key: "sendMetricsInQueue",
72
+ value: function sendMetricsInQueue() {
73
+ if (this.metricsQueue.length) {
74
+ this.sendMetrics();
75
+ this.metricsQueue = [];
76
+ }
77
+ }
78
+
79
+ /**
80
+ * Forces sending metrics when we get the next stats-report
81
+ *
82
+ * This is useful for cases when something important happens that affects the media connection,
83
+ * for example when we move from lobby into the meeting.
84
+ *
85
+ * @returns {void}
86
+ */
87
+ }, {
88
+ key: "sendNextMetrics",
89
+ value: function sendNextMetrics() {
90
+ this.shouldSendMetricsOnNextStatsReport = true;
91
+ }
92
+
93
+ /**
94
+ * Add metrics items to the metrics queue.
95
+ *
96
+ * @param {object} data - An object with a payload array of metrics items.
97
+ *
98
+ * @returns {void}
99
+ */
100
+ }, {
101
+ key: "addMetrics",
102
+ value: function addMetrics(data) {
103
+ if (data.payload.length) {
104
+ if (data.name === 'stats-report') {
105
+ data.payload = data.payload.map(this.anonymizeIp);
106
+ }
107
+ this.metricsQueue.push(data);
108
+ if (this.shouldSendMetricsOnNextStatsReport && data.name === 'stats-report') {
109
+ // this is the first useful set of data (WCME gives it to us after 5s), send it out immediately
110
+ // in case the user is unhappy and closes the browser early
111
+ this.sendMetricsInQueue();
112
+ this.shouldSendMetricsOnNextStatsReport = false;
113
+ }
114
+ try {
115
+ // If a connection fails, send the rest of the metrics in queue and get a new connection id.
116
+ var parsedPayload = parseJsonPayload(data.payload);
117
+ if (data.name === 'onconnectionstatechange' && parsedPayload && parsedPayload.value === 'failed') {
118
+ this.sendMetricsInQueue();
119
+ this.resetConnection();
120
+ }
121
+ } catch (e) {
122
+ console.error(e);
123
+ }
124
+ }
125
+ }
126
+
127
+ /**
128
+ * Clear the metrics interval.
129
+ *
130
+ * @returns {void}
131
+ */
132
+ }, {
133
+ key: "closeMetrics",
134
+ value: function closeMetrics() {
135
+ this.sendMetricsInQueue();
136
+ clearInterval(this.intervalId);
137
+ }
138
+
139
+ /**
140
+ * Anonymize IP addresses.
141
+ *
142
+ * @param {array} stats - An RTCStatsReport organized into an array of strings.
143
+ * @returns {string}
144
+ */
145
+ }, {
146
+ key: "anonymizeIp",
147
+ value: function anonymizeIp(stats) {
148
+ var data = JSON.parse(stats);
149
+ // on local and remote candidates, anonymize the last 4 bits.
150
+ if (data.type === 'local-candidate' || data.type === 'remote-candidate') {
151
+ data.ip = CallDiagnosticUtils.anonymizeIPAddress(data.ip) || undefined;
152
+ data.address = CallDiagnosticUtils.anonymizeIPAddress(data.address) || undefined;
153
+ data.relatedAddress = CallDiagnosticUtils.anonymizeIPAddress(data.relatedAddress) || undefined;
154
+ }
155
+ return (0, _stringify.default)(data);
156
+ }
157
+
158
+ /**
159
+ * Set a new connection id.
160
+ *
161
+ * @returns {void}
162
+ */
163
+ }, {
164
+ key: "resetConnection",
165
+ value: function resetConnection() {
166
+ this.connectionId = _uuid.default.v4();
167
+ this.shouldSendMetricsOnNextStatsReport = true;
168
+ }
169
+
170
+ /**
171
+ * Send metrics to the metrics service.
172
+ *
173
+ * @returns {void}
174
+ */
175
+ }, {
176
+ key: "sendMetrics",
177
+ value: function sendMetrics() {
178
+ this.webex.request({
179
+ method: 'POST',
180
+ service: 'unifiedTelemetry',
181
+ resource: 'metric/v2',
182
+ headers: {
183
+ type: 'webrtcMedia',
184
+ appId: _constants.default.APP_ID
185
+ },
186
+ body: {
187
+ metrics: [{
188
+ type: 'webrtc',
189
+ version: '1.1.0',
190
+ userId: this.webex.internal.device.userId,
191
+ meetingId: this.meetingId,
192
+ correlationId: this.correlationId,
193
+ connectionId: this.connectionId,
194
+ data: this.metricsQueue
195
+ }]
196
+ }
197
+ });
198
+ }
199
+ }]);
200
+ return RtcMetrics;
201
+ }();
202
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_uuid","_interopRequireDefault","require","CallDiagnosticUtils","_interopRequireWildcard","_constants","_getRequireWildcardCache","e","_WeakMap","r","t","__esModule","_typeof","default","has","get","n","__proto__","a","_Object$defineProperty","_Object$getOwnPropertyDescriptor","u","Object","prototype","hasOwnProperty","call","i","set","parseJsonPayload","payload","JSON","parse","_","RtcMetrics","exports","webex","meetingId","correlationId","_classCallCheck2","_defineProperty2","intervalId","window","setInterval","sendMetricsInQueue","bind","resetConnection","_createClass2","key","value","metricsQueue","length","sendMetrics","sendNextMetrics","shouldSendMetricsOnNextStatsReport","addMetrics","data","name","map","anonymizeIp","push","parsedPayload","console","error","closeMetrics","clearInterval","stats","type","ip","anonymizeIPAddress","undefined","address","relatedAddress","_stringify","connectionId","uuid","v4","request","method","service","resource","headers","appId","RTC_METRICS","APP_ID","body","metrics","version","userId","internal","device"],"sources":["index.ts"],"sourcesContent":["/* eslint-disable class-methods-use-this */\nimport uuid from 'uuid';\nimport * as CallDiagnosticUtils from '../call-diagnostic/call-diagnostic-metrics.util';\nimport RTC_METRICS from './constants';\n\nconst parseJsonPayload = (payload: any[]): any | null => {\n try {\n if (payload && payload[0]) {\n return JSON.parse(payload[0]);\n }\n\n return null;\n } catch (_) {\n return null;\n }\n};\n\n/**\n * Rtc Metrics\n */\nexport default class RtcMetrics {\n /**\n * Array of MetricData items to be sent to the metrics service.\n */\n metricsQueue = [];\n\n intervalId: number;\n\n webex: any;\n\n meetingId: string;\n\n correlationId: string;\n\n connectionId: string;\n\n shouldSendMetricsOnNextStatsReport: boolean;\n\n /**\n * Initialize the interval.\n *\n * @param {object} webex - The main `webex` object.\n * @param {string} meetingId - The meeting id.\n * @param {string} correlationId - The correlation id.\n */\n constructor(webex, meetingId, correlationId) {\n // `window` is used to prevent typescript from returning a NodeJS.Timer.\n this.intervalId = window.setInterval(this.sendMetricsInQueue.bind(this), 30 * 1000);\n this.meetingId = meetingId;\n this.webex = webex;\n this.correlationId = correlationId;\n this.resetConnection();\n }\n\n /**\n * Check to see if the metrics queue has any items.\n *\n * @returns {void}\n */\n public sendMetricsInQueue() {\n if (this.metricsQueue.length) {\n this.sendMetrics();\n this.metricsQueue = [];\n }\n }\n\n /**\n * Forces sending metrics when we get the next stats-report\n *\n * This is useful for cases when something important happens that affects the media connection,\n * for example when we move from lobby into the meeting.\n *\n * @returns {void}\n */\n public sendNextMetrics() {\n this.shouldSendMetricsOnNextStatsReport = true;\n }\n\n /**\n * Add metrics items to the metrics queue.\n *\n * @param {object} data - An object with a payload array of metrics items.\n *\n * @returns {void}\n */\n addMetrics(data) {\n if (data.payload.length) {\n if (data.name === 'stats-report') {\n data.payload = data.payload.map(this.anonymizeIp);\n }\n\n this.metricsQueue.push(data);\n\n if (this.shouldSendMetricsOnNextStatsReport && data.name === 'stats-report') {\n // this is the first useful set of data (WCME gives it to us after 5s), send it out immediately\n // in case the user is unhappy and closes the browser early\n this.sendMetricsInQueue();\n this.shouldSendMetricsOnNextStatsReport = false;\n }\n\n try {\n // If a connection fails, send the rest of the metrics in queue and get a new connection id.\n const parsedPayload = parseJsonPayload(data.payload);\n if (\n data.name === 'onconnectionstatechange' &&\n parsedPayload &&\n parsedPayload.value === 'failed'\n ) {\n this.sendMetricsInQueue();\n this.resetConnection();\n }\n } catch (e) {\n console.error(e);\n }\n }\n }\n\n /**\n * Clear the metrics interval.\n *\n * @returns {void}\n */\n closeMetrics() {\n this.sendMetricsInQueue();\n clearInterval(this.intervalId);\n }\n\n /**\n * Anonymize IP addresses.\n *\n * @param {array} stats - An RTCStatsReport organized into an array of strings.\n * @returns {string}\n */\n anonymizeIp(stats: string): string {\n const data = JSON.parse(stats);\n // on local and remote candidates, anonymize the last 4 bits.\n if (data.type === 'local-candidate' || data.type === 'remote-candidate') {\n data.ip = CallDiagnosticUtils.anonymizeIPAddress(data.ip) || undefined;\n data.address = CallDiagnosticUtils.anonymizeIPAddress(data.address) || undefined;\n data.relatedAddress =\n CallDiagnosticUtils.anonymizeIPAddress(data.relatedAddress) || undefined;\n }\n\n return JSON.stringify(data);\n }\n\n /**\n * Set a new connection id.\n *\n * @returns {void}\n */\n private resetConnection() {\n this.connectionId = uuid.v4();\n this.shouldSendMetricsOnNextStatsReport = true;\n }\n\n /**\n * Send metrics to the metrics service.\n *\n * @returns {void}\n */\n private sendMetrics() {\n this.webex.request({\n method: 'POST',\n service: 'unifiedTelemetry',\n resource: 'metric/v2',\n headers: {\n type: 'webrtcMedia',\n appId: RTC_METRICS.APP_ID,\n },\n body: {\n metrics: [\n {\n type: 'webrtc',\n version: '1.1.0',\n userId: this.webex.internal.device.userId,\n meetingId: this.meetingId,\n correlationId: this.correlationId,\n connectionId: this.connectionId,\n data: this.metricsQueue,\n },\n ],\n },\n });\n }\n}\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import GenericMetrics from './generic-metrics';
2
- import { EventPayload } from './metrics.types';
2
+ import { EventPayload, Table } from './metrics.types';
3
3
  /**
4
4
  * @description Util class to handle Buisness Metrics
5
5
  * @export
@@ -7,13 +7,41 @@ import { EventPayload } from './metrics.types';
7
7
  */
8
8
  export default class BusinessMetrics extends GenericMetrics {
9
9
  /**
10
- * Submit a buisness metric to our metrics endpoint.
10
+ * unfortunately, the pinot team does not allow changes to the schema of wbxapp_callend_metrics
11
+ * so we have to shim this layer specifically for this
12
+ * @param {EventPayload} payload payload of the metric
13
+ * @returns {Promise<any>}
14
+ */
15
+ private submitCallEndEvent;
16
+ /**
17
+ * Submit a buisness metric to our metrics endpoint, going to the default business_ucf table
18
+ * all event payload keys are converted into a hex string value
19
+ * unfortunately, the pinot team does not allow changes to the schema of business_metrics
20
+ * so we have to shim this layer specifically for this
21
+ * @param {string} name of the metric
22
+ * @param {EventPayload} payload payload of the metric
23
+ * @returns {Promise<any>}
24
+ */
25
+ private submitBusinessMetricsEvent;
26
+ /**
27
+ * Submit a buisness metric to our metrics endpoint, going to the default business_ucf table
28
+ * all event payload keys are converted into a hex string value
11
29
  * @param {string} name of the metric
12
30
  * @param {EventPayload} user payload of the metric
13
31
  * @returns {Promise<any>}
14
32
  */
15
- submitBusinessEvent({ name, payload }: {
33
+ private submitDefaultEvent;
34
+ /**
35
+ * Submit a buisness metric to our metrics endpoint.
36
+ * routes to the correct table with the correct schema payload by table
37
+ * @param {string} name of the metric, ignored if going to wbxapp_callend_metrics
38
+ * @param {EventPayload} payload user payload of the metric
39
+ * @param {Table} table optional - to submit the metric to and adapt the sent schema
40
+ * @returns {Promise<any>}
41
+ */
42
+ submitBusinessEvent({ name, payload, table, }: {
16
43
  name: string;
17
44
  payload: EventPayload;
18
- }): void;
45
+ table?: Table;
46
+ }): Promise<void>;
19
47
  }
@@ -116,7 +116,12 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
116
116
  cpuInfo?: {
117
117
  description: string;
118
118
  numberOfCores: number;
119
- architecture: "unknown" | "intel32" | "intel64" | "amd32" | "amd64" | "arm32" | "arm64";
119
+ architecture: "unknown" | "intel32" | "intel64" | "amd32" | "amd64" | "arm32" | "arm64"; /**
120
+ * Get origin object for Call Diagnostic Event payload.
121
+ * @param options
122
+ * @param meetingId
123
+ * @returns
124
+ */
120
125
  staticPerformance?: string;
121
126
  clockSpeedGigaHertz?: number;
122
127
  additionalProperties?: false;
@@ -96,6 +96,7 @@ export declare const ERROR_DESCRIPTIONS: {
96
96
  ICE_AND_REACHABILITY_FAILED: string;
97
97
  SDP_OFFER_CREATION_ERROR: string;
98
98
  SDP_OFFER_CREATION_ERROR_MISSING_CODEC: string;
99
+ WDM_RESTRICTED_REGION: string;
99
100
  };
100
101
  export declare const SERVICE_ERROR_CODES_TO_CLIENT_ERROR_CODES_MAP: {
101
102
  58400: number;
@@ -175,6 +176,8 @@ export declare const SERVICE_ERROR_CODES_TO_CLIENT_ERROR_CODES_MAP: {
175
176
  100006: number;
176
177
  100005: number;
177
178
  100004: number;
179
+ 4404002: number;
180
+ 4404003: number;
178
181
  };
179
182
  export declare const CLIENT_ERROR_CODE_TO_ERROR_PAYLOAD: Record<number, Partial<ClientEventError>>;
180
183
  export declare const CALL_DIAGNOSTIC_EVENT_FAILED_TO_SEND = "js_sdk_call_diagnostic_event_failed_to_send";
@@ -12,6 +12,7 @@ import CallDiagnosticLatencies from './call-diagnostic/call-diagnostic-metrics-l
12
12
  import BehavioralMetrics from './behavioral-metrics';
13
13
  import OperationalMetrics from './operational-metrics';
14
14
  import BusinessMetrics from './business-metrics';
15
+ import RtcMetrics from './rtcMetrics';
15
16
  export { default, getOSNameInternal } from './metrics';
16
- export { config, CALL_DIAGNOSTIC_CONFIG, NewMetrics, Utils, CallDiagnosticUtils, CallDiagnosticLatencies, CallDiagnosticMetrics, BehavioralMetrics, OperationalMetrics, BusinessMetrics, };
17
+ export { config, CALL_DIAGNOSTIC_CONFIG, NewMetrics, Utils, CallDiagnosticUtils, CallDiagnosticLatencies, CallDiagnosticMetrics, BehavioralMetrics, OperationalMetrics, BusinessMetrics, RtcMetrics, };
17
18
  export type { ClientEvent, ClientEventLeaveReason, SubmitBehavioralEvent, SubmitClientEvent, SubmitInternalEvent, SubmitMQE, SubmitOperationalEvent, PreComputedLatencies, };
@@ -55,6 +55,7 @@ export interface DeviceContext {
55
55
  };
56
56
  }
57
57
  export type MetricType = 'behavioral' | 'operational' | 'business';
58
+ export type Table = 'wbxapp_callend_metrics' | 'business_metrics' | 'business_ucf' | 'default';
58
59
  type InternalEventPayload = string | number | boolean;
59
60
  export type EventPayload = Record<string, InternalEventPayload>;
60
61
  export type BehavioralEventPayload = EventPayload;
@@ -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 } from './metrics.types';
6
+ import { RecursivePartial, MetricEventProduct, MetricEventAgent, MetricEventVerb, ClientEvent, FeatureEvent, EventPayload, MediaQualityEvent, InternalEvent, SubmitClientEventOptions, Table } 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.
@@ -85,10 +85,11 @@ declare class Metrics extends WebexPlugin {
85
85
  * Buisness event
86
86
  * @param args
87
87
  */
88
- submitBusinessEvent({ name, payload }: {
88
+ submitBusinessEvent({ name, payload, table, }: {
89
89
  name: string;
90
90
  payload: EventPayload;
91
- }): void | Promise<void>;
91
+ table?: Table;
92
+ }): Promise<void>;
92
93
  /**
93
94
  * Call Analyzer: Media Quality Event
94
95
  * @param args
@@ -0,0 +1,4 @@
1
+ declare const RTC_METRICS: {
2
+ APP_ID: string;
3
+ };
4
+ export { RTC_METRICS as default };
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Rtc Metrics
3
+ */
4
+ export default class RtcMetrics {
5
+ /**
6
+ * Array of MetricData items to be sent to the metrics service.
7
+ */
8
+ metricsQueue: any[];
9
+ intervalId: number;
10
+ webex: any;
11
+ meetingId: string;
12
+ correlationId: string;
13
+ connectionId: string;
14
+ shouldSendMetricsOnNextStatsReport: boolean;
15
+ /**
16
+ * Initialize the interval.
17
+ *
18
+ * @param {object} webex - The main `webex` object.
19
+ * @param {string} meetingId - The meeting id.
20
+ * @param {string} correlationId - The correlation id.
21
+ */
22
+ constructor(webex: any, meetingId: any, correlationId: any);
23
+ /**
24
+ * Check to see if the metrics queue has any items.
25
+ *
26
+ * @returns {void}
27
+ */
28
+ sendMetricsInQueue(): void;
29
+ /**
30
+ * Forces sending metrics when we get the next stats-report
31
+ *
32
+ * This is useful for cases when something important happens that affects the media connection,
33
+ * for example when we move from lobby into the meeting.
34
+ *
35
+ * @returns {void}
36
+ */
37
+ sendNextMetrics(): void;
38
+ /**
39
+ * Add metrics items to the metrics queue.
40
+ *
41
+ * @param {object} data - An object with a payload array of metrics items.
42
+ *
43
+ * @returns {void}
44
+ */
45
+ addMetrics(data: any): void;
46
+ /**
47
+ * Clear the metrics interval.
48
+ *
49
+ * @returns {void}
50
+ */
51
+ closeMetrics(): void;
52
+ /**
53
+ * Anonymize IP addresses.
54
+ *
55
+ * @param {array} stats - An RTCStatsReport organized into an array of strings.
56
+ * @returns {string}
57
+ */
58
+ anonymizeIp(stats: string): string;
59
+ /**
60
+ * Set a new connection id.
61
+ *
62
+ * @returns {void}
63
+ */
64
+ private resetConnection;
65
+ /**
66
+ * Send metrics to the metrics service.
67
+ *
68
+ * @returns {void}
69
+ */
70
+ private sendMetrics;
71
+ }
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.5.0-next.1",
30
- "@webex/test-helper-mocha": "3.5.0-next.1",
31
- "@webex/test-helper-mock-webex": "3.5.0-next.1",
32
- "@webex/test-helper-test-users": "3.5.0-next.1",
29
+ "@webex/test-helper-chai": "3.5.0-next.10",
30
+ "@webex/test-helper-mocha": "3.5.0-next.10",
31
+ "@webex/test-helper-mock-webex": "3.5.0-next.10",
32
+ "@webex/test-helper-test-users": "3.5.0-next.10",
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.5.0-next.1",
39
- "@webex/common-timers": "3.5.0-next.1",
38
+ "@webex/common": "3.5.0-next.10",
39
+ "@webex/common-timers": "3.5.0-next.10",
40
40
  "@webex/event-dictionary-ts": "^1.0.1546",
41
- "@webex/internal-plugin-metrics": "3.5.0-next.1",
42
- "@webex/test-helper-chai": "3.5.0-next.1",
43
- "@webex/test-helper-mock-webex": "3.5.0-next.1",
44
- "@webex/webex-core": "3.5.0-next.1",
41
+ "@webex/internal-plugin-metrics": "3.5.0-next.10",
42
+ "@webex/test-helper-chai": "3.5.0-next.10",
43
+ "@webex/test-helper-mock-webex": "3.5.0-next.10",
44
+ "@webex/webex-core": "3.5.0-next.10",
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.5.0-next.1"
57
+ "version": "3.5.0-next.10"
58
58
  }
@@ -1,5 +1,5 @@
1
1
  import GenericMetrics from './generic-metrics';
2
- import {EventPayload} from './metrics.types';
2
+ import {EventPayload, Table} from './metrics.types';
3
3
 
4
4
  /**
5
5
  * @description Util class to handle Buisness Metrics
@@ -8,16 +8,71 @@ import {EventPayload} from './metrics.types';
8
8
  */
9
9
  export default class BusinessMetrics extends GenericMetrics {
10
10
  /**
11
- * Submit a buisness metric to our metrics endpoint.
11
+ * unfortunately, the pinot team does not allow changes to the schema of wbxapp_callend_metrics
12
+ * so we have to shim this layer specifically for this
13
+ * @param {EventPayload} payload payload of the metric
14
+ * @returns {Promise<any>}
15
+ */
16
+ private submitCallEndEvent({payload}: {payload: EventPayload}) {
17
+ const event = {
18
+ type: ['business'],
19
+ eventPayload: {
20
+ key: 'callEnd',
21
+ client_timestamp: Date.now(),
22
+ appType: 'Web Client',
23
+ value: {
24
+ ...payload,
25
+ },
26
+ },
27
+ };
28
+
29
+ return this.submitEvent({
30
+ kind: 'buisness-events:wbxapp_callend_metrics -> ',
31
+ name: 'wbxapp_callend_metrics',
32
+ event,
33
+ });
34
+ }
35
+
36
+ /**
37
+ * Submit a buisness metric to our metrics endpoint, going to the default business_ucf table
38
+ * all event payload keys are converted into a hex string value
39
+ * unfortunately, the pinot team does not allow changes to the schema of business_metrics
40
+ * so we have to shim this layer specifically for this
41
+ * @param {string} name of the metric
42
+ * @param {EventPayload} payload payload of the metric
43
+ * @returns {Promise<any>}
44
+ */
45
+ private submitBusinessMetricsEvent({name, payload}: {name: string; payload: EventPayload}) {
46
+ const event = {
47
+ type: ['business'],
48
+ eventPayload: {
49
+ key: name,
50
+ client_timestamp: Date.now(),
51
+ appType: 'Web Client',
52
+ value: {
53
+ ...this.getContext(),
54
+ ...this.getBrowserDetails(),
55
+ ...payload,
56
+ },
57
+ },
58
+ };
59
+
60
+ return this.submitEvent({kind: 'buisness-events:business_metrics -> ', name, event});
61
+ }
62
+
63
+ /**
64
+ * Submit a buisness metric to our metrics endpoint, going to the default business_ucf table
65
+ * all event payload keys are converted into a hex string value
12
66
  * @param {string} name of the metric
13
67
  * @param {EventPayload} user payload of the metric
14
68
  * @returns {Promise<any>}
15
69
  */
16
- public submitBusinessEvent({name, payload}: {name: string; payload: EventPayload}) {
70
+ private submitDefaultEvent({name, payload}: {name: string; payload: EventPayload}) {
17
71
  const event = {
18
72
  type: ['business'],
19
73
  eventPayload: {
20
74
  key: name,
75
+ appType: 'Web Client',
21
76
  client_timestamp: Date.now(),
22
77
  context: this.getContext(),
23
78
  browserDetails: this.getBrowserDetails(),
@@ -25,6 +80,39 @@ export default class BusinessMetrics extends GenericMetrics {
25
80
  },
26
81
  };
27
82
 
28
- this.submitEvent({kind: 'buisness-events -> ', name, event});
83
+ return this.submitEvent({kind: 'buisness-events:default -> ', name, event});
84
+ }
85
+
86
+ /**
87
+ * Submit a buisness metric to our metrics endpoint.
88
+ * routes to the correct table with the correct schema payload by table
89
+ * @param {string} name of the metric, ignored if going to wbxapp_callend_metrics
90
+ * @param {EventPayload} payload user payload of the metric
91
+ * @param {Table} table optional - to submit the metric to and adapt the sent schema
92
+ * @returns {Promise<any>}
93
+ */
94
+ public submitBusinessEvent({
95
+ name,
96
+ payload,
97
+ table,
98
+ }: {
99
+ name: string;
100
+ payload: EventPayload;
101
+ table?: Table;
102
+ }): Promise<void> {
103
+ if (!table) {
104
+ table = 'default';
105
+ }
106
+ switch (table) {
107
+ case 'wbxapp_callend_metrics':
108
+ return this.submitCallEndEvent({payload});
109
+ case 'business_metrics':
110
+ return this.submitBusinessMetricsEvent({name, payload});
111
+ case 'business_ucf':
112
+ return this.submitDefaultEvent({name, payload});
113
+ case 'default':
114
+ default:
115
+ return this.submitDefaultEvent({name, payload});
116
+ }
29
117
  }
30
118
  }
@@ -49,7 +49,7 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
49
49
  private getMeeting() {
50
50
  if (this.meetingId) {
51
51
  // @ts-ignore
52
- return this.webex.meetings.meetingCollection.get(this.meetingId);
52
+ return this.webex.meetings.getBasicMeetingInformation(this.meetingId);
53
53
  }
54
54
 
55
55
  return undefined;