diff --git a/app.js b/app.js
index 38f19ff613..4b8da6c680 100644
--- a/app.js
+++ b/app.js
@@ -21,6 +21,7 @@ window.toastr = require("toastr");
const Logger = require("jitsi-meet-logger");
const LogCollector = Logger.LogCollector;
+import JitsiMeetLogStorage from "./modules/util/JitsiMeetLogStorage";
import URLProcessor from "./modules/config/URLProcessor";
import RoomnameGenerator from './modules/util/RoomnameGenerator';
@@ -163,26 +164,7 @@ const APP = {
configureLoggingLevels();
// Start the LogCollector and register it as the global log transport
if (!this.logCollector && !loggingConfig.disableLogCollector) {
- this.logCollector = new LogCollector({
- storeLogs: (logJSON) => {
- // Try catch was used, because there are many variables
- // on the way that could be uninitialized if the storeLogs
- // attempt would be made very early (which is unlikely)
- try {
- // Currently it makes sense to store the log only
- // if CallStats is enabled
- if (APP.logCollectorStarted
- && APP.conference
- && APP.conference.isCallstatsEnabled()) {
- APP.conference.logJSON(logJSON);
- }
- } catch (error) {
- // NOTE console is intentional here
- console.error(
- "Failed to store the logs: ", logJSON, error);
- }
- }
- });
+ this.logCollector = new LogCollector(new JitsiMeetLogStorage());
Logger.addGlobalTransport(this.logCollector);
JitsiMeetJS.addGlobalLogTransport(this.logCollector);
}
diff --git a/modules/util/JitsiMeetLogStorage.js b/modules/util/JitsiMeetLogStorage.js
new file mode 100644
index 0000000000..1dfa9f9e4a
--- /dev/null
+++ b/modules/util/JitsiMeetLogStorage.js
@@ -0,0 +1,59 @@
+/* global APP */
+
+/**
+ * Implements logs storage through the CallStats.
+ */
+export default class JitsiMeetLogStorage {
+
+ /**
+ * Creates new JitsiMeetLogStorage
+ */
+ constructor() {
+ /**
+ * Counts each log entry, increases on every batch log entry stored.
+ * @type {number}
+ */
+ this.counter = 1;
+ }
+
+ /**
+ * Called by the LogCollector to store a series of log lines into
+ * batch.
+ * @param {string|object[]}logEntries an array containing strings
+ * representing log lines or aggregated lines objects.
+ */
+ storeLogs(logEntries) {
+
+ let logJSON = '{"log' + this.counter + '":"\n';
+ for (let i = 0, len = logEntries.length; i < len; i++) {
+ let logEntry = logEntries[i];
+ if (typeof logEntry === 'object') {
+ // Aggregated message
+ logJSON += '(' + logEntry.count + ') ' + logEntry.text + '\n';
+ } else {
+ // Regular message
+ logJSON += logEntry + '\n';
+ }
+ }
+ logJSON += '"}';
+
+ this.counter += 1;
+
+ // Try catch was used, because there are many variables
+ // on the way that could be uninitialized if the storeLogs
+ // attempt would be made very early (which is unlikely)
+ try {
+ // Currently it makes sense to store the log only
+ // if CallStats is enabled
+ if (APP.logCollectorStarted
+ && APP.conference
+ && APP.conference.isCallstatsEnabled()) {
+ APP.conference.logJSON(logJSON);
+ }
+ } catch (error) {
+ // NOTE console is intentional here
+ console.error(
+ "Failed to store the logs: ", logJSON, error);
+ }
+ }
+}