@webex/internal-plugin-metrics 3.0.0-beta.22 → 3.0.0-beta.221

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 (67) hide show
  1. package/dist/call-diagnostic/call-diagnostic-metrics-batcher.js +56 -0
  2. package/dist/call-diagnostic/call-diagnostic-metrics-batcher.js.map +1 -0
  3. package/dist/call-diagnostic/call-diagnostic-metrics-latencies.js +451 -0
  4. package/dist/call-diagnostic/call-diagnostic-metrics-latencies.js.map +1 -0
  5. package/dist/call-diagnostic/call-diagnostic-metrics.js +645 -0
  6. package/dist/call-diagnostic/call-diagnostic-metrics.js.map +1 -0
  7. package/dist/call-diagnostic/call-diagnostic-metrics.util.js +276 -0
  8. package/dist/call-diagnostic/call-diagnostic-metrics.util.js.map +1 -0
  9. package/dist/call-diagnostic/config.js +580 -0
  10. package/dist/call-diagnostic/config.js.map +1 -0
  11. package/dist/call-diagnostic/generated-types-temp/ClientEvent.js +7 -0
  12. package/dist/call-diagnostic/generated-types-temp/ClientEvent.js.map +1 -0
  13. package/dist/call-diagnostic/generated-types-temp/Event.js +7 -0
  14. package/dist/call-diagnostic/generated-types-temp/Event.js.map +1 -0
  15. package/dist/call-diagnostic/generated-types-temp/MediaQualityEvent.js +7 -0
  16. package/dist/call-diagnostic/generated-types-temp/MediaQualityEvent.js.map +1 -0
  17. package/dist/config.js +20 -1
  18. package/dist/config.js.map +1 -1
  19. package/dist/index.js +25 -1
  20. package/dist/index.js.map +1 -1
  21. package/dist/metrics.js +30 -30
  22. package/dist/metrics.js.map +1 -1
  23. package/dist/metrics.types.js +7 -0
  24. package/dist/metrics.types.js.map +1 -0
  25. package/dist/new-metrics.js +249 -0
  26. package/dist/new-metrics.js.map +1 -0
  27. package/dist/types/batcher.d.ts +2 -0
  28. package/dist/types/call-diagnostic/call-diagnostic-metrics-batcher.d.ts +2 -0
  29. package/dist/types/call-diagnostic/call-diagnostic-metrics-latencies.d.ts +189 -0
  30. package/dist/types/call-diagnostic/call-diagnostic-metrics.d.ts +356 -0
  31. package/dist/types/call-diagnostic/call-diagnostic-metrics.util.d.ts +73 -0
  32. package/dist/types/call-diagnostic/config.d.ts +86 -0
  33. package/dist/types/call-diagnostic/generated-types-temp/ClientEvent.d.ts +1112 -0
  34. package/dist/types/call-diagnostic/generated-types-temp/Event.d.ts +4851 -0
  35. package/dist/types/call-diagnostic/generated-types-temp/MediaQualityEvent.d.ts +2121 -0
  36. package/dist/types/client-metrics-batcher.d.ts +2 -0
  37. package/dist/types/config.d.ts +35 -0
  38. package/dist/types/index.d.ts +11 -0
  39. package/dist/types/metrics.d.ts +3 -0
  40. package/dist/types/metrics.types.d.ts +95 -0
  41. package/dist/types/new-metrics.d.ts +119 -0
  42. package/package.json +12 -8
  43. package/src/call-diagnostic/call-diagnostic-metrics-batcher.ts +51 -0
  44. package/src/call-diagnostic/call-diagnostic-metrics-latencies.ts +408 -0
  45. package/src/call-diagnostic/call-diagnostic-metrics.ts +655 -0
  46. package/src/call-diagnostic/call-diagnostic-metrics.util.ts +280 -0
  47. package/src/call-diagnostic/config.ts +578 -0
  48. package/src/call-diagnostic/generated-types-temp/ClientEvent.ts +2395 -0
  49. package/src/call-diagnostic/generated-types-temp/Event.ts +7762 -0
  50. package/src/call-diagnostic/generated-types-temp/MediaQualityEvent.ts +2321 -0
  51. package/src/config.js +19 -0
  52. package/src/index.ts +41 -0
  53. package/src/metrics.js +25 -27
  54. package/src/metrics.types.ts +140 -0
  55. package/src/new-metrics.ts +223 -0
  56. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics-batcher.ts +243 -0
  57. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics-latencies.ts +474 -0
  58. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics.ts +1015 -0
  59. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics.util.ts +454 -0
  60. package/test/unit/spec/metrics.js +65 -97
  61. package/test/unit/spec/new-metrics.ts +155 -0
  62. package/tsconfig.json +6 -0
  63. package/dist/call-diagnostic-events-batcher.js +0 -60
  64. package/dist/call-diagnostic-events-batcher.js.map +0 -1
  65. package/src/call-diagnostic-events-batcher.js +0 -62
  66. package/src/index.js +0 -17
  67. package/test/unit/spec/call-diagnostic-events-batcher.js +0 -195
@@ -0,0 +1,408 @@
1
+ /* eslint-disable class-methods-use-this */
2
+ /* eslint-disable valid-jsdoc */
3
+ import {WebexPlugin} from '@webex/webex-core';
4
+
5
+ import {MetricEventNames} from '../metrics.types';
6
+
7
+ // we only care about client event and feature event for now
8
+
9
+ /**
10
+ * @description Helper class to store latencies timestamp and to calculate various latencies for CA.
11
+ * @exports
12
+ * @class CallDiagnosticLatencies
13
+ */
14
+ export default class CallDiagnosticLatencies extends WebexPlugin {
15
+ latencyTimestamps: Map<MetricEventNames, number>;
16
+ precomputedLatencies: Map<string, number>;
17
+ // meetingId that the current latencies are for
18
+ private meetingId?: string;
19
+
20
+ /**
21
+ * @constructor
22
+ */
23
+ constructor(...args) {
24
+ super(...args);
25
+ this.latencyTimestamps = new Map();
26
+ this.precomputedLatencies = new Map();
27
+ }
28
+
29
+ /**
30
+ * Clear timestamps
31
+ */
32
+ public clearTimestamps() {
33
+ this.latencyTimestamps.clear();
34
+ }
35
+
36
+ /**
37
+ * Associate current latencies with a meeting id
38
+ * @param meetingId
39
+ */
40
+ private setMeetingId(meetingId: string) {
41
+ this.meetingId = meetingId;
42
+ }
43
+
44
+ /**
45
+ * Returns the meeting object associated with current latencies
46
+ * @returns meeting object
47
+ */
48
+ private getMeeting() {
49
+ if (this.meetingId) {
50
+ // @ts-ignore
51
+ return this.webex.meetings.meetingCollection.get(this.meetingId);
52
+ }
53
+
54
+ return undefined;
55
+ }
56
+
57
+ /**
58
+ * Store timestamp value
59
+ * @param key - key
60
+ * @param value -value
61
+ * @throws
62
+ * @returns
63
+ */
64
+ public saveTimestamp({
65
+ key,
66
+ value = new Date().getTime(),
67
+ options = {},
68
+ }: {
69
+ key: MetricEventNames;
70
+ value?: number;
71
+ options?: {meetingId?: string};
72
+ }) {
73
+ // save the meetingId so we can use the meeting object in latency calculations if needed
74
+ const {meetingId} = options;
75
+ if (meetingId) {
76
+ this.setMeetingId(meetingId);
77
+ }
78
+ // for some events we're only interested in the first timestamp not last
79
+ // as these events can happen multiple times
80
+ if (key === 'client.media.rx.start' || key === 'client.media.tx.start') {
81
+ this.saveFirstTimestampOnly(key, value);
82
+ } else {
83
+ this.latencyTimestamps.set(key, value);
84
+ }
85
+ }
86
+
87
+ /**
88
+ * Store precomputed latency value
89
+ * @param key - key
90
+ * @param value -value
91
+ * @throws
92
+ * @returns
93
+ */
94
+ public saveLatency(key: string, value: number) {
95
+ this.precomputedLatencies.set(key, value);
96
+ }
97
+
98
+ /**
99
+ * Store only the first timestamp value for the given key
100
+ * @param key - key
101
+ * @param value -value
102
+ * @throws
103
+ * @returns
104
+ */
105
+ saveFirstTimestampOnly(key: MetricEventNames, value: number = new Date().getTime()) {
106
+ if (this.latencyTimestamps.has(key)) {
107
+ return;
108
+ }
109
+ this.latencyTimestamps.set(key, value);
110
+ }
111
+
112
+ /**
113
+ * Helper to calculate end - start
114
+ * @param a start
115
+ * @param b end
116
+ * @returns latency
117
+ */
118
+ public getDiffBetweenTimestamps(a: MetricEventNames, b: MetricEventNames) {
119
+ const start = this.latencyTimestamps.get(a);
120
+ const end = this.latencyTimestamps.get(b);
121
+ if (start && end) {
122
+ return end - start;
123
+ }
124
+
125
+ return undefined;
126
+ }
127
+
128
+ /**
129
+ * Meeting Info Request
130
+ * @note Meeting Info request happen not just in the join phase. CA requires
131
+ * metrics around meeting info request that are only part of join phase.
132
+ * This internal.* event is used to track the real timestamps
133
+ * (when the actual request/response happen). This is because the actual CA event is
134
+ * sent inside the join method on the meeting object based on some logic, but that's not exactly when
135
+ * those events are actually fired. The logic only confirms that they have happened, and we send them over.
136
+ * @returns - latency
137
+ */
138
+ public getMeetingInfoReqResp() {
139
+ return this.getDiffBetweenTimestamps(
140
+ 'internal.client.meetinginfo.request',
141
+ 'internal.client.meetinginfo.response'
142
+ );
143
+ }
144
+
145
+ /**
146
+ * Interstitial Time
147
+ * @returns - latency
148
+ */
149
+ public getShowInterstitialTime() {
150
+ return this.getDiffBetweenTimestamps(
151
+ 'internal.client.interstitial-window.launched',
152
+ 'internal.client.interstitial-window.click.joinbutton'
153
+ );
154
+ }
155
+
156
+ /**
157
+ * Call Init Join Request
158
+ * @returns - latency
159
+ */
160
+ public getCallInitJoinReq() {
161
+ if (this.latencyTimestamps.get('internal.client.meeting.click.joinbutton')) {
162
+ return this.getDiffBetweenTimestamps(
163
+ 'internal.client.meeting.click.joinbutton',
164
+ 'client.locus.join.request'
165
+ );
166
+ }
167
+
168
+ // for cross launch and guest flows
169
+ return this.precomputedLatencies.get('internal.call.init.join.req') || undefined;
170
+ }
171
+
172
+ /**
173
+ * Locus Join Request
174
+ * @returns - latency
175
+ */
176
+ public getJoinReqResp() {
177
+ return this.getDiffBetweenTimestamps('client.locus.join.request', 'client.locus.join.response');
178
+ }
179
+
180
+ /**
181
+ * Locus Join Response Sent Received
182
+ * @returns - latency
183
+ */
184
+ public getJoinRespSentReceived() {
185
+ // TODO: not clear SPARK-440554
186
+ return undefined;
187
+ }
188
+
189
+ /**
190
+ * Local SDP Generated Remote SDP REceived
191
+ * @returns - latency
192
+ */
193
+ public getLocalSDPGenRemoteSDPRecv() {
194
+ return this.getDiffBetweenTimestamps(
195
+ 'client.media-engine.local-sdp-generated',
196
+ 'client.media-engine.remote-sdp-received'
197
+ );
198
+ }
199
+
200
+ /**
201
+ * ICE Setup Time
202
+ * @returns - latency
203
+ */
204
+ public getICESetupTime() {
205
+ return this.getDiffBetweenTimestamps('client.ice.start', 'client.ice.end');
206
+ }
207
+
208
+ /**
209
+ * Audio ICE time
210
+ * @returns - latency
211
+ */
212
+ public getAudioICESetupTime() {
213
+ return this.getDiffBetweenTimestamps('client.ice.start', 'client.ice.end');
214
+ }
215
+
216
+ /**
217
+ * Video ICE Time
218
+ * @returns - latency
219
+ */
220
+ public getVideoICESetupTime() {
221
+ return this.getDiffBetweenTimestamps('client.ice.start', 'client.ice.end');
222
+ }
223
+
224
+ /**
225
+ * Share ICE Time
226
+ * @returns - latency
227
+ */
228
+ public getShareICESetupTime() {
229
+ return this.getDiffBetweenTimestamps('client.ice.start', 'client.ice.end');
230
+ }
231
+
232
+ /**
233
+ * Stay Lobby Time
234
+ * @returns - latency
235
+ */
236
+ public getStayLobbyTime() {
237
+ return this.getDiffBetweenTimestamps(
238
+ 'client.locus.join.response',
239
+ 'internal.host.meeting.participant.admitted'
240
+ );
241
+ }
242
+
243
+ /**
244
+ * Page JMT
245
+ * @returns - latency
246
+ */
247
+ public getPageJMT() {
248
+ return this.precomputedLatencies.get('internal.client.pageJMT') || undefined;
249
+ }
250
+
251
+ /**
252
+ * Click To Interstitial
253
+ * @returns - latency
254
+ */
255
+ public getClickToInterstitial() {
256
+ // for normal join (where green join button exists before interstitial, i.e reminder, space list etc)
257
+ if (this.latencyTimestamps.get('internal.client.meeting.click.joinbutton')) {
258
+ return this.getDiffBetweenTimestamps(
259
+ 'internal.client.meeting.click.joinbutton',
260
+ 'internal.client.meeting.interstitial-window.showed'
261
+ );
262
+ }
263
+
264
+ // for cross launch and guest flows
265
+ return this.precomputedLatencies.get('internal.click.to.interstitial') || undefined;
266
+ }
267
+
268
+ /**
269
+ * Interstitial To Join Ok
270
+ * @returns - latency
271
+ */
272
+ public getInterstitialToJoinOK() {
273
+ return this.getDiffBetweenTimestamps(
274
+ 'internal.client.interstitial-window.click.joinbutton',
275
+ 'client.locus.join.response'
276
+ );
277
+ }
278
+
279
+ /**
280
+ * Call Init To MediaEngineReady
281
+ * @returns - latency
282
+ */
283
+ public getCallInitMediaEngineReady() {
284
+ return this.getDiffBetweenTimestamps(
285
+ 'internal.client.interstitial-window.click.joinbutton',
286
+ 'client.media-engine.ready'
287
+ );
288
+ }
289
+
290
+ /**
291
+ * Interstitial To Media Ok
292
+ * @returns - latency
293
+ */
294
+ public getInterstitialToMediaOKJMT() {
295
+ const interstitialJoinClickTimestamp = this.latencyTimestamps.get(
296
+ 'internal.client.interstitial-window.click.joinbutton'
297
+ );
298
+
299
+ // get the first timestamp
300
+ const mediaFlowStartedTimestamp = Math.min(
301
+ this.latencyTimestamps.get('client.media.rx.start'),
302
+ this.latencyTimestamps.get('client.media.tx.start')
303
+ );
304
+
305
+ const lobbyTime = this.getStayLobbyTime() || 0;
306
+
307
+ if (interstitialJoinClickTimestamp && mediaFlowStartedTimestamp) {
308
+ return mediaFlowStartedTimestamp - interstitialJoinClickTimestamp - lobbyTime;
309
+ }
310
+
311
+ return undefined;
312
+ }
313
+
314
+ /**
315
+ * Total JMT
316
+ * @returns - latency
317
+ */
318
+ public getTotalJMT() {
319
+ const clickToInterstitial = this.getClickToInterstitial();
320
+ const interstitialToJoinOk = this.getInterstitialToJoinOK();
321
+
322
+ if (clickToInterstitial && interstitialToJoinOk) {
323
+ return clickToInterstitial + interstitialToJoinOk;
324
+ }
325
+
326
+ return undefined;
327
+ }
328
+
329
+ /**
330
+ * Join Conf JMT
331
+ * @returns - latency
332
+ */
333
+ public getJoinConfJMT() {
334
+ const joinReqResp = this.getJoinReqResp();
335
+ const ICESetupTime = this.getICESetupTime();
336
+
337
+ if (joinReqResp && ICESetupTime) {
338
+ return joinReqResp + ICESetupTime;
339
+ }
340
+
341
+ return undefined;
342
+ }
343
+
344
+ /**
345
+ * Total Media JMT
346
+ * @returns - latency
347
+ */
348
+ public getTotalMediaJMT() {
349
+ const clickToInterstitial = this.getClickToInterstitial();
350
+ const interstitialToJoinOk = this.getInterstitialToJoinOK();
351
+ const joinConfJMT = this.getJoinConfJMT();
352
+ const lobbyTime = this.getStayLobbyTime();
353
+
354
+ if (clickToInterstitial && interstitialToJoinOk && joinConfJMT) {
355
+ const totalMediaJMT = clickToInterstitial + interstitialToJoinOk + joinConfJMT;
356
+ if (this.getMeeting()?.allowMediaInLobby) {
357
+ return totalMediaJMT;
358
+ }
359
+
360
+ return totalMediaJMT - lobbyTime;
361
+ }
362
+
363
+ return undefined;
364
+ }
365
+
366
+ /**
367
+ * Client JMT
368
+ * @returns - latency
369
+ */
370
+ public getClientJMT() {
371
+ const interstitialToJoinOk = this.getInterstitialToJoinOK();
372
+ const joinConfJMT = this.getJoinConfJMT();
373
+
374
+ if (interstitialToJoinOk && joinConfJMT) {
375
+ return interstitialToJoinOk - joinConfJMT;
376
+ }
377
+
378
+ return undefined;
379
+ }
380
+
381
+ /**
382
+ * Audio setup delay receive
383
+ */
384
+ public getAudioJoinRespRxStart() {
385
+ return this.getDiffBetweenTimestamps('client.locus.join.response', 'client.media.rx.start');
386
+ }
387
+
388
+ /**
389
+ * Video setup delay receive
390
+ */
391
+ public getVideoJoinRespRxStart() {
392
+ return this.getDiffBetweenTimestamps('client.locus.join.response', 'client.media.rx.start');
393
+ }
394
+
395
+ /**
396
+ * Audio setup delay transmit
397
+ */
398
+ public getAudioJoinRespTxStart() {
399
+ return this.getDiffBetweenTimestamps('client.locus.join.response', 'client.media.tx.start');
400
+ }
401
+
402
+ /**
403
+ * Video setup delay transmit
404
+ */
405
+ public getVideoJoinRespTxStart() {
406
+ return this.getDiffBetweenTimestamps('client.locus.join.response', 'client.media.tx.start');
407
+ }
408
+ }