From 3c77ffaba6dc3863bf6b7ca28c5dedf9ffa5aa28 Mon Sep 17 00:00:00 2001 From: Marcin Wojtczak Date: Wed, 9 Oct 2024 18:17:18 +0100 Subject: [PATCH] feat(meetings): incremental log uploads --- .../internal-plugin-support/src/support.js | 2 + packages/@webex/plugin-logger/src/logger.js | 14 +++++++ packages/@webex/plugin-meetings/src/config.ts | 1 + .../plugin-meetings/src/meeting/index.ts | 40 +++++++++++++++++++ .../plugin-meetings/src/meeting/util.ts | 1 + 5 files changed, 58 insertions(+) diff --git a/packages/@webex/internal-plugin-support/src/support.js b/packages/@webex/internal-plugin-support/src/support.js index f41d380637e..84f3e088915 100644 --- a/packages/@webex/internal-plugin-support/src/support.js +++ b/packages/@webex/internal-plugin-support/src/support.js @@ -107,6 +107,8 @@ const Support = WebexPlugin.extend({ return this.webex.upload(options); }) .then((body) => { + this.webex.logger.clearBuffers(); + if (userId && !body.userId) { body.userId = userId; } diff --git a/packages/@webex/plugin-logger/src/logger.js b/packages/@webex/plugin-logger/src/logger.js index 7ef5a925fa9..183602dbe50 100644 --- a/packages/@webex/plugin-logger/src/logger.js +++ b/packages/@webex/plugin-logger/src/logger.js @@ -252,6 +252,20 @@ const Logger = WebexPlugin.extend({ return this.getCurrentLevel(); }, + /** + * Clears the log buffers + * + * @instance + * @memberof Logger + * @public + * @returns {undefined} + */ + clearBuffers() { + this.clientBuffer = []; + this.sdkBuffer = []; + this.buffer = []; + }, + /** * Format logs (for upload) * diff --git a/packages/@webex/plugin-meetings/src/config.ts b/packages/@webex/plugin-meetings/src/config.ts index 759372cd615..b602fba5040 100644 --- a/packages/@webex/plugin-meetings/src/config.ts +++ b/packages/@webex/plugin-meetings/src/config.ts @@ -92,5 +92,6 @@ export default { degradationPreferences: { maxMacroblocksLimit: 8192, }, + logUploadInterval: 60 * 10, // in seconds }, }; diff --git a/packages/@webex/plugin-meetings/src/meeting/index.ts b/packages/@webex/plugin-meetings/src/meeting/index.ts index 526fd355080..f66c7d77910 100644 --- a/packages/@webex/plugin-meetings/src/meeting/index.ts +++ b/packages/@webex/plugin-meetings/src/meeting/index.ts @@ -5,6 +5,7 @@ import jwtDecode from 'jwt-decode'; import {StatelessWebexPlugin} from '@webex/webex-core'; // @ts-ignore - Types not available for @webex/common import {Defer} from '@webex/common'; +import {safeSetTimeout, safeSetInterval} from '@webex/common-timers'; import { ClientEvent, ClientEventLeaveReason, @@ -700,6 +701,7 @@ export default class Meeting extends StatelessWebexPlugin { private iceCandidateErrors: Map; private iceCandidatesCount: number; private rtcMetrics?: RtcMetrics; + private uploadLogsIntervalId?: ReturnType; /** * @param {Object} attrs @@ -3964,6 +3966,43 @@ export default class Meeting extends StatelessWebexPlugin { Trigger.trigger(this, options, EVENTS.REQUEST_UPLOAD_LOGS, this); } + /** + * Starts a periodic upload of logs + * + * @returns {undefined} + */ + public startPeriodicLogUpload() { + if (!this.uploadLogsIntervalId) { + // start a periodic log upload after an initial delay of a few seconds to let things settle down first + safeSetTimeout(() => { + this.uploadLogs(); + + this.uploadLogsIntervalId = safeSetInterval(() => { + this.uploadLogs(); + + // just as an extra precaution, to avoid uploading logs forever in case something goes wrong + // and the page remains opened, we stop it if there is no media connection + if (!this.mediaProperties.webrtcMediaConnection) { + this.stopPeriodicLogUpload(); + } + // @ts-ignore - config coming from registerPlugin + }, this.config.logUploadInterval * 1000); + }, 3000); + } + } + + /** + * Stops the periodic upload of logs + * + * @returns {undefined} + */ + public stopPeriodicLogUpload() { + if (this.uploadLogsIntervalId) { + clearInterval(this.uploadLogsIntervalId); + this.uploadLogsIntervalId = undefined; + } + } + /** * Removes remote audio, video and share streams from class instance's mediaProperties * @returns {undefined} @@ -7130,6 +7169,7 @@ export default class Meeting extends StatelessWebexPlugin { // We can log ReceiveSlot SSRCs only after the SDP exchange, so doing it here: this.remoteMediaManager?.logAllReceiveSlots(); + this.startPeriodicLogUpload(); } catch (error) { LoggerProxy.logger.error(`${LOG_HEADER} failed to establish media connection: `, error); diff --git a/packages/@webex/plugin-meetings/src/meeting/util.ts b/packages/@webex/plugin-meetings/src/meeting/util.ts index a67fce6dd65..41a18d69fd9 100644 --- a/packages/@webex/plugin-meetings/src/meeting/util.ts +++ b/packages/@webex/plugin-meetings/src/meeting/util.ts @@ -171,6 +171,7 @@ const MeetingUtil = { cleanUp: (meeting) => { meeting.getWebexObject().internal.device.meetingEnded(); + meeting.stopPeriodicLogUpload(); meeting.breakouts.cleanUp(); meeting.simultaneousInterpretation.cleanUp();