feat(rtcstats): attach LogCollector storage to rtcstats lifecycle

* attach LogCollector to rtcstats lifecycle

* remove legacy param
This commit is contained in:
Andrei Gavrilescu
2025-04-02 17:07:39 +03:00
committed by GitHub
parent cf7c39d3e5
commit 5314d779ed
4 changed files with 26 additions and 27 deletions

View File

@@ -190,10 +190,10 @@ export interface IConfig {
obfuscateRoomName?: boolean;
rtcstatsEnabled?: boolean;
rtcstatsEndpoint?: string;
rtcstatsLogFlushSizeBytes?: number;
rtcstatsPollInterval?: number;
rtcstatsSendSdp?: boolean;
rtcstatsStoreLogs?: boolean;
rtcstatsUseLegacy?: boolean;
scriptURLs?: Array<string>;
watchRTCEnabled?: boolean;
whiteListedEvents?: string[];

View File

@@ -24,7 +24,6 @@ export function _cleanupConfig(config: IConfig) {
delete config.analytics?.rtcstatsEndpoint;
delete config.analytics?.rtcstatsPollInterval;
delete config.analytics?.rtcstatsSendSdp;
delete config.analytics?.rtcstatsUseLegacy;
delete config.analytics?.obfuscateRoomName;
delete config.analytics?.watchRTCEnabled;
delete config.watchRTCConfigParams;

View File

@@ -1,12 +1,13 @@
import { IStore } from '../../app/types';
import JitsiMeetJS from '../../base/lib-jitsi-meet';
import RTCStats from '../../rtcstats/RTCStats';
import { isRTCStatsEnabled } from '../../rtcstats/functions';
/**
* Implements log storage interface from the @jitsi/logger lib.
* Implements log storage interface from the @jitsi/logger lib, as it stands
* now it only sends logs to the rtcstats server in case it is enabled.
*/
export default class JitsiMeetLogStorage {
counter: number;
getState: IStore['getState'];
/**
@@ -15,12 +16,6 @@ export default class JitsiMeetLogStorage {
* @param {Function} getState - The Redux store's {@code getState} method.
*/
constructor(getState: IStore['getState']) {
/**
* Counts each log entry, increases on every batch log entry stored.
*
* @type {number}
*/
this.counter = 1;
/**
* The Redux store's {@code getState} method.
@@ -31,18 +26,14 @@ export default class JitsiMeetLogStorage {
}
/**
* The JitsiMeetLogStorage is ready when the conference has been joined.
* A conference is considered joined when the 'conference' field is defined
* in the base/conference state.
* The JitsiMeetLogStorage is ready we can use the rtcstats trace to send logs
* to the rtcstats server.
*
* @returns {boolean} <tt>true</tt> when this storage is ready or
* <tt>false</tt> otherwise.
*/
isReady() {
const { conference, error: conferenceError } = this.getState()['features/base/conference'];
const { error: connectionError } = this.getState()['features/base/connection'];
return Boolean(conference || conferenceError || connectionError);
return JitsiMeetJS.rtcstats.isTraceAvailable();
}
/**
@@ -55,9 +46,9 @@ export default class JitsiMeetLogStorage {
const config = this.getState()['features/base/config'];
// Saving the logs in RTCStats is a new feature and so there is no prior behavior that needs to be maintained.
// That said, this is still experimental and needs to be rolled out gradually so we want this to be off by
// default.
// RTCStats can run without sending app logs to the server.
// Be mindful that there exists another LogStorage instance withing lib-jitsi-meet,
// that is used to send logs generated there.
return config?.analytics?.rtcstatsStoreLogs && isRTCStatsEnabled(this.getState());
}

View File

@@ -107,9 +107,6 @@ function _conferenceJoined({ getState }: IStore, next: Function, action: AnyActi
const { logCollector } = getState()['features/base/logging'];
if (logCollector && conference === getCurrentConference(getState())) {
// Start the LogCollector's periodic "store logs" task
logCollector.start();
// Make an attempt to flush in case a lot of logs have been cached,
// before the collector was started.
logCollector.flush();
@@ -150,12 +147,21 @@ function _initLogging({ dispatch, getState }: IStore,
// Create the LogCollector and register it as the global log transport. It
// is done early to capture as much logs as possible. Captured logs will be
// cached, before the JitsiMeetLogStorage gets ready (statistics module is
// initialized).
// cached, before the JitsiMeetLogStorage gets ready (RTCStats trace is
// available).
if (!logCollector && !loggingConfig.disableLogCollector) {
const _logCollector = new Logger.LogCollector(new JitsiMeetLogStorage(getState));
const { apiLogLevels, analytics: { rtcstatsLogFlushSizeBytes } = {} } = getState()['features/base/config'];
const { apiLogLevels } = getState()['features/base/config'];
// The smaller the flush size the smaller the chance of losing logs, but
// the more often the logs will be sent to the server, by default the LogCollector
// will set once the logs reach 10KB or 30 seconds have passed since the last flush,
// this means if something happens between that interval and the logs don't get flushed
// they will be lost, for instance the meeting tab is closed, the browser crashes,
// an uncaught exception happens, etc.
// If undefined is passed the default values will be used,
const _logCollector = new Logger.LogCollector(new JitsiMeetLogStorage(getState), {
maxEntryLength: rtcstatsLogFlushSizeBytes
});
if (apiLogLevels && Array.isArray(apiLogLevels) && typeof APP === 'object') {
const transport = buildExternalApiLogTransport(apiLogLevels);
@@ -165,6 +171,9 @@ function _initLogging({ dispatch, getState }: IStore,
}
Logger.addGlobalTransport(_logCollector);
_logCollector.start();
dispatch(setLogCollector(_logCollector));
// The JitsiMeetInMemoryLogStorage can not be accessed on mobile through