Browse Source

feat(AvgRTPStatsReporter): batch avg RTP stats

Tries to batch as many reports as possible into single analytics event
and sends all of them under "avg.rtp.stats" event name.

Also converts dots to underscores in all of the stat names, because now
they become JSON keys where dots are not allowed.
dev1
paweldomas 8 years ago
parent
commit
b94f1d027e
1 changed files with 87 additions and 46 deletions
  1. 87
    46
      modules/statistics/AvgRTPStatsReporter.js

+ 87
- 46
modules/statistics/AvgRTPStatsReporter.js View File

9
 import Statistics from './statistics';
9
 import Statistics from './statistics';
10
 import * as VideoType from '../../service/RTC/VideoType';
10
 import * as VideoType from '../../service/RTC/VideoType';
11
 
11
 
12
+/**
13
+ * All avg RTP stats are currently reported under 1 event name, but under
14
+ * different keys. This constant stores the name of this event.
15
+ * Example structure of "avg.rtp.stats" analytics event:
16
+ *
17
+ * {
18
+ *   "stat_avg_rtt": {
19
+ *     value: 200,
20
+ *     samples: [ 100, 200, 300 ]
21
+ *   },
22
+ *   "stat_avg_packetloss_total": {
23
+ *     value: 10,
24
+ *     samples: [ 5, 10, 15]
25
+ *   },
26
+ *   "p2p_stat_avg_packetloss_total": {
27
+ *     value: 15,
28
+ *     samples: [ 10, 15, 20]
29
+ *   }
30
+ * }
31
+ *
32
+ * Note that the samples array is currently emitted for debug purposes only and
33
+ * can be removed anytime soon from the structure.
34
+ *
35
+ * Also not all values are always present in "avg.rtp.stats", some of the values
36
+ * are obtained and calculated as part of different process/event pipe. For
37
+ * example {@link ConnectionAvgStats} instances are doing the reports for each
38
+ * {@link TraceablePeerConnection} and work independently from the main stats
39
+ * pipe.
40
+ *
41
+ * @type {string}
42
+ */
43
+const AVG_RTP_STATS_EVENT = 'avg.rtp.stats';
44
+
12
 const logger = getLogger(__filename);
45
 const logger = getLogger(__filename);
13
 
46
 
14
 /**
47
 /**
55
     }
88
     }
56
 
89
 
57
     /**
90
     /**
58
-     * Calculates an average and submit the report to the analytics module.
59
-     * @param {boolean} isP2P indicates if the report is to be submitted for
60
-     * the P2P connection (when conference is currently in the P2P mode). This
61
-     * will add 'p2p.' prefix to the name of the event. All averages should be
62
-     * cleared when the conference switches, between P2P and JVB modes.
91
+     * Appends the report to the analytics "data" object. The object will be
92
+     * added under {@link this.name} key or "p2p_" + {@link this.name} if
93
+     * <tt>isP2P</tt> is <tt>true</tt>.
94
+     * @param {Object} report the analytics "data" object
95
+     * @param {boolean} isP2P <tt>true</tt> if the stats is being report for
96
+     * P2P connection or <tt>false</tt> for the JVB connection.
63
      */
97
      */
64
-    report(isP2P) {
65
-        Statistics.analytics.sendEvent(
66
-            `${isP2P ? 'p2p.' : ''}${this.name}`,
67
-            {
68
-                value: this.calculate(),
69
-                samples: this.samples
70
-            });
98
+    appendReport(report, isP2P) {
99
+        report[`${isP2P ? 'p2p_' : ''}${this.name}`] = {
100
+            value: this.calculate(),
101
+            samples: this.samples
102
+        };
71
     }
103
     }
72
 
104
 
73
     /**
105
     /**
120
          * Average round trip time reported by the ICE candidate pair.
152
          * Average round trip time reported by the ICE candidate pair.
121
          * @type {AverageStatReport}
153
          * @type {AverageStatReport}
122
          */
154
          */
123
-        this._avgRTT = new AverageStatReport('stat.avg.rtt');
155
+        this._avgRTT = new AverageStatReport('stat_avg_rtt');
124
 
156
 
125
         /**
157
         /**
126
          * Map stores average RTT to the JVB reported by remote participants.
158
          * Map stores average RTT to the JVB reported by remote participants.
183
 
215
 
184
         if (this._sampleIdx >= this._n) {
216
         if (this._sampleIdx >= this._n) {
185
             if (RTCBrowserType.supportsRTTStatistics()) {
217
             if (RTCBrowserType.supportsRTTStatistics()) {
186
-                this._avgRTT.report(this.isP2P);
218
+                const batchReport = { };
219
+
220
+                this._avgRTT.appendReport(batchReport, this.isP2P);
187
 
221
 
188
                 // Report end to end RTT only for JVB
222
                 // Report end to end RTT only for JVB
189
                 if (!this.isP2P) {
223
                 if (!this.isP2P) {
191
                     const avgLocalRTT = this._avgRTT.calculate();
225
                     const avgLocalRTT = this._avgRTT.calculate();
192
 
226
 
193
                     if (!isNaN(avgLocalRTT) && !isNaN(avgRemoteRTT)) {
227
                     if (!isNaN(avgLocalRTT) && !isNaN(avgRemoteRTT)) {
194
-                        Statistics.analytics.sendEvent(
195
-                            'stat.avg.end2endrtt',
196
-                            { value: avgLocalRTT + avgRemoteRTT });
228
+                        // eslint-disable-next-line camelcase
229
+                        batchReport.stat_avg_end2endrtt
230
+                            = { value: avgLocalRTT + avgRemoteRTT };
197
                     }
231
                     }
198
                 }
232
                 }
233
+
234
+                Statistics.analytics.sendEvent(
235
+                    AVG_RTP_STATS_EVENT, batchReport);
199
             }
236
             }
200
 
237
 
201
             this._resetAvgStats();
238
             this._resetAvgStats();
238
         let rttAvg = this._avgRemoteRTTMap.get(id);
275
         let rttAvg = this._avgRemoteRTTMap.get(id);
239
 
276
 
240
         if (!rttAvg && validData) {
277
         if (!rttAvg && validData) {
241
-            rttAvg = new AverageStatReport(`${id}.stat.rtt`);
278
+            rttAvg = new AverageStatReport(`${id}_stat_rtt`);
242
             this._avgRemoteRTTMap.set(id, rttAvg);
279
             this._avgRemoteRTTMap.set(id, rttAvg);
243
         }
280
         }
244
 
281
 
332
          * @private
369
          * @private
333
          */
370
          */
334
         this._avgAudioBitrateUp
371
         this._avgAudioBitrateUp
335
-            = new AverageStatReport('stat.avg.bitrate.audio.upload');
372
+            = new AverageStatReport('stat_avg_bitrate_audio_upload');
336
 
373
 
337
         /**
374
         /**
338
          * Average audio download bitrate
375
          * Average audio download bitrate
340
          * @private
377
          * @private
341
          */
378
          */
342
         this._avgAudioBitrateDown
379
         this._avgAudioBitrateDown
343
-            = new AverageStatReport('stat.avg.bitrate.audio.download');
380
+            = new AverageStatReport('stat_avg_bitrate_audio_download');
344
 
381
 
345
         /**
382
         /**
346
          * Average video upload bitrate
383
          * Average video upload bitrate
348
          * @private
385
          * @private
349
          */
386
          */
350
         this._avgVideoBitrateUp
387
         this._avgVideoBitrateUp
351
-            = new AverageStatReport('stat.avg.bitrate.video.upload');
388
+            = new AverageStatReport('stat_avg_bitrate_video_upload');
352
 
389
 
353
         /**
390
         /**
354
          * Average video download bitrate
391
          * Average video download bitrate
356
          * @private
393
          * @private
357
          */
394
          */
358
         this._avgVideoBitrateDown
395
         this._avgVideoBitrateDown
359
-            = new AverageStatReport('stat.avg.bitrate.video.download');
396
+            = new AverageStatReport('stat_avg_bitrate_video_download');
360
 
397
 
361
         /**
398
         /**
362
          * Average upload bandwidth
399
          * Average upload bandwidth
364
          * @private
401
          * @private
365
          */
402
          */
366
         this._avgBandwidthUp
403
         this._avgBandwidthUp
367
-            = new AverageStatReport('stat.avg.bandwidth.upload');
404
+            = new AverageStatReport('stat_avg_bandwidth_upload');
368
 
405
 
369
         /**
406
         /**
370
          * Average download bandwidth
407
          * Average download bandwidth
372
          * @private
409
          * @private
373
          */
410
          */
374
         this._avgBandwidthDown
411
         this._avgBandwidthDown
375
-            = new AverageStatReport('stat.avg.bandwidth.download');
412
+            = new AverageStatReport('stat_avg_bandwidth_download');
376
 
413
 
377
         /**
414
         /**
378
          * Average total packet loss
415
          * Average total packet loss
380
          * @private
417
          * @private
381
          */
418
          */
382
         this._avgPacketLossTotal
419
         this._avgPacketLossTotal
383
-            = new AverageStatReport('stat.avg.packetloss.total');
420
+            = new AverageStatReport('stat_avg_packetloss_total');
384
 
421
 
385
         /**
422
         /**
386
          * Average upload packet loss
423
          * Average upload packet loss
388
          * @private
425
          * @private
389
          */
426
          */
390
         this._avgPacketLossUp
427
         this._avgPacketLossUp
391
-            = new AverageStatReport('stat.avg.packetloss.upload');
428
+            = new AverageStatReport('stat_avg_packetloss_upload');
392
 
429
 
393
         /**
430
         /**
394
          * Average download packet loss
431
          * Average download packet loss
396
          * @private
433
          * @private
397
          */
434
          */
398
         this._avgPacketLossDown
435
         this._avgPacketLossDown
399
-            = new AverageStatReport('stat.avg.packetloss.download');
436
+            = new AverageStatReport('stat_avg_packetloss_download');
400
 
437
 
401
         /**
438
         /**
402
          * Average FPS for remote videos
439
          * Average FPS for remote videos
403
          * @type {AverageStatReport}
440
          * @type {AverageStatReport}
404
          * @private
441
          * @private
405
          */
442
          */
406
-        this._avgRemoteFPS = new AverageStatReport('stat.avg.framerate.remote');
443
+        this._avgRemoteFPS = new AverageStatReport('stat_avg_framerate_remote');
407
 
444
 
408
         /**
445
         /**
409
          * Average FPS for remote screen streaming videos (reported only if not
446
          * Average FPS for remote screen streaming videos (reported only if not
412
          * @private
449
          * @private
413
          */
450
          */
414
         this._avgRemoteScreenFPS
451
         this._avgRemoteScreenFPS
415
-            = new AverageStatReport('stat.avg.framerate.screen.remote');
452
+            = new AverageStatReport('stat_avg_framerate_screen_remote');
416
 
453
 
417
         /**
454
         /**
418
          * Average FPS for local video (camera)
455
          * Average FPS for local video (camera)
419
          * @type {AverageStatReport}
456
          * @type {AverageStatReport}
420
          * @private
457
          * @private
421
          */
458
          */
422
-        this._avgLocalFPS = new AverageStatReport('stat.avg.framerate.local');
459
+        this._avgLocalFPS = new AverageStatReport('stat_avg_framerate_local');
423
 
460
 
424
         /**
461
         /**
425
          * Average FPS for local screen streaming video (reported only if not
462
          * Average FPS for local screen streaming video (reported only if not
428
          * @private
465
          * @private
429
          */
466
          */
430
         this._avgLocalScreenFPS
467
         this._avgLocalScreenFPS
431
-            = new AverageStatReport('stat.avg.framerate.screen.local');
468
+            = new AverageStatReport('stat_avg_framerate_screen_local');
432
 
469
 
433
         /**
470
         /**
434
          * Average connection quality as defined by
471
          * Average connection quality as defined by
436
          * @type {AverageStatReport}
473
          * @type {AverageStatReport}
437
          * @private
474
          * @private
438
          */
475
          */
439
-        this._avgCQ = new AverageStatReport('stat.avg.cq');
476
+        this._avgCQ = new AverageStatReport('stat_avg_cq');
440
 
477
 
441
         this._onLocalStatsUpdated = data => this._calculateAvgStats(data);
478
         this._onLocalStatsUpdated = data => this._calculateAvgStats(data);
442
         conference.on(
479
         conference.on(
551
         this._sampleIdx += 1;
588
         this._sampleIdx += 1;
552
 
589
 
553
         if (this._sampleIdx >= this._n) {
590
         if (this._sampleIdx >= this._n) {
554
-            this._avgAudioBitrateUp.report(isP2P);
555
-            this._avgAudioBitrateDown.report(isP2P);
591
+            const batchReport = { };
556
 
592
 
557
-            this._avgVideoBitrateUp.report(isP2P);
558
-            this._avgVideoBitrateDown.report(isP2P);
593
+            this._avgAudioBitrateUp.appendReport(batchReport, isP2P);
594
+            this._avgAudioBitrateDown.appendReport(batchReport, isP2P);
595
+
596
+            this._avgVideoBitrateUp.appendReport(batchReport, isP2P);
597
+            this._avgVideoBitrateDown.appendReport(batchReport, isP2P);
559
 
598
 
560
             if (RTCBrowserType.supportsBandwidthStatistics()) {
599
             if (RTCBrowserType.supportsBandwidthStatistics()) {
561
-                this._avgBandwidthUp.report(isP2P);
562
-                this._avgBandwidthDown.report(isP2P);
600
+                this._avgBandwidthUp.appendReport(batchReport, isP2P);
601
+                this._avgBandwidthDown.appendReport(batchReport, isP2P);
563
             }
602
             }
564
-            this._avgPacketLossUp.report(isP2P);
565
-            this._avgPacketLossDown.report(isP2P);
566
-            this._avgPacketLossTotal.report(isP2P);
603
+            this._avgPacketLossUp.appendReport(batchReport, isP2P);
604
+            this._avgPacketLossDown.appendReport(batchReport, isP2P);
605
+            this._avgPacketLossTotal.appendReport(batchReport, isP2P);
567
 
606
 
568
-            this._avgRemoteFPS.report(isP2P);
607
+            this._avgRemoteFPS.appendReport(batchReport, isP2P);
569
             if (!isNaN(this._avgRemoteScreenFPS.calculate())) {
608
             if (!isNaN(this._avgRemoteScreenFPS.calculate())) {
570
-                this._avgRemoteScreenFPS.report(isP2P);
609
+                this._avgRemoteScreenFPS.appendReport(batchReport, isP2P);
571
             }
610
             }
572
-            this._avgLocalFPS.report(isP2P);
611
+            this._avgLocalFPS.appendReport(batchReport, isP2P);
573
             if (!isNaN(this._avgLocalScreenFPS.calculate())) {
612
             if (!isNaN(this._avgLocalScreenFPS.calculate())) {
574
-                this._avgLocalScreenFPS.report(isP2P);
613
+                this._avgLocalScreenFPS.appendReport(batchReport, isP2P);
575
             }
614
             }
576
 
615
 
577
-            this._avgCQ.report(isP2P);
616
+            this._avgCQ.appendReport(batchReport, isP2P);
617
+
618
+            Statistics.analytics.sendEvent(AVG_RTP_STATS_EVENT, batchReport);
578
 
619
 
579
             this._resetAvgStats();
620
             this._resetAvgStats();
580
         }
621
         }

Loading…
Cancel
Save