From 0e560fcbab98bac925dd89e4553ea2f5dc035c88 Mon Sep 17 00:00:00 2001 From: Boris Grozev Date: Mon, 20 Nov 2023 11:19:27 -0600 Subject: [PATCH 1/6] ref: Remove PrecallTest. --- JitsiMeetJS.ts | 6 +- modules/statistics/PrecallTest.js | 133 ------------------------------ 2 files changed, 1 insertion(+), 138 deletions(-) delete mode 100644 modules/statistics/PrecallTest.js diff --git a/JitsiMeetJS.ts b/JitsiMeetJS.ts index 23b616e367..8802105d60 100644 --- a/JitsiMeetJS.ts +++ b/JitsiMeetJS.ts @@ -25,7 +25,6 @@ import ProxyConnectionService import recordingConstants from './modules/recording/recordingConstants'; import Settings from './modules/settings/Settings'; import LocalStatsCollector from './modules/statistics/LocalStatsCollector'; -import precallTest from './modules/statistics/PrecallTest'; import Statistics from './modules/statistics/statistics'; import GlobalOnErrorHandler from './modules/util/GlobalOnErrorHandler'; import ScriptUtil from './modules/util/ScriptUtil'; @@ -549,6 +548,7 @@ export default { 'StackTrace: ', error); Statistics.reportGlobalError(error); }, + /* eslint-enable max-params */ /** * Informs lib-jitsi-meet about the current network status. @@ -561,10 +561,6 @@ export default { NetworkInfo.updateNetworkInfo({ isOnline }); }, - precallTest, - - /* eslint-enable max-params */ - /** * Represents a hub/namespace for utility functionality which may be of * interest to lib-jitsi-meet clients. diff --git a/modules/statistics/PrecallTest.js b/modules/statistics/PrecallTest.js deleted file mode 100644 index f5f03a683c..0000000000 --- a/modules/statistics/PrecallTest.js +++ /dev/null @@ -1,133 +0,0 @@ -import EventEmitter from 'events'; - -import browser from '../browser'; -import Settings from '../settings/Settings'; -import ScriptUtil from '../util/ScriptUtil'; - -import { CALLSTATS_SCRIPT_URL } from './constants'; - -const PRECALL_TEST_RESULTS = 'preCallTestResults'; -const emitter = new EventEmitter(); -let _initialized = false; -let api = null; - -/** - * Loads the callstats io script. - * - * @returns {Promise} - */ -function _loadScript(options) { - if (browser.isReactNative()) { - return; - } - - return new Promise(resolve => { - ScriptUtil.loadScript( - options.callStatsCustomScriptUrl || CALLSTATS_SCRIPT_URL, - /* async */ true, - /* prepend */ true, - /* relativeURL */ undefined, - /* loadCallback */ resolve); - }); -} - -/** - * Initializes the callstats lib and registers a callback to be invoked - * when there are 'preCallTestResults'. - * - * @typedef PrecallTestOptions - * @type {Object} - * @property {string} callStatsID - Callstats credentials - the id. - * @property {string} callStatsSecret - Callstats credentials - the secret. - * @property {string} statisticsId - The user name to use when initializing callstats. - * @property {string} statisticsDisplayName - The user display name. - * - * @param { PrecallTestOptions} options - The init options. - * @returns {Promise} - */ -function _initialize(options) { - return new Promise((resolve, reject) => { - const appId = options.callStatsID; - const appSecret = options.callStatsSecret; - const userId = options.statisticsId || options.statisticsDisplayName || Settings.callStatsUserName; - - api.initialize(appId, appSecret, userId, (status, message) => { - if (status === 'success') { - api.on(PRECALL_TEST_RESULTS, (...args) => { - emitter.emit(PRECALL_TEST_RESULTS, ...args); - }); - _initialized = true; - resolve(); - } else { - reject({ - status, - message - }); - } - }, null, { disablePrecalltest: true }); - }); -} - -/** - * Loads the callstats script and initializes the library. - * - * @param {Function} onResult - The callback to be invoked when results are received. - * @returns {Promise} - */ -export async function init(options) { - if (_initialized) { - throw new Error('Precall Test already initialized'); - } - - const { callStatsID, callStatsSecret, disableThirdPartyRequests } = options; - - if (!callStatsID || !callStatsSecret || disableThirdPartyRequests) { - throw new Error('Callstats is disabled'); - } - - await _loadScript(options); - // eslint-disable-next-line new-cap - api = new window.callstats(); - - return _initialize(options); -} - -/** - * Executes a pre call test. - * - * @typedef PrecallTestResults - * @type {Object} - * @property {boolean} mediaConnectivity - If there is media connectivity or not. - * @property {number} throughput - The average throughput. - * @property {number} fractionalLoss - The packet loss. - * @property {number} rtt - The round trip time. - * @property {string} provider - It is usually 'callstats'. - * - * @returns {Promise<{PrecallTestResults}>} - */ -export function execute() { - if (!_initialized) { - return Promise.reject('uninitialized'); - } - - return new Promise((resolve, reject) => { - emitter.on(PRECALL_TEST_RESULTS, (status, payload) => { - if (status === 'success') { - resolve(payload); - } else { - reject({ - status, - payload - }); - } - - }); - - api.makePrecallTest(); - }); -} - -export default { - init, - execute -}; From 86bb00ebba42de6cc938c1a59a5f766609fb4950 Mon Sep 17 00:00:00 2001 From: Boris Grozev Date: Mon, 20 Nov 2023 11:36:48 -0600 Subject: [PATCH 2/6] ref: Remove startCallStats. --- JitsiConference.js | 26 ----------------------- modules/statistics/statistics.js | 36 -------------------------------- 2 files changed, 62 deletions(-) diff --git a/JitsiConference.js b/JitsiConference.js index c7ca319c17..3138b004a9 100644 --- a/JitsiConference.js +++ b/JitsiConference.js @@ -2256,14 +2256,6 @@ JitsiConference.prototype._acceptJvbIncomingCall = function(jingleSession, jingl this._desktopSharingFrameRate && jingleSession.peerconnection.setDesktopSharingFrameRate(this._desktopSharingFrameRate); - // Start callstats as soon as peerconnection is initialized, - // do not wait for XMPPEvents.PEERCONNECTION_READY, as it may never - // happen in case if user doesn't have or denied permission to - // both camera and microphone. - logger.info('Starting CallStats for JVB connection...'); - this.statistics.startCallStats( - this.jvbJingleSession.peerconnection, - 'jitsi' /* Remote user ID for JVB is 'jitsi' */); this.statistics.startRemoteStats(this.jvbJingleSession.peerconnection); } catch (e) { GlobalOnErrorHandler.callErrorHandler(e); @@ -3006,10 +2998,6 @@ JitsiConference.prototype._acceptP2PIncomingCall = function(jingleSession, jingl remoteID = participant.getStatsID() || remoteID; } - this.statistics.startCallStats( - this.p2pJingleSession.peerconnection, - remoteID); - const localTracks = this._getInitialLocalTracks(); this.p2pJingleSession.acceptOffer( @@ -3353,20 +3341,6 @@ JitsiConference.prototype._startP2PSession = function(remoteJid) { enableInsertableStreams: this.isE2EEEnabled() || FeatureFlags.isRunInLiteModeEnabled() }); - logger.info('Starting CallStats for P2P connection...'); - - let remoteID = Strophe.getResourceFromJid(this.p2pJingleSession.remoteJid); - - const participant = this.participants.get(remoteID); - - if (participant) { - remoteID = participant.getStatsID() || remoteID; - } - - this.statistics.startCallStats( - this.p2pJingleSession.peerconnection, - remoteID); - const localTracks = this.getLocalTracks(); this.p2pJingleSession.invite(localTracks); diff --git a/modules/statistics/statistics.js b/modules/statistics/statistics.js index 8addcaa297..afb2a95d03 100644 --- a/modules/statistics/statistics.js +++ b/modules/statistics/statistics.js @@ -484,42 +484,6 @@ Statistics.prototype.stopRemoteStats = function(tpc) { // CALSTATS METHODS -/** - * Initializes the callstats.io API. - * @param {TraceablePeerConnection} tpc the {@link TraceablePeerConnection} - * instance for which CalStats will be started. - * @param {string} remoteUserID - */ -Statistics.prototype.startCallStats = function(tpc, remoteUserID) { - if (!this.callStatsIntegrationEnabled) { - return; - } else if (this.callsStatsInstances.has(tpc.id)) { - logger.error('CallStats instance for ${tpc} exists already'); - - return; - } - let confID = this.options.confID; - - // confID - domain/tenant/roomName - // roomName - meeting name or breakout room ID - // For breakout rooms we change the conference ID used for callstats to use - // the room ID instead of the meeting name - if (!confID.endsWith(this.options.roomName)) { - confID = `${this.options.confID.slice(0, this.options.confID.lastIndexOf('/'))}/${this.options.roomName}`; - } - - logger.info(`Starting CallStats for ${tpc}...`); - const newInstance - = new CallStats( - tpc, - { - confID, - remoteUserID - }); - - this.callsStatsInstances.set(tpc.id, newInstance); -}; - /** * Obtains the list of *all* {@link CallStats} instances collected from every * valid {@link Statistics} instance. From c5827bcc77ee2a95ae7bf966e9c4170e6860a385 Mon Sep 17 00:00:00 2001 From: Boris Grozev Date: Mon, 20 Nov 2023 12:31:12 -0600 Subject: [PATCH 3/6] ref: Remove callstats support. --- JitsiConference.js | 104 +-- JitsiConferenceEventManager.js | 87 +- JitsiConferenceEvents.ts | 3 +- JitsiConnection.js | 6 - JitsiMediaDevices.js | 32 - JitsiMeetJS.ts | 32 - modules/RTC/JitsiLocalTrack.js | 14 +- modules/RTC/JitsiTrack.js | 13 - modules/RTCStats/RTCStats.ts | 17 +- modules/connectivity/TrackStreamingStatus.ts | 8 - modules/settings/Settings.js | 12 +- modules/statistics/CallStats.js | 787 ------------------- modules/statistics/constants.js | 2 - modules/statistics/statistics.js | 468 +---------- modules/version/ComponentsVersions.js | 13 - modules/xmpp/xmpp.js | 1 - service/statistics/Events.ts | 3 +- 17 files changed, 23 insertions(+), 1579 deletions(-) delete mode 100644 modules/statistics/CallStats.js diff --git a/JitsiConference.js b/JitsiConference.js index 3138b004a9..b68443bf0e 100644 --- a/JitsiConference.js +++ b/JitsiConference.js @@ -472,13 +472,8 @@ JitsiConference.prototype._init = function(options = {}) { userName: config.statisticsDisplayName ? config.statisticsDisplayName : this.myUserId(), confID: config.confID || `${this.connection.options.hosts.domain}/${this.options.name}`, siteID: config.siteID, - customScriptUrl: config.callStatsCustomScriptUrl, - callStatsID: config.callStatsID, - callStatsSecret: config.callStatsSecret, - callStatsApplicationLogsDisabled: config.callStatsApplicationLogsDisabled, roomName: this.options.name, applicationName: config.applicationName, - configParams: config.callStatsConfigParams }); Statistics.analytics.addPermanentProperties({ 'callstats_name': this._statsCurrentId @@ -1237,13 +1232,6 @@ JitsiConference.prototype.onLocalTrackRemoved = function(track) { track.removeEventListener(JitsiTrackEvents.TRACK_AUDIO_LEVEL_CHANGED, track.audioLevelHandler); } - // send event for stopping screen sharing - // FIXME: we assume we have only one screen sharing track - // if we change this we need to fix this check - if (track.isVideoTrack() && track.videoType === VideoType.DESKTOP) { - this.statistics.sendScreenSharingEvent(false); - } - this.eventEmitter.emit(JitsiConferenceEvents.TRACK_REMOVED, track); }; @@ -1381,17 +1369,6 @@ JitsiConference.prototype._removeLocalSourceOnReject = function(jingleSession, e JitsiConference.prototype._setupNewTrack = function(newTrack) { const mediaType = newTrack.getType(); - if (newTrack.isAudioTrack() || (newTrack.isVideoTrack() && newTrack.videoType !== VideoType.DESKTOP)) { - // Report active device to statistics - const devices = RTC.getCurrentlyAvailableMediaDevices(); - const device = devices - .find(d => d.kind === `${newTrack.getTrack().kind}input` && d.label === newTrack.getTrack().label); - - if (device) { - Statistics.sendActiveDeviceListEvent(RTC.getEventDataForActiveDevice(device)); - } - } - // Create a source name for this track if it doesn't exist. if (!newTrack.getSourceName()) { const sourceName = getSourceNameForJitsiTrack( @@ -2369,11 +2346,7 @@ JitsiConference.prototype.onCallEnded = function(jingleSession, reasonCondition, // Stop the stats if (this.statistics) { - this.statistics.stopRemoteStats( - this.jvbJingleSession.peerconnection); - logger.info('Stopping JVB CallStats'); - this.statistics.stopCallStats( - this.jvbJingleSession.peerconnection); + this.statistics.stopRemoteStats(this.jvbJingleSession.peerconnection); } // Current JVB JingleSession is no longer valid, so set it to null @@ -2686,7 +2659,7 @@ JitsiConference.prototype.getLocalParticipantProperty = function(name) { }; /** - * Sends the given feedback through CallStats if enabled. + * Sends the given feedback if enabled. * * @param overallFeedback an integer between 1 and 5 indicating the * user feedback @@ -2698,14 +2671,10 @@ JitsiConference.prototype.sendFeedback = function(overallFeedback, detailedFeedb }; /** - * Returns true if the callstats integration is enabled, otherwise returns - * false. - * - * @returns true if the callstats integration is enabled, otherwise returns - * false. + * @returns false, since callstats in not supported anymore. */ JitsiConference.prototype.isCallstatsEnabled = function() { - return this.statistics.isCallstatsEnabled(); + return false; }; /** @@ -2719,52 +2688,9 @@ JitsiConference.prototype.getSsrcByTrack = function(track) { }; /** - * Handles track attached to container (Calls associateStreamWithVideoTag method - * from statistics module) - * @param {JitsiLocalTrack|JitsiRemoteTrack} track the track - * @param container the container - */ -JitsiConference.prototype._onTrackAttach = function(track, container) { - const isLocal = track.isLocal(); - let ssrc = null; - const isP2P = track.isP2P; - const remoteUserId = isP2P ? track.getParticipantId() : 'jitsi'; - const peerConnection - = isP2P - ? this.p2pJingleSession && this.p2pJingleSession.peerconnection - : this.jvbJingleSession && this.jvbJingleSession.peerconnection; - - if (isLocal) { - // Local tracks have SSRC stored on per peer connection basis. - if (peerConnection) { - ssrc = peerConnection.getLocalSSRC(track); - } - } else { - ssrc = track.getSSRC(); - } - if (!container.id || !ssrc || !peerConnection) { - return; - } - - this.statistics.associateStreamWithVideoTag( - peerConnection, - ssrc, - isLocal, - remoteUserId, - track.getUsageLabel(), - container.id); -}; - -/** - * Logs an "application log" message. - * @param message {string} The message to log. Note that while this can be a - * generic string, the convention used by lib-jitsi-meet and jitsi-meet is to - * log valid JSON strings, with an "id" field used for distinguishing between - * message types. E.g.: {id: "recorder_status", status: "off"} + * This is a no-op since callstats is no longer supported. */ -JitsiConference.prototype.sendApplicationLog = function(message) { - Statistics.sendLog(message); -}; +JitsiConference.prototype.sendApplicationLog = function() { }; /** * Checks if the user identified by given mucJid is the conference focus. @@ -2988,16 +2914,6 @@ JitsiConference.prototype._acceptP2PIncomingCall = function(jingleSession, jingl enableInsertableStreams: this.isE2EEEnabled() || FeatureFlags.isRunInLiteModeEnabled() }); - logger.info('Starting CallStats for P2P connection...'); - - let remoteID = Strophe.getResourceFromJid(this.p2pJingleSession.remoteJid); - - const participant = this.participants.get(remoteID); - - if (participant) { - remoteID = participant.getStatsID() || remoteID; - } - const localTracks = this._getInitialLocalTracks(); this.p2pJingleSession.acceptOffer( @@ -3283,12 +3199,6 @@ JitsiConference.prototype._setP2PStatus = function(newStatus) { logger.info('Peer to peer connection closed!'); } - // Put the JVB connection on hold/resume - if (this.jvbJingleSession) { - this.statistics.sendConnectionResumeOrHoldEvent( - this.jvbJingleSession.peerconnection, !newStatus); - } - // Clear dtmfManager, so that it can be recreated with new connection this.dtmfManager = null; @@ -3494,8 +3404,6 @@ JitsiConference.prototype._stopP2PSession = function(options = {}) { // Stop P2P stats logger.info('Stopping remote stats for P2P connection'); this.statistics.stopRemoteStats(this.p2pJingleSession.peerconnection); - logger.info('Stopping CallStats for P2P connection'); - this.statistics.stopCallStats(this.p2pJingleSession.peerconnection); this.p2pJingleSession.terminate( () => { diff --git a/JitsiConferenceEventManager.js b/JitsiConferenceEventManager.js index ba9be2528b..2057f17531 100644 --- a/JitsiConferenceEventManager.js +++ b/JitsiConferenceEventManager.js @@ -31,26 +31,6 @@ const logger = getLogger(__filename); export default function JitsiConferenceEventManager(conference) { this.conference = conference; this.xmppListeners = {}; - - // Listeners related to the conference only - conference.on(JitsiConferenceEvents.TRACK_MUTE_CHANGED, - track => { - if (!track.isLocal() || !conference.statistics) { - return; - } - const session - = track.isP2P - ? conference.p2pJingleSession : conference.jvbJingleSession; - - // TPC will be null, before the conference starts, but the event - // still should be queued - const tpc = (session && session.peerconnection) || null; - - conference.statistics.sendMuteEvent( - tpc, - track.isMuted(), - track.getType()); - }); } /** @@ -360,20 +340,6 @@ JitsiConferenceEventManager.prototype.setupChatRoomListeners = function() { chatRoom.addListener(XMPPEvents.LOCAL_ROLE_CHANGED, role => { conference.onLocalRoleChanged(role); - - // log all events for the recorder operated by the moderator - if (conference.statistics && conference.isModerator()) { - conference.on(JitsiConferenceEvents.RECORDER_STATE_CHANGED, - recorderSession => { - const logObject = { - error: recorderSession.getError(), - id: 'recorder_status', - status: recorderSession.getStatus() - }; - - Statistics.sendLog(JSON.stringify(logObject)); - }); - } }); chatRoom.addListener(XMPPEvents.MUC_ROLE_CHANGED, @@ -475,21 +441,6 @@ JitsiConferenceEventManager.prototype.setupChatRoomListeners = function() { } }); - if (conference.statistics) { - // FIXME ICE related events should end up in RTCEvents eventually - chatRoom.addListener(XMPPEvents.CONNECTION_ICE_FAILED, - session => { - conference.statistics.sendIceConnectionFailedEvent( - session.peerconnection); - }); - - // FIXME XMPPEvents.ADD_ICE_CANDIDATE_FAILED is never emitted - chatRoom.addListener(XMPPEvents.ADD_ICE_CANDIDATE_FAILED, - (e, pc) => { - conference.statistics.sendAddIceCandidateFailed(e, pc); - }); - } - // Breakout rooms. this.chatRoomForwarder.forward(XMPPEvents.BREAKOUT_ROOMS_MOVE_TO_ROOM, JitsiConferenceEvents.BREAKOUT_ROOMS_MOVE_TO_ROOM); @@ -526,7 +477,7 @@ JitsiConferenceEventManager.prototype.setupRTCListeners = function() { JitsiConferenceEvents.DOMINANT_SPEAKER_CHANGED, dominant, previous, silence); if (conference.statistics && conference.myUserId() === dominant) { // We are the new dominant speaker. - conference.statistics.sendDominantSpeakerEvent(conference.room.roomjid, silence); + conference.xmpp.sendDominantSpeakerEvent(conference.room.roomjid, silence); } if (conference.lastDominantSpeaker !== dominant) { if (previous && previous.length) { @@ -603,30 +554,8 @@ JitsiConferenceEventManager.prototype.setupRTCListeners = function() { } }); - rtc.addListener(RTCEvents.LOCAL_UFRAG_CHANGED, - (tpc, ufrag) => { - if (!tpc.isP2P) { - Statistics.sendLog( - JSON.stringify({ - id: 'local_ufrag', - value: ufrag - })); - } - }); - rtc.addListener(RTCEvents.REMOTE_UFRAG_CHANGED, - (tpc, ufrag) => { - if (!tpc.isP2P) { - Statistics.sendLog( - JSON.stringify({ - id: 'remote_ufrag', - value: ufrag - })); - } - }); - rtc.addListener(RTCEvents.CREATE_ANSWER_FAILED, (e, tpc) => { - conference.statistics.sendCreateAnswerFailed(e, tpc); if (!tpc.isP2P) { conference.eventEmitter.emit(JitsiConferenceEvents.CONFERENCE_FAILED, JitsiConferenceErrors.OFFER_ANSWER_FAILED, e); @@ -635,7 +564,6 @@ JitsiConferenceEventManager.prototype.setupRTCListeners = function() { rtc.addListener(RTCEvents.CREATE_OFFER_FAILED, (e, tpc) => { - conference.statistics.sendCreateOfferFailed(e, tpc); if (!tpc.isP2P) { conference.eventEmitter.emit(JitsiConferenceEvents.CONFERENCE_FAILED, JitsiConferenceErrors.OFFER_ANSWER_FAILED, e); @@ -644,7 +572,6 @@ JitsiConferenceEventManager.prototype.setupRTCListeners = function() { rtc.addListener(RTCEvents.SET_LOCAL_DESCRIPTION_FAILED, (e, tpc) => { - conference.statistics.sendSetLocalDescFailed(e, tpc); if (!tpc.isP2P) { conference.eventEmitter.emit(JitsiConferenceEvents.CONFERENCE_FAILED, JitsiConferenceErrors.OFFER_ANSWER_FAILED, e); @@ -653,23 +580,11 @@ JitsiConferenceEventManager.prototype.setupRTCListeners = function() { rtc.addListener(RTCEvents.SET_REMOTE_DESCRIPTION_FAILED, (e, tpc) => { - conference.statistics.sendSetRemoteDescFailed(e, tpc); if (!tpc.isP2P) { conference.eventEmitter.emit(JitsiConferenceEvents.CONFERENCE_FAILED, JitsiConferenceErrors.OFFER_ANSWER_FAILED, e); } }); - - rtc.addListener(RTCEvents.LOCAL_TRACK_SSRC_UPDATED, - (track, ssrc) => { - // when starting screen sharing, the track is created and when - // we do set local description and we process the ssrc we - // will be notified for it and we will report it with the event - // for screen sharing - if (track.isVideoTrack() && track.videoType === VideoType.DESKTOP) { - conference.statistics.sendScreenSharingEvent(true, ssrc); - } - }); }; /** diff --git a/JitsiConferenceEvents.ts b/JitsiConferenceEvents.ts index 29d542ccd9..b02b29d3ca 100644 --- a/JitsiConferenceEvents.ts +++ b/JitsiConferenceEvents.ts @@ -22,8 +22,7 @@ export enum JitsiConferenceEvents { /** * Fired just before the statistics module is disposed and it's the last chance - * to submit some logs to the statistics service (ex. CallStats if enabled), - * before it's disconnected. + * to submit some logs to the statistics service before it's disconnected. */ BEFORE_STATISTICS_DISPOSED = 'conference.beforeStatisticsDisposed', diff --git a/JitsiConnection.js b/JitsiConnection.js index 1835a1625b..95b417b9ef 100644 --- a/JitsiConnection.js +++ b/JitsiConnection.js @@ -43,12 +43,6 @@ export default function JitsiConnection(appID, token, options) { ANALYTICS_CONNECTION_DISCONNECTED, { message: msg }); } - Statistics.sendLog( - JSON.stringify( - { - id: ANALYTICS_CONNECTION_DISCONNECTED, - msg - })); }); } diff --git a/JitsiMediaDevices.js b/JitsiMediaDevices.js index 59cbb7646e..adcce4d682 100644 --- a/JitsiMediaDevices.js +++ b/JitsiMediaDevices.js @@ -29,12 +29,6 @@ class JitsiMediaDevices { this._eventEmitter.emit( JitsiMediaDevicesEvents.DEVICE_LIST_CHANGED, devices)); - RTC.addListener( - RTCEvents.DEVICE_LIST_AVAILABLE, - devices => - this._logOutputDevice( - this.getAudioOutputDevice(), - devices)); // We would still want to update the permissions cache in case the permissions API is not supported. RTC.addListener( @@ -146,22 +140,6 @@ class JitsiMediaDevices { } } - /** - * Gathers data and sends it to statistics. - * @param deviceID the device id to log - * @param devices list of devices - */ - _logOutputDevice(deviceID, devices) { - const device - = devices.find( - d => d.kind === 'audiooutput' && d.deviceId === deviceID); - - if (device) { - Statistics.sendActiveDeviceListEvent( - RTC.getEventDataForActiveDevice(device)); - } - } - /** * Executes callback with list of media devices connected. * @param {function} callback @@ -286,16 +264,6 @@ class JitsiMediaDevices { * otherwise */ setAudioOutputDevice(deviceId) { - const availableDevices = RTC.getCurrentlyAvailableMediaDevices(); - - if (availableDevices.length > 0) { - // if we have devices info report device to stats - // normally this will not happen on startup as this method is called - // too early. This will happen only on user selection of new device - this._logOutputDevice( - deviceId, RTC.getCurrentlyAvailableMediaDevices()); - } - return RTC.setAudioOutputDevice(deviceId); } diff --git a/JitsiMeetJS.ts b/JitsiMeetJS.ts index 8802105d60..c825a358f5 100644 --- a/JitsiMeetJS.ts +++ b/JitsiMeetJS.ts @@ -157,16 +157,6 @@ export default { this.getGlobalOnErrorHandler.bind(this)); } - if (this.version) { - const logObject = { - id: 'component_version', - component: 'lib-jitsi-meet', - version: this.version - }; - - Statistics.sendLog(JSON.stringify(logObject)); - } - return RTC.init(options); }, @@ -378,16 +368,6 @@ export default { promiseFulfilled = true; if (error.name === JitsiTrackErrors.SCREENSHARING_USER_CANCELED) { - // User cancelled action is not really an error, so only - // log it as an event to avoid having conference classified - // as partially failed - const logObject = { - id: 'screensharing_user_canceled', - message: error.message - }; - - Statistics.sendLog(JSON.stringify(logObject)); - Statistics.sendAnalytics( createGetUserMediaEvent( 'warning', @@ -395,14 +375,6 @@ export default { reason: 'extension install user canceled' })); } else if (error.name === JitsiTrackErrors.NOT_FOUND) { - // logs not found devices with just application log to cs - const logObject = { - id: 'usermedia_missing_device', - status: error.gum.devices - }; - - Statistics.sendLog(JSON.stringify(logObject)); - const attributes = getAnalyticsAttributesFromOptions(options); @@ -411,9 +383,6 @@ export default { Statistics.sendAnalytics( createGetUserMediaEvent('error', attributes)); } else { - // Report gUM failed to the stats - Statistics.sendGetUserMediaFailed(error); - const attributes = getAnalyticsAttributesFromOptions(options); @@ -546,7 +515,6 @@ export default { `Line: ${lineno}`, `Column: ${colno}`, 'StackTrace: ', error); - Statistics.reportGlobalError(error); }, /* eslint-enable max-params */ diff --git a/modules/RTC/JitsiLocalTrack.js b/modules/RTC/JitsiLocalTrack.js index 76c1be105b..cc4caf705e 100644 --- a/modules/RTC/JitsiLocalTrack.js +++ b/modules/RTC/JitsiLocalTrack.js @@ -233,7 +233,7 @@ export default class JitsiLocalTrack extends JitsiTrack { } /** - * Fires NO_DATA_FROM_SOURCE event and logs it to analytics and callstats. + * Fires NO_DATA_FROM_SOURCE event and logs it to analytics * * @private * @returns {void} @@ -247,10 +247,6 @@ export default class JitsiLocalTrack extends JitsiTrack { // FIXME: Should we report all of those events Statistics.sendAnalytics(createNoDataFromSourceEvent(this.getType(), value)); - Statistics.sendLog(JSON.stringify({ - name: NO_DATA_FROM_SOURCE, - log: value - })); } /** @@ -817,14 +813,6 @@ export default class JitsiLocalTrack extends JitsiTrack { */ setConference(conference) { this.conference = conference; - - // We want to keep up with postponed events which should have been fired - // on "attach" call, but for local track we not always have the - // conference before attaching. However this may result in duplicated - // events if they have been triggered on "attach" already. - for (let i = 0; i < this.containers.length; i++) { - this._maybeFireTrackAttached(this.containers[i]); - } } /** diff --git a/modules/RTC/JitsiTrack.js b/modules/RTC/JitsiTrack.js index 54d398991f..0e7b553dee 100644 --- a/modules/RTC/JitsiTrack.js +++ b/modules/RTC/JitsiTrack.js @@ -107,18 +107,6 @@ export default class JitsiTrack extends EventEmitter { // Should be defined by the classes that are extending JitsiTrack } - /** - * Eventually will trigger RTCEvents.TRACK_ATTACHED event. - * @param container the video/audio container to which this stream is - * attached and for which event will be fired. - * @private - */ - _maybeFireTrackAttached(container) { - if (this.conference && container) { - this.conference._onTrackAttach(this, container); - } - } - /** * Called when the track has been attached to a new container. * @@ -235,7 +223,6 @@ export default class JitsiTrack extends EventEmitter { result = RTCUtils.attachMediaStream(container, this.stream); } this.containers.push(container); - this._maybeFireTrackAttached(container); this._attachTTFMTracker(container); return result; diff --git a/modules/RTCStats/RTCStats.ts b/modules/RTCStats/RTCStats.ts index 7449a7e0e1..a6a8764c6c 100644 --- a/modules/RTCStats/RTCStats.ts +++ b/modules/RTCStats/RTCStats.ts @@ -15,20 +15,6 @@ import { RTC_STATS_PC_EVENT, RTC_STATS_WC_DISCONNECTED } from './RTCStatsEvents' const logger = getLogger(__filename); -/** - * Filter out RTCPeerConnection that are created by callstats.io. - * - * @param {*} config - Config object sent to the PC c'tor. - * @returns {boolean} - */ -function connectionFilter(config) { - for(const iceUrl of (config?.iceServers ?? [])[0]?.urls ?? []) { - if (iceUrl.includes('callstats.io')) { - return true; - } - } -} - /** * RTCStats Singleton that is initialized only once for the lifetime of the app, subsequent calls to init will be ignored. * Config and conference changes are handled by the start method. @@ -63,8 +49,7 @@ class RTCStats { rtcstatsInit( { statsEntry: this.sendStatsEntry.bind(this) }, - { connectionFilter, - pollInterval, + { pollInterval, useLegacy, sendSdp, eventCallback: (event) => this.events.emit(RTC_STATS_PC_EVENT, event)} diff --git a/modules/connectivity/TrackStreamingStatus.ts b/modules/connectivity/TrackStreamingStatus.ts index 193a83db75..61c0509440 100644 --- a/modules/connectivity/TrackStreamingStatus.ts +++ b/modules/connectivity/TrackStreamingStatus.ts @@ -329,14 +329,6 @@ export class TrackStreamingStatusImpl { logger.debug(`Emit track streaming status(${Date.now()}) ${sourceName}: ${newStatus}`); - // Log the event on CallStats - Statistics.sendLog( - JSON.stringify({ - id: 'track.streaming.status', - track: sourceName, - status: newStatus - })); - // It's common for the event listeners to access the JitsiRemoteTrack. Thus pass it as a parameter here. this.track.emit(JitsiTrackEvents.TRACK_STREAMING_STATUS_CHANGED, this.track, newStatus); } diff --git a/modules/settings/Settings.js b/modules/settings/Settings.js index b2fef5116e..6f0d6ffa7a 100644 --- a/modules/settings/Settings.js +++ b/modules/settings/Settings.js @@ -30,14 +30,14 @@ export default { }, /** - * Returns fake username for callstats + * Returns the ID to use for the purposes of stats, saved in localstorage as "callStatsUserName". * @returns {string} fake username for callstats */ get callStatsUserName() { if (!_callStatsUserName) { _callStatsUserName = this._storage.getItem('callStatsUserName'); if (!_callStatsUserName) { - _callStatsUserName = generateCallStatsUserName(); + _callStatsUserName = _generateStatsId(); this._storage.setItem('callStatsUserName', _callStatsUserName); } } @@ -90,13 +90,13 @@ export default { }; /** - * Generate fake username for callstats. - * @returns {string} fake random username + * Generate a random ID to be used for statistics. + * @returns {string} the random ID */ -function generateCallStatsUserName() { +function _generateStatsId() { const username = UsernameGenerator.generateUsername(); - logger.log('generated callstats uid', username); + logger.log('generated stats id', username); return username; } diff --git a/modules/statistics/CallStats.js b/modules/statistics/CallStats.js deleted file mode 100644 index 35a08bed4c..0000000000 --- a/modules/statistics/CallStats.js +++ /dev/null @@ -1,787 +0,0 @@ -/* global callstats */ - -import browser from '../browser'; -import GlobalOnErrorHandler from '../util/GlobalOnErrorHandler'; - -const logger = require('@jitsi/logger').getLogger(__filename); - -/** - * We define enumeration of wrtcFuncNames as we need them before - * callstats is initialized to queue events. - * @const - * @see http://www.callstats.io/api/#enumeration-of-wrtcfuncnames - */ -const wrtcFuncNames = { - createOffer: 'createOffer', - createAnswer: 'createAnswer', - setLocalDescription: 'setLocalDescription', - setRemoteDescription: 'setRemoteDescription', - addIceCandidate: 'addIceCandidate', - getUserMedia: 'getUserMedia', - iceConnectionFailure: 'iceConnectionFailure', - signalingError: 'signalingError', - applicationLog: 'applicationLog' -}; - -/** - * We define enumeration of fabricEvent as we need them before - * callstats is initialized to queue events. - * @const - * @see http://www.callstats.io/api/#enumeration-of-fabricevent - */ -const fabricEvent = { - fabricHold: 'fabricHold', - fabricResume: 'fabricResume', - audioMute: 'audioMute', - audioUnmute: 'audioUnmute', - videoPause: 'videoPause', - videoResume: 'videoResume', - fabricUsageEvent: 'fabricUsageEvent', - fabricStats: 'fabricStats', - fabricTerminated: 'fabricTerminated', - screenShareStart: 'screenShareStart', - screenShareStop: 'screenShareStop', - dominantSpeaker: 'dominantSpeaker', - activeDeviceList: 'activeDeviceList' -}; - -/** - * The user id to report to callstats as destination. - * @type {string} - */ -const DEFAULT_REMOTE_USER = 'jitsi'; - -/** - * Type of pending reports, can be event or an error. - * @type {{ERROR: string, EVENT: string}} - */ -const reportType = { - ERROR: 'error', - EVENT: 'event', - MST_WITH_USERID: 'mstWithUserID' -}; - -/** - * Set of currently existing {@link CallStats} instances. - * @type {Set} - */ -let _fabrics; - -/** - * An instance of this class is a wrapper for the CallStats API fabric. A fabric - * reports one peer connection to the CallStats backend and is allocated with - * {@link callstats.addNewFabric}. It has a bunch of instance methods for - * reporting various events. A fabric is considered disposed when - * {@link CallStats.sendTerminateEvent} is executed. - * - * Currently only one backend instance can be created ever and it's done using - * {@link CallStats.initBackend}. At the time of this writing there is no way to - * explicitly shutdown the backend, but it's supposed to close it's connection - * automatically, after all fabrics have been terminated. - */ -export default class CallStats { - /** - * A callback passed to {@link callstats.addNewFabric}. - * @param {string} error 'success' means ok - * @param {string} msg some more details - * @private - */ - static _addNewFabricCallback(error, msg) { - if (CallStats.backend && error !== 'success') { - logger.error(`Monitoring status: ${error} msg: ${msg}`); - } - } - - /** - * Callback passed to {@link callstats.initialize} (backend initialization) - * @param {string} error 'success' means ok - * @param {String} msg - * @private - */ - static _initCallback(error, msg) { - logger.log(`CallStats Status: err=${error} msg=${msg}`); - - // there is no lib, nothing to report to - if (error !== 'success') { - return; - } - - CallStats.backendInitialized = true; - - // I hate that - let atLeastOneFabric = false; - let defaultInstance = null; - - for (const callStatsInstance of CallStats.fabrics.values()) { - if (!callStatsInstance.hasFabric) { - logger.debug('addNewFabric - initCallback'); - if (callStatsInstance._addNewFabric()) { - atLeastOneFabric = true; - if (!defaultInstance) { - defaultInstance = callStatsInstance; - } - } - } - } - - if (!atLeastOneFabric) { - return; - } - - CallStats._emptyReportQueue(defaultInstance); - } - - /** - * Empties report queue. - * - * @param {CallStats} csInstance - The callstats instance. - * @private - */ - static _emptyReportQueue(csInstance) { - // There is no conference ID nor a PeerConnection available when some of - // the events are scheduled on the reportsQueue, so those will be - // reported on the first initialized fabric. - const defaultConfID = csInstance.confID; - const defaultPC = csInstance.peerconnection; - - // notify callstats about failures if there were any - for (const report of CallStats.reportsQueue) { - if (report.type === reportType.ERROR) { - const errorData = report.data; - - CallStats._reportError( - csInstance, - errorData.type, - errorData.error, - errorData.pc || defaultPC); - } else if (report.type === reportType.EVENT) { - // if we have and event to report and we failed to add - // fabric this event will not be reported anyway, returning - // an error - const eventData = report.data; - - CallStats.backend.sendFabricEvent( - report.pc || defaultPC, - eventData.event, - defaultConfID, - eventData.eventData); - } else if (report.type === reportType.MST_WITH_USERID) { - const data = report.data; - - CallStats.backend.associateMstWithUserID( - report.pc || defaultPC, - data.callStatsId, - defaultConfID, - data.ssrc, - data.usageLabel, - data.containerId - ); - } - } - CallStats.reportsQueue.length = 0; - } - - /* eslint-disable max-params */ - /** - * Reports an error to callstats. - * - * @param {CallStats} [cs] - * @param type the type of the error, which will be one of the wrtcFuncNames - * @param error the error - * @param pc the peerconnection - * @private - */ - static _reportError(cs, type, error, pc) { - let _error = error; - - if (!_error) { - logger.warn('No error is passed!'); - _error = new Error('Unknown error'); - } - if (CallStats.backendInitialized && cs) { - CallStats.backend.reportError(pc, cs.confID, type, _error); - } else { - CallStats.reportsQueue.push({ - type: reportType.ERROR, - data: { - error: _error, - pc, - type - } - }); - } - - // else just ignore it - } - - /* eslint-enable max-params */ - - /** - * Reports an error to callstats. - * - * @param {CallStats} cs - * @param event the type of the event, which will be one of the fabricEvent - * @param eventData additional data to pass to event - * @private - */ - static _reportEvent(cs, event, eventData) { - const pc = cs && cs.peerconnection; - const confID = cs && cs.confID; - - if (CallStats.backendInitialized && cs) { - CallStats.backend.sendFabricEvent(pc, event, confID, eventData); - } else { - CallStats.reportsQueue.push({ - confID, - pc, - type: reportType.EVENT, - data: { event, - eventData } - }); - } - } - - /** - * Wraps some of the CallStats API method and logs their calls with - * arguments on the debug logging level. Also wraps some of the backend - * methods execution into try catch blocks to not crash the app in case - * there is a problem with the backend itself. - * @param {callstats} theBackend - * @private - */ - static _traceAndCatchBackendCalls(theBackend) { - const tryCatchMethods = [ - 'associateMstWithUserID', - 'sendFabricEvent', - 'sendUserFeedback' - - // 'reportError', - this one needs special handling - see code below - ]; - - for (const methodName of tryCatchMethods) { - const originalMethod = theBackend[methodName]; - - theBackend[methodName] = function(...theArguments) { - try { - return originalMethod.apply(theBackend, theArguments); - } catch (e) { - GlobalOnErrorHandler.callErrorHandler(e); - } - }; - } - const debugMethods = [ - 'associateMstWithUserID', - 'sendFabricEvent', - 'sendUserFeedback' - - // 'reportError', - this one needs special handling - see code below - ]; - - for (const methodName of debugMethods) { - const originalMethod = theBackend[methodName]; - - theBackend[methodName] = function(...theArguments) { - logger.debug(methodName, theArguments); - originalMethod.apply(theBackend, theArguments); - }; - } - const originalReportError = theBackend.reportError; - - /* eslint-disable max-params */ - theBackend.reportError = function(pc, cs, type, ...args) { - // Logs from the logger are submitted on the applicationLog event - // "type". Logging the arguments on the logger will create endless - // loop, because it will put all the logs to the logger queue again. - if (type === wrtcFuncNames.applicationLog) { - // NOTE otherArguments are not logged to the console on purpose - // to not log the whole log batch - // FIXME check the current logging level (currently not exposed - // by the logger implementation) - // NOTE it is not safe to log whole objects on react-native as - // those contain too many circular references and may crash - // the app. - if (!browser.isReactNative()) { - console && console.debug('reportError', pc, cs, type); - } - } else { - logger.debug('reportError', pc, cs, type, ...args); - } - try { - originalReportError.call(theBackend, pc, cs, type, ...args); - } catch (exception) { - if (type === wrtcFuncNames.applicationLog) { - console && console.error('reportError', exception); - } else { - GlobalOnErrorHandler.callErrorHandler(exception); - } - } - }; - - /* eslint-enable max-params */ - } - - /** - * Returns the Set with the currently existing {@link CallStats} instances. - * Lazily initializes the Set to allow any Set polyfills to be applied. - * @type {Set} - */ - static get fabrics() { - if (!_fabrics) { - _fabrics = new Set(); - } - - return _fabrics; - } - - /** - * Initializes the CallStats backend. Should be called only if - * {@link CallStats.isBackendInitialized} returns false. - * @param {object} options - * @param {String} options.callStatsID CallStats credentials - ID - * @param {String} options.callStatsSecret CallStats credentials - secret - * @param {string} options.aliasName the aliasName part of - * the userID aka endpoint ID, see CallStats docs for more info. - * @param {string} options.userName the userName part of - * the userID aka display name, see CallStats docs for more info. - * @param {object} options.configParams the set of parameters - * to enable/disable certain features in the library. See CallStats docs for more info. - * - */ - static initBackend(options) { - if (CallStats.backend) { - throw new Error('CallStats backend has been initialized already!'); - } - try { - const CallStatsBackend = callstats; - - CallStats.backend = new CallStatsBackend(); - CallStats._traceAndCatchBackendCalls(CallStats.backend); - CallStats.userID = { - aliasName: options.aliasName, - userName: options.userName - }; - CallStats.callStatsID = options.callStatsID; - CallStats.callStatsSecret = options.callStatsSecret; - - const configParams = { ...options.configParams }; - - if (options.applicationName) { - configParams.applicationVersion = `${options.applicationName} (${browser.getName()})`; - } - - if (options.confID) { - // we first check is there a tenant in the confID - const match = options.confID.match(/.*\/(.*)\/.*/); - - // if there is no tenant, we will just set '/' - configParams.siteID = options.siteID || (match && match[1]) || '/'; - } - - // userID is generated or given by the origin server - CallStats.backend.initialize( - CallStats.callStatsID, - CallStats.callStatsSecret, - CallStats.userID, - CallStats._initCallback, - undefined, - configParams); - - return true; - } catch (e) { - // The callstats.io API failed to initialize (e.g. because its - // download did not succeed in general or on time). Further attempts - // to utilize it cannot possibly succeed. - GlobalOnErrorHandler.callErrorHandler(e); - CallStats.backend = null; - logger.error(e); - - return false; - } - } - - /** - * Checks if the CallStats backend has been created. It does not mean that - * it has been initialized, but only that the API instance has been - * allocated successfully. - * @return {boolean} true if backend exists or false - * otherwise - */ - static isBackendInitialized() { - return Boolean(CallStats.backend); - } - - /** - * Notifies CallStats about active device. - * @param {{deviceList: {String:String}}} devicesData list of devices with - * their data - * @param {CallStats} cs callstats instance related to the event - */ - static sendActiveDeviceListEvent(devicesData, cs) { - CallStats._reportEvent(cs, fabricEvent.activeDeviceList, devicesData); - } - - /** - * Notifies CallStats that there is a log we want to report. - * - * @param {Error} e error to send or {String} message - * @param {CallStats} cs callstats instance related to the error (optional) - */ - static sendApplicationLog(e, cs) { - try { - CallStats._reportError( - cs, - wrtcFuncNames.applicationLog, - e, - cs && cs.peerconnection); - } catch (error) { - // If sendApplicationLog fails it should not be printed to - // the logger, because it will try to push the logs again - // (through sendApplicationLog) and an endless loop is created. - if (console && (typeof console.error === 'function')) { - // FIXME send analytics event as well - console.error('sendApplicationLog failed', error); - } - } - } - - /** - * Sends the given feedback through CallStats. - * - * @param {string} conferenceID the conference ID for which the feedback - * will be reported. - * @param overall an integer between 1 and 5 indicating the - * user feedback - * @param comment detailed feedback from the user. - */ - static sendFeedback(conferenceID, overall, comment) { - return new Promise((resolve, reject) => { - if (CallStats.backend) { - CallStats.backend.sendUserFeedback( - conferenceID, - { - userID: CallStats.userID, - overall, - comment - }, - (status, message) => { - if (status === 'success') { - resolve(message); - } else { - reject(message); - } - }); - } else { - const reason = 'Failed to submit feedback to CallStats - no backend'; - - logger.error(reason); - reject(reason); - } - }); - } - - /** - * Notifies CallStats that getUserMedia failed. - * - * @param {Error} e error to send - * @param {CallStats} cs callstats instance related to the error (optional) - */ - static sendGetUserMediaFailed(e, cs) { - CallStats._reportError(cs, wrtcFuncNames.getUserMedia, e, null); - } - - /** - * Notifies CallStats for mute events - * @param mute {boolean} true for muted and false for not muted - * @param type {String} "audio"/"video" - * @param {CallStats} cs callstats instance related to the event - */ - static sendMuteEvent(mute, type, cs) { - let event; - - if (type === 'video') { - event = mute ? fabricEvent.videoPause : fabricEvent.videoResume; - } else { - event = mute ? fabricEvent.audioMute : fabricEvent.audioUnmute; - } - - CallStats._reportEvent(cs, event); - } - - /** - * Creates new CallStats instance that handles all callstats API calls for - * given {@link TraceablePeerConnection}. Each instance is meant to handle - * one CallStats fabric added with 'addFabric' API method for the - * {@link TraceablePeerConnection} instance passed in the constructor. - * @param {TraceablePeerConnection} tpc - * @param {Object} options - * @param {string} options.confID the conference ID that wil be used to - * report the session. - * @param {string} [options.remoteUserID='jitsi'] the remote user ID to - * which given tpc is connected. - */ - constructor(tpc, options) { - this.confID = options.confID; - this.tpc = tpc; - this.peerconnection = tpc.peerconnection; - this.remoteUserID = options.remoteUserID || DEFAULT_REMOTE_USER; - this.hasFabric = false; - - CallStats.fabrics.add(this); - - if (CallStats.backendInitialized) { - this._addNewFabric(); - - // if this is the first fabric let's try to empty the - // report queue. Reports all events that we recorded between - // backend initialization and receiving the first fabric - if (CallStats.fabrics.size === 1) { - CallStats._emptyReportQueue(this); - } - } - } - - /** - * Initializes CallStats fabric by calling "addNewFabric" for - * the peer connection associated with this instance. - * @return {boolean} true if the call was successful or false otherwise. - */ - _addNewFabric() { - logger.info('addNewFabric', this.remoteUserID); - try { - const fabricAttributes = { - remoteEndpointType: - this.tpc.isP2P - ? CallStats.backend.endpointType.peer - : CallStats.backend.endpointType.server - }; - const ret - = CallStats.backend.addNewFabric( - this.peerconnection, - this.remoteUserID, - CallStats.backend.fabricUsage.multiplex, - this.confID, - fabricAttributes, - CallStats._addNewFabricCallback); - - this.hasFabric = true; - - const success = ret.status === 'success'; - - if (!success) { - logger.error('callstats fabric not initilized', ret.message); - } - - return success; - - } catch (error) { - GlobalOnErrorHandler.callErrorHandler(error); - - return false; - } - } - - /* eslint-disable max-params */ - - /** - * Lets CallStats module know where is given SSRC rendered by providing - * renderer tag ID. - * If the lib is not initialized yet queue the call for later, when it's - * ready. - * @param {number} ssrc the SSRC of the stream - * @param {boolean} isLocal indicates whether this the stream is local - * @param {string|null} streamEndpointId if the stream is not local the it - * needs to contain the stream owner's ID - * @param {string} usageLabel meaningful usage label of this stream like - * 'microphone', 'camera' or 'screen'. - * @param {string} containerId the id of media 'audio' or 'video' tag which - * renders the stream. - */ - associateStreamWithVideoTag( - ssrc, - isLocal, - streamEndpointId, - usageLabel, - containerId) { - if (!CallStats.backend) { - return; - } - - const callStatsId = isLocal ? CallStats.userID : streamEndpointId; - - if (CallStats.backendInitialized) { - CallStats.backend.associateMstWithUserID( - this.peerconnection, - callStatsId, - this.confID, - ssrc, - usageLabel, - containerId); - } else { - CallStats.reportsQueue.push({ - type: reportType.MST_WITH_USERID, - pc: this.peerconnection, - data: { - callStatsId, - containerId, - ssrc, - usageLabel - } - }); - } - } - - /* eslint-enable max-params */ - - /** - * Notifies CallStats that we are the new dominant speaker in the - * conference. - */ - sendDominantSpeakerEvent() { - CallStats._reportEvent(this, fabricEvent.dominantSpeaker); - } - - /** - * Notifies CallStats that the fabric for the underlying peerconnection was - * closed and no evens should be reported, after this call. - */ - sendTerminateEvent() { - if (CallStats.backendInitialized) { - CallStats.backend.sendFabricEvent( - this.peerconnection, - CallStats.backend.fabricEvent.fabricTerminated, - this.confID); - } - CallStats.fabrics.delete(this); - } - - /** - * Notifies CallStats for ice connection failed - */ - sendIceConnectionFailedEvent() { - CallStats._reportError( - this, - wrtcFuncNames.iceConnectionFailure, - null, - this.peerconnection); - } - - /** - * Notifies CallStats that peer connection failed to create offer. - * - * @param {Error} e error to send - */ - sendCreateOfferFailed(e) { - CallStats._reportError( - this, wrtcFuncNames.createOffer, e, this.peerconnection); - } - - /** - * Notifies CallStats that peer connection failed to create answer. - * - * @param {Error} e error to send - */ - sendCreateAnswerFailed(e) { - CallStats._reportError( - this, wrtcFuncNames.createAnswer, e, this.peerconnection); - } - - /** - * Sends either resume or hold event for the fabric associated with - * the underlying peerconnection. - * @param {boolean} isResume true to resume or false to hold - */ - sendResumeOrHoldEvent(isResume) { - CallStats._reportEvent( - this, - isResume ? fabricEvent.fabricResume : fabricEvent.fabricHold); - } - - /** - * Notifies CallStats for screen sharing events - * @param {boolean} start true for starting screen sharing and - * false for not stopping - * @param {string|null} ssrc - optional ssrc value, used only when - * starting screen sharing. - */ - sendScreenSharingEvent(start, ssrc) { - let eventData; - - if (ssrc) { - eventData = { ssrc }; - } - - CallStats._reportEvent( - this, - start ? fabricEvent.screenShareStart : fabricEvent.screenShareStop, - eventData); - } - - /** - * Notifies CallStats that peer connection failed to set local description. - * - * @param {Error} e error to send - */ - sendSetLocalDescFailed(e) { - CallStats._reportError( - this, wrtcFuncNames.setLocalDescription, e, this.peerconnection); - } - - /** - * Notifies CallStats that peer connection failed to set remote description. - * - * @param {Error} e error to send - */ - sendSetRemoteDescFailed(e) { - CallStats._reportError( - this, wrtcFuncNames.setRemoteDescription, e, this.peerconnection); - } - - /** - * Notifies CallStats that peer connection failed to add ICE candidate. - * - * @param {Error} e error to send - */ - sendAddIceCandidateFailed(e) { - CallStats._reportError( - this, wrtcFuncNames.addIceCandidate, e, this.peerconnection); - } -} - -/** - * The CallStats API backend instance - * @type {callstats} - */ -CallStats.backend = null; - -// some errors/events may happen before CallStats init -// in this case we accumulate them in this array -// and send them to callstats on init -CallStats.reportsQueue = []; - -/** - * Whether the library was successfully initialized(the backend) using its - * initialize method. - * @type {boolean} - */ -CallStats.backendInitialized = false; - -/** - * Part of the CallStats credentials - application ID - * @type {string} - */ -CallStats.callStatsID = null; - -/** - * Part of the CallStats credentials - application secret - * @type {string} - */ -CallStats.callStatsSecret = null; - -/** - * Local CallStats user ID structure. Can be set only once when - * {@link backend} is initialized, so it's static for the time being. - * See CallStats API for more info: - * https://www.callstats.io/api/#userid - * @type {object} - */ -CallStats.userID = null; diff --git a/modules/statistics/constants.js b/modules/statistics/constants.js index 386b24eb56..6c321bde4b 100644 --- a/modules/statistics/constants.js +++ b/modules/statistics/constants.js @@ -1,5 +1,3 @@ -export const CALLSTATS_SCRIPT_URL = 'https://api.callstats.io/static/callstats-ws.min.js'; - /** * The number of remote speakers for which the audio levels will be calculated using * RTCRtpReceiver#getSynchronizationSources. Limit the number of endpoints to save cpu on the client as this API call diff --git a/modules/statistics/statistics.js b/modules/statistics/statistics.js index afb2a95d03..6329601a92 100644 --- a/modules/statistics/statistics.js +++ b/modules/statistics/statistics.js @@ -11,11 +11,9 @@ import ScriptUtil from '../util/ScriptUtil'; import WatchRTC from '../watchRTC/WatchRTC'; import analytics from './AnalyticsAdapter'; -import CallStats from './CallStats'; import LocalStats from './LocalStatsCollector'; import { PerformanceObserverStats } from './PerformanceObserverStats'; import RTPStats from './RTPStatsCollector'; -import { CALLSTATS_SCRIPT_URL } from './constants'; const logger = require('@jitsi/logger').getLogger(__filename); @@ -25,91 +23,6 @@ const logger = require('@jitsi/logger').getLogger(__filename); */ let _instances; -/** - * True if callstats API is loaded - */ -let isCallstatsLoaded = false; - -/** - * Since callstats.io is a third party, we cannot guarantee the quality of their - * service. More specifically, their server may take noticeably long time to - * respond. Consequently, it is in our best interest (in the sense that the - * intergration of callstats.io is pretty important to us but not enough to - * allow it to prevent people from joining a conference) to (1) start - * downloading their API as soon as possible and (2) do the downloading - * asynchronously. - * - * @param {StatisticsOptions} options - Options to use for downloading and - * initializing callstats backend. - */ -function loadCallStatsAPI(options) { - if (!isCallstatsLoaded) { - ScriptUtil.loadScript( - options.customScriptUrl || CALLSTATS_SCRIPT_URL, - /* async */ true, - /* prepend */ true, - /* relativeURL */ undefined, - /* loadCallback */ () => _initCallStatsBackend(options) - ); - isCallstatsLoaded = true; - } -} - -/** - * Initializes Callstats backend. - * - * @param {StatisticsOptions} options - The options to use for initializing - * callstats backend. - * @private - */ -function _initCallStatsBackend(options) { - if (CallStats.isBackendInitialized()) { - return; - } - - if (!CallStats.initBackend({ - callStatsID: options.callStatsID, - callStatsSecret: options.callStatsSecret, - userName: options.userName, - aliasName: options.aliasName, - applicationName: options.applicationName, - confID: options.confID, - siteID: options.siteID, - configParams: options.configParams - })) { - logger.error('CallStats Backend initialization failed bad'); - } -} - -/** - * callstats strips any additional fields from Error except for "name", "stack", - * "message" and "constraintName". So we need to bundle additional information - * from JitsiTrackError into error passed to callstats to preserve valuable - * information about error. - * @param {JitsiTrackError} error - */ -function formatJitsiTrackErrorForCallStats(error) { - const err = new Error(); - - // Just copy original stack from error - err.stack = error.stack; - - // Combine name from error's name plus (possibly) name of original GUM error - err.name = (error.name || 'Unknown error') + (error.gum && error.gum.error - && error.gum.error.name ? ` - ${error.gum.error.name}` : ''); - - // Put all constraints into this field. For constraint failed errors we will - // still know which exactly constraint failed as it will be a part of - // message. - err.constraintName = error.gum && error.gum.constraints - ? JSON.stringify(error.gum.constraints) : ''; - - // Just copy error's message. - err.message = error.message; - - return err; -} - /** * Init statistic options * @param options @@ -141,20 +54,8 @@ Statistics.init = function(options) { /** * The options to configure Statistics. * @typedef {Object} StatisticsOptions - * @property {string} applicationName - The application name to pass to - * callstats. - * @property {string} aliasName - The alias name to use when initializing callstats. - * @property {string} userName - The user name to use when initializing callstats. - * @property {string} confID - The callstats conference ID to use. - * @property {string} callStatsID - Callstats credentials - the id. - * @property {string} callStatsSecret - Callstats credentials - the secret. - * @property {string} customScriptUrl - A custom lib url to use when downloading - * callstats library. + * @property {string} userName - The user name to use * @property {string} roomName - The room name we are currently in. - * @property {string} configParams - The set of parameters - * to enable/disable certain features in the library. See CallStats docs for more info. - */ -/** * * @param {JitsiConference} conference - The conference instance from which the statistics were initialized. * @param {StatisticsOptions} options - The options to use creating the @@ -172,35 +73,6 @@ export default function Statistics(conference, options) { this.xmpp = conference?.xmpp; this.options = options || {}; - this.callStatsIntegrationEnabled - = this.options.callStatsID && this.options.callStatsSecret - - // Even though AppID and AppSecret may be specified, the integration - // of callstats.io may be disabled because of globally-disallowed - // requests to any third parties. - && (Statistics.disableThirdPartyRequests !== true); - if (this.callStatsIntegrationEnabled) { - this.callStatsApplicationLogsDisabled - = this.options.callStatsApplicationLogsDisabled; - if (browser.isReactNative()) { - _initCallStatsBackend(this.options); - } else { - loadCallStatsAPI(this.options); - } - - if (!this.options.confID) { - logger.warn('"confID" is not defined'); - } - } - - /** - * Stores {@link CallStats} instances for each - * {@link TraceablePeerConnection} (one {@link CallStats} instance serves - * one TPC). The instances are mapped by {@link TraceablePeerConnection.id}. - * @type {Map} - */ - this.callsStatsInstances = new Map(); - Statistics.instances.add(this); RTCStats.start(this.conference); @@ -419,19 +291,8 @@ Statistics.prototype.setSpeakerList = function(speakerList) { Statistics.prototype.dispose = function() { try { - // NOTE Before reading this please see the comment in stopCallStats... - // - // Here we prevent from emitting the event twice in case it will be - // triggered from stopCallStats. - // If the event is triggered from here it means that the logs will not - // be submitted anyway (because there is no CallStats instance), but - // we're doing that for the sake of some kind of consistency. - if (!this.callsStatsInstances.size) { - this.eventEmitter.emit(StatisticsEvents.BEFORE_DISPOSED); - } - for (const callStats of this.callsStatsInstances.values()) { - this.stopCallStats(callStats.tpc); - } + this.eventEmitter.emit(StatisticsEvents.BEFORE_DISPOSED); + for (const tpcId of this.rtpStatsMap.keys()) { this._stopRemoteStats(tpcId); } @@ -482,311 +343,12 @@ Statistics.prototype.stopRemoteStats = function(tpc) { this._stopRemoteStats(tpc.id); }; -// CALSTATS METHODS - -/** - * Obtains the list of *all* {@link CallStats} instances collected from every - * valid {@link Statistics} instance. - * @return {Set} - * @private - */ -Statistics._getAllCallStatsInstances = function() { - const csInstances = new Set(); - - for (const statistics of Statistics.instances) { - for (const cs of statistics.callsStatsInstances.values()) { - csInstances.add(cs); - } - } - - return csInstances; -}; - -/** - * Removes the callstats.io instances. - */ -Statistics.prototype.stopCallStats = function(tpc) { - const callStatsInstance = this.callsStatsInstances.get(tpc.id); - - if (callStatsInstance) { - // FIXME the original purpose of adding BEFORE_DISPOSED event was to be - // able to submit the last log batch from jitsi-meet to CallStats. After - // recent changes we dispose the CallStats earlier - // (before Statistics.dispose), so we need to emit this event here to - // give this last chance for final log batch submission. - // - // Eventually there should be a separate module called "log storage" - // which should emit proper events when it's underlying - // CallStats instance is going away. - if (this.callsStatsInstances.size === 1) { - this.eventEmitter.emit(StatisticsEvents.BEFORE_DISPOSED); - } - this.callsStatsInstances.delete(tpc.id); - - // The fabric needs to be terminated when being stopped - callStatsInstance.sendTerminateEvent(); - } -}; - -/** - * Returns true if the callstats integration is enabled, otherwise returns - * false. - * - * @returns true if the callstats integration is enabled, otherwise returns - * false. - */ -Statistics.prototype.isCallstatsEnabled = function() { - return this.callStatsIntegrationEnabled; -}; - -/** - * Logs either resume or hold event for the given peer connection. - * @param {TraceablePeerConnection} tpc the connection for which event will be - * reported - * @param {boolean} isResume true for resume or false for hold - */ -Statistics.prototype.sendConnectionResumeOrHoldEvent = function(tpc, isResume) { - const instance = this.callsStatsInstances.get(tpc.id); - - if (instance) { - instance.sendResumeOrHoldEvent(isResume); - } -}; - -/** - * Notifies CallStats and analytics (if present) for ice connection failed - * @param {TraceablePeerConnection} tpc connection on which failure occurred. - */ -Statistics.prototype.sendIceConnectionFailedEvent = function(tpc) { - const instance = this.callsStatsInstances.get(tpc.id); - - if (instance) { - instance.sendIceConnectionFailedEvent(); - } -}; - -/** - * Notifies CallStats for mute events - * @param {TraceablePeerConnection} tpc connection on which failure occurred. - * @param {boolean} muted true for muted and false for not muted - * @param {String} type "audio"/"video" - */ -Statistics.prototype.sendMuteEvent = function(tpc, muted, type) { - const instance = tpc && this.callsStatsInstances.get(tpc.id); - - CallStats.sendMuteEvent(muted, type, instance); -}; - -/** - * Notifies CallStats for screen sharing events - * @param start {boolean} true for starting screen sharing and - * false for not stopping - * @param {string|null} ssrc - optional ssrc value, used only when - * starting screen sharing. - */ -Statistics.prototype.sendScreenSharingEvent - = function(start, ssrc) { - for (const cs of this.callsStatsInstances.values()) { - cs.sendScreenSharingEvent(start, ssrc); - } - }; - -/** - * Notifies the statistics module that we are now the dominant speaker of the - * conference. - * @param {String} roomJid - The room jid where the speaker event occurred. - * @param {boolean} silence - Whether the dominant speaker is silent or not. - */ -Statistics.prototype.sendDominantSpeakerEvent = function(roomJid, silence) { - for (const cs of this.callsStatsInstances.values()) { - cs.sendDominantSpeakerEvent(); - } - - // xmpp send dominant speaker event - this.xmpp.sendDominantSpeakerEvent(roomJid, silence); -}; - -/** - * Notifies about active device. - * @param {{deviceList: {String:String}}} devicesData - list of devices with - * their data - */ -Statistics.sendActiveDeviceListEvent = function(devicesData) { - const globalSet = Statistics._getAllCallStatsInstances(); - - if (globalSet.size) { - for (const cs of globalSet) { - CallStats.sendActiveDeviceListEvent(devicesData, cs); - } - } else { - CallStats.sendActiveDeviceListEvent(devicesData, null); - } -}; - -/* eslint-disable max-params */ - /** - * Lets the underlying statistics module know where is given SSRC rendered by - * providing renderer tag ID. - * @param {TraceablePeerConnection} tpc the connection to which the stream - * belongs to - * @param {number} ssrc the SSRC of the stream - * @param {boolean} isLocal - * @param {string} userId - * @param {string} usageLabel meaningful usage label of this stream like - * 'microphone', 'camera' or 'screen'. - * @param {string} containerId the id of media 'audio' or 'video' tag which - * renders the stream. - */ -Statistics.prototype.associateStreamWithVideoTag = function( - tpc, - ssrc, - isLocal, - userId, - usageLabel, - containerId) { - const instance = this.callsStatsInstances.get(tpc.id); - - if (instance) { - instance.associateStreamWithVideoTag( - ssrc, - isLocal, - userId, - usageLabel, - containerId); - } -}; - -/* eslint-enable max-params */ - -/** - * Notifies CallStats that getUserMedia failed. - * - * @param {Error} e error to send - */ -Statistics.sendGetUserMediaFailed = function(e) { - const error - = e instanceof JitsiTrackError - ? formatJitsiTrackErrorForCallStats(e) : e; - const globalSet = Statistics._getAllCallStatsInstances(); - - if (globalSet.size) { - for (const cs of globalSet) { - CallStats.sendGetUserMediaFailed(error, cs); - } - } else { - CallStats.sendGetUserMediaFailed(error, null); - } -}; - -/** - * Notifies CallStats that peer connection failed to create offer. - * - * @param {Error} e error to send - * @param {TraceablePeerConnection} tpc connection on which failure occurred. - */ -Statistics.prototype.sendCreateOfferFailed = function(e, tpc) { - const instance = this.callsStatsInstances.get(tpc.id); - - if (instance) { - instance.sendCreateOfferFailed(e); - } -}; - -/** - * Notifies CallStats that peer connection failed to create answer. - * - * @param {Error} e error to send - * @param {TraceablePeerConnection} tpc connection on which failure occured. - */ -Statistics.prototype.sendCreateAnswerFailed = function(e, tpc) { - const instance = this.callsStatsInstances.get(tpc.id); - - if (instance) { - instance.sendCreateAnswerFailed(e); - } -}; - -/** - * Notifies CallStats that peer connection failed to set local description. - * - * @param {Error} e error to send - * @param {TraceablePeerConnection} tpc connection on which failure occurred. - */ -Statistics.prototype.sendSetLocalDescFailed = function(e, tpc) { - const instance = this.callsStatsInstances.get(tpc.id); - - if (instance) { - instance.sendSetLocalDescFailed(e); - } -}; - -/** - * Notifies CallStats that peer connection failed to set remote description. - * - * @param {Error} e error to send - * @param {TraceablePeerConnection} tpc connection on which failure occurred. - */ -Statistics.prototype.sendSetRemoteDescFailed = function(e, tpc) { - const instance = this.callsStatsInstances.get(tpc.id); - - if (instance) { - instance.sendSetRemoteDescFailed(e); - } -}; - -/** - * Notifies CallStats that peer connection failed to add ICE candidate. - * - * @param {Error} e error to send - * @param {TraceablePeerConnection} tpc connection on which failure occurred. - */ -Statistics.prototype.sendAddIceCandidateFailed = function(e, tpc) { - const instance = this.callsStatsInstances.get(tpc.id); - - if (instance) { - instance.sendAddIceCandidateFailed(e); - } -}; - -/** - * Adds to CallStats an application log. - * - * @param {String} m a log message to send or an {Error} object to be reported - */ -Statistics.sendLog = function(m) { - const globalSubSet = new Set(); - - // FIXME we don't want to duplicate logs over P2P instance, but - // here we should go over instances and call this method for each - // unique conference ID rather than selecting the first one. - // We don't have such use case though, so leaving as is for now. - for (const stats of Statistics.instances) { - if (stats.callStatsApplicationLogsDisabled) { - return; - } - - if (stats.callsStatsInstances.size) { - globalSubSet.add(stats.callsStatsInstances.values().next().value); - } - } - - if (globalSubSet.size) { - for (const csPerStats of globalSubSet) { - CallStats.sendApplicationLog(m, csPerStats); - } - } else { - CallStats.sendApplicationLog(m, null); - } -}; - -/** - * Sends the given feedback through CallStats. + * Sends the given feedback * * @param overall an integer between 1 and 5 indicating the user's rating. * @param comment the comment from the user. - * @returns {Promise} Resolves when callstats feedback has been submitted - * successfully. + * @returns {Promise} Resolves immediately. */ Statistics.prototype.sendFeedback = function(overall, comment) { // Statistics.analytics.sendEvent is currently fire and forget, without @@ -798,31 +360,13 @@ Statistics.prototype.sendFeedback = function(overall, comment) { comment }); - if (this.isCallstatsEnabled()) { - return CallStats.sendFeedback(this.options.confID, overall, comment); - } - return Promise.resolve(); }; Statistics.LOCAL_JID = require('../../service/statistics/constants').LOCAL_JID; /** - * Reports global error to CallStats. - * - * @param {Error} error - */ -Statistics.reportGlobalError = function(error) { - if (error instanceof JitsiTrackError && error.gum) { - Statistics.sendGetUserMediaFailed(error); - } else { - Statistics.sendLog(error); - } -}; - -/** - * Sends event to analytics and logs a message to the logger/console. Console - * messages might also be logged to callstats automatically. + * Sends event to analytics and logs a message to the logger/console. * * @param {string | Object} event the event name, or an object which * represents the entire event. diff --git a/modules/version/ComponentsVersions.js b/modules/version/ComponentsVersions.js index 93d07c0caf..9be37abcf7 100644 --- a/modules/version/ComponentsVersions.js +++ b/modules/version/ComponentsVersions.js @@ -29,8 +29,6 @@ ComponentsVersions.prototype.processVersions return; } - const log = []; - versions.children.forEach(component => { const name = component.attributes.name; @@ -39,19 +37,8 @@ ComponentsVersions.prototype.processVersions if (this.versions[name] !== version) { this.versions[name] = version; logger.info(`Got ${name} version: ${version}`); - - log.push({ - id: 'component_version', - component: name, - version - }); } }); - - // logs versions to stats - if (log.length > 0) { - Statistics.sendLog(JSON.stringify(log)); - } }; /** diff --git a/modules/xmpp/xmpp.js b/modules/xmpp/xmpp.js index 835592d119..ac788e0256 100644 --- a/modules/xmpp/xmpp.js +++ b/modules/xmpp/xmpp.js @@ -1125,7 +1125,6 @@ export default class XMPP extends Listenable { logObject.id = 'deployment_info'; const entry = JSON.stringify(logObject); - Statistics.sendLog(entry); logger.info(entry); } diff --git a/service/statistics/Events.ts b/service/statistics/Events.ts index 312ae0cd8b..f23f1137cd 100644 --- a/service/statistics/Events.ts +++ b/service/statistics/Events.ts @@ -13,8 +13,7 @@ export enum Events { /** * An event fired just before the statistics module gets disposes and it's - * the last chance to submit some logs that will end up in stats services like - * CallStats (if enabled). + * the last chance to submit logs. */ BEFORE_DISPOSED = 'statistics.before_disposed', From e1002bb56d9d7e1d52b38c34cd79b2269f9a5aa8 Mon Sep 17 00:00:00 2001 From: Boris Grozev Date: Mon, 20 Nov 2023 12:41:26 -0600 Subject: [PATCH 4/6] squash: Fix lint errors. --- JitsiConference.js | 5 +++-- JitsiConferenceEventManager.js | 1 - JitsiMediaDevices.js | 1 - modules/statistics/AnalyticsAdapter.js | 1 - modules/statistics/statistics.js | 4 +--- modules/version/ComponentsVersions.js | 2 -- 6 files changed, 4 insertions(+), 10 deletions(-) diff --git a/JitsiConference.js b/JitsiConference.js index b68443bf0e..15cc33aa77 100644 --- a/JitsiConference.js +++ b/JitsiConference.js @@ -473,7 +473,7 @@ JitsiConference.prototype._init = function(options = {}) { confID: config.confID || `${this.connection.options.hosts.domain}/${this.options.name}`, siteID: config.siteID, roomName: this.options.name, - applicationName: config.applicationName, + applicationName: config.applicationName }); Statistics.analytics.addPermanentProperties({ 'callstats_name': this._statsCurrentId @@ -2671,7 +2671,7 @@ JitsiConference.prototype.sendFeedback = function(overallFeedback, detailedFeedb }; /** - * @returns false, since callstats in not supported anymore. + * @returns false, since callstats in not supported anymore. */ JitsiConference.prototype.isCallstatsEnabled = function() { return false; @@ -2690,6 +2690,7 @@ JitsiConference.prototype.getSsrcByTrack = function(track) { /** * This is a no-op since callstats is no longer supported. */ +// eslint-disable-next-line no-empty-function JitsiConference.prototype.sendApplicationLog = function() { }; /** diff --git a/JitsiConferenceEventManager.js b/JitsiConferenceEventManager.js index 2057f17531..144e3cc1bb 100644 --- a/JitsiConferenceEventManager.js +++ b/JitsiConferenceEventManager.js @@ -9,7 +9,6 @@ import Statistics from './modules/statistics/statistics'; import EventEmitterForwarder from './modules/util/EventEmitterForwarder'; import { MediaType } from './service/RTC/MediaType'; import RTCEvents from './service/RTC/RTCEvents'; -import { VideoType } from './service/RTC/VideoType'; import AuthenticationEvents from './service/authentication/AuthenticationEvents'; import { diff --git a/JitsiMediaDevices.js b/JitsiMediaDevices.js index adcce4d682..577d68c15c 100644 --- a/JitsiMediaDevices.js +++ b/JitsiMediaDevices.js @@ -3,7 +3,6 @@ import EventEmitter from 'events'; import * as JitsiMediaDevicesEvents from './JitsiMediaDevicesEvents'; import RTC from './modules/RTC/RTC'; import browser from './modules/browser'; -import Statistics from './modules/statistics/statistics'; import { MediaType } from './service/RTC/MediaType'; import RTCEvents from './service/RTC/RTCEvents'; diff --git a/modules/statistics/AnalyticsAdapter.js b/modules/statistics/AnalyticsAdapter.js index 54c2e0dbb1..61271c2fb2 100644 --- a/modules/statistics/AnalyticsAdapter.js +++ b/modules/statistics/AnalyticsAdapter.js @@ -10,7 +10,6 @@ import browser from '../browser'; const MAX_CACHE_SIZE = 100; -// eslist-disable-line no-undef const logger = getLogger(__filename); /** diff --git a/modules/statistics/statistics.js b/modules/statistics/statistics.js index 6329601a92..12c5be5ec5 100644 --- a/modules/statistics/statistics.js +++ b/modules/statistics/statistics.js @@ -1,13 +1,11 @@ import EventEmitter from 'events'; import * as JitsiConferenceEvents from '../../JitsiConferenceEvents'; -import JitsiTrackError from '../../JitsiTrackError'; import { JitsiTrackEvents } from '../../JitsiTrackEvents'; import { FEEDBACK } from '../../service/statistics/AnalyticsEvents'; import * as StatisticsEvents from '../../service/statistics/Events'; import RTCStats from '../RTCStats/RTCStats'; import browser from '../browser'; -import ScriptUtil from '../util/ScriptUtil'; import WatchRTC from '../watchRTC/WatchRTC'; import analytics from './AnalyticsAdapter'; @@ -366,7 +364,7 @@ Statistics.prototype.sendFeedback = function(overall, comment) { Statistics.LOCAL_JID = require('../../service/statistics/constants').LOCAL_JID; /** - * Sends event to analytics and logs a message to the logger/console. + * Sends event to analytics and logs a message to the logger/console. * * @param {string | Object} event the event name, or an object which * represents the entire event. diff --git a/modules/version/ComponentsVersions.js b/modules/version/ComponentsVersions.js index 9be37abcf7..f24c1961da 100644 --- a/modules/version/ComponentsVersions.js +++ b/modules/version/ComponentsVersions.js @@ -1,5 +1,3 @@ -import Statistics from '../statistics/statistics'; - const logger = require('@jitsi/logger').getLogger(__filename); /** From 3c5504818c50d3f7b6536fe4ea6e1d8b4016f1e3 Mon Sep 17 00:00:00 2001 From: Boris Grozev Date: Tue, 21 Nov 2023 14:14:08 -0600 Subject: [PATCH 5/6] squash: Add a log message and a @deprecated annotation --- JitsiConference.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/JitsiConference.js b/JitsiConference.js index 15cc33aa77..32ca8fb48b 100644 --- a/JitsiConference.js +++ b/JitsiConference.js @@ -2672,8 +2672,10 @@ JitsiConference.prototype.sendFeedback = function(overallFeedback, detailedFeedb /** * @returns false, since callstats in not supported anymore. + * @deprecated */ JitsiConference.prototype.isCallstatsEnabled = function() { + logger.warn('Callstats is no longer supported'); return false; }; From 43ff151512611352c56442a53642625491c063d7 Mon Sep 17 00:00:00 2001 From: Boris Grozev Date: Tue, 21 Nov 2023 14:38:44 -0600 Subject: [PATCH 6/6] squash: Fix lint error. --- JitsiConference.js | 1 + 1 file changed, 1 insertion(+) diff --git a/JitsiConference.js b/JitsiConference.js index 32ca8fb48b..c0259818b4 100644 --- a/JitsiConference.js +++ b/JitsiConference.js @@ -2676,6 +2676,7 @@ JitsiConference.prototype.sendFeedback = function(overallFeedback, detailedFeedb */ JitsiConference.prototype.isCallstatsEnabled = function() { logger.warn('Callstats is no longer supported'); + return false; };