From 11cfea2359f76406613b8c5b2055ce0cf6eaf901 Mon Sep 17 00:00:00 2001
From: Pedro Beschorner Marin <pedrobmarin@gmail.com>
Date: Wed, 29 Jan 2020 14:52:55 -0300
Subject: [PATCH] Logging audio stats

---
 bigbluebutton-html5/imports/utils/stats.js    | 76 ++++++++++++-------
 .../private/config/settings.yml               |  1 +
 2 files changed, 50 insertions(+), 27 deletions(-)

diff --git a/bigbluebutton-html5/imports/utils/stats.js b/bigbluebutton-html5/imports/utils/stats.js
index 5212fca285..36b1a2949c 100644
--- a/bigbluebutton-html5/imports/utils/stats.js
+++ b/bigbluebutton-html5/imports/utils/stats.js
@@ -4,12 +4,11 @@ const STATS = Meteor.settings.public.stats;
 
 const STATS_LENGTH = STATS.length;
 const STATS_INTERVAL = STATS.interval;
+const STATS_LOG = STATS.log;
 
 const stop = callback => {
-  logger.info(
-    {
-      logCode: 'stats_stop_monitor'
-    },
+  logger.debug(
+    { logCode: 'stats_stop_monitor' },
     'Lost peer connection. Stopping monitor'
   );
   callback(clearResult());
@@ -19,7 +18,7 @@ const stop = callback => {
 const collect = (conn, callback) => {
   let stats = [];
 
-  const monitor = (conn, stats) => {
+  const monitor = (conn, stats, iteration) => {
     if (!conn) return stop(callback);
 
     conn.getStats().then(results => {
@@ -42,12 +41,8 @@ const collect = (conn, callback) => {
 
       if (inboundRTP || remoteInboundRTP) {
         if (!inboundRTP) {
-          const { peerIdentity } = conn;
-          logger.warn(
-            {
-              logCode: 'missing_inbound_rtc',
-              extraInfo: { peerIdentity }
-            },
+          logger.debug(
+            { logCode: 'stats_missing_inbound_rtc' },
             'Missing local inbound RTC. Using remote instead'
           );
         }
@@ -56,13 +51,21 @@ const collect = (conn, callback) => {
         while (stats.length > STATS_LENGTH) stats.shift();
 
         const interval = calculateInterval(stats);
-        callback(buildResult(interval));
+        callback(buildResult(interval, iteration));
       }
 
-      setTimeout(monitor, STATS_INTERVAL, conn, stats);
-    }).catch(error => logger.error(error));
+      setTimeout(monitor, STATS_INTERVAL, conn, stats, iteration + 1);
+    }).catch(error => {
+      logger.debug(
+        {
+          logCode: 'stats_get_stats_error',
+          extraInfo: { error }
+        },
+        'WebRTC stats not available'
+      );
+    });
   };
-  monitor(conn, stats);
+  monitor(conn, stats, 1);
 };
 
 const buildData = inboundRTP => {
@@ -78,9 +81,10 @@ const buildData = inboundRTP => {
   };
 };
 
-const buildResult = (interval) => {
+const buildResult = (interval, iteration) => {
   const rate = calculateRate(interval.packets);
   return {
+    iteration: iteration,
     packets: {
       received: interval.packets.received,
       lost: interval.packets.lost
@@ -97,6 +101,7 @@ const buildResult = (interval) => {
 
 const clearResult = () => {
   return {
+    iteration: 0,
     packets: {
       received: 0,
       lost: 0
@@ -144,19 +149,40 @@ const calculateMOS = (rate) => {
   return 1 + (0.035) * rate + (0.000007) * rate * (rate - 60) * (100 - rate);
 };
 
-const monitorAudioConnection = conn => {
-  if (!conn) return;
+const logResult = (id, result) => {
+  if (!STATS_LOG) return null;
+
+  const {
+    iteration,
+    loss,
+    jitter
+  } = result;
+  // Avoiding messages flood
+  if (!iteration || iteration % STATS_LENGTH !== 0) return null;
 
-  const { peerIdentity } = conn;
+  const duration = STATS_LENGTH * STATS_INTERVAL / 1000;
   logger.info(
     {
-      logCode: 'stats_audio_monitor',
-      extraInfo: { peerIdentity }
+      logCode: 'stats_monitor_result',
+      extraInfo: {
+        id,
+        result
+      }
     },
+    `Stats result for the last ${duration} seconds: loss: ${loss}, jitter: ${jitter}.`
+  );
+};
+
+const monitorAudioConnection = conn => {
+  if (!conn) return;
+
+  logger.debug(
+    { logCode: 'stats_audio_monitor' },
     'Starting to monitor audio connection'
   );
 
   collect(conn, (result) => {
+    logResult('audio', result);
     const event = new CustomEvent('audiostats', { detail: result });
     window.dispatchEvent(event);
   });
@@ -165,12 +191,8 @@ const monitorAudioConnection = conn => {
 const monitorVideoConnection = conn => {
   if (!conn) return;
 
-  const { peerIdentity } = conn;
-  logger.info(
-    {
-      logCode: 'stats_video_monitor',
-      extraInfo: { peerIdentity }
-    },
+  logger.debug(
+    { logCode: 'stats_video_monitor' },
     'Starting to monitor video connection'
   );
 
diff --git a/bigbluebutton-html5/private/config/settings.yml b/bigbluebutton-html5/private/config/settings.yml
index 5a20b486e9..538304604e 100755
--- a/bigbluebutton-html5/private/config/settings.yml
+++ b/bigbluebutton-html5/private/config/settings.yml
@@ -182,6 +182,7 @@ public:
     enabled: false
     interval: 2000
     length: 5
+    log: false
     jitter:
       - 10
       - 20
-- 
GitLab