Просмотр исходного кода

feat(RN): enable log collector on mobile

Stores the Logger.LogCollector instance in base/logging state instead of
global APP variable and enables it on mobile.
master
paweldomas 7 лет назад
Родитель
Сommit
2305effa5c

+ 0
- 28
conference.js Просмотреть файл

2234
      * @returns {void}
2234
      * @returns {void}
2235
      */
2235
      */
2236
     _onConferenceJoined() {
2236
     _onConferenceJoined() {
2237
-        if (APP.logCollector) {
2238
-            // Start the LogCollector's periodic "store logs" task
2239
-            APP.logCollector.start();
2240
-            APP.logCollectorStarted = true;
2241
-
2242
-            // Make an attempt to flush in case a lot of logs have been
2243
-            // cached, before the collector was started.
2244
-            APP.logCollector.flush();
2245
-
2246
-            // This event listener will flush the logs, before
2247
-            // the statistics module (CallStats) is stopped.
2248
-            //
2249
-            // NOTE The LogCollector is not stopped, because this event can
2250
-            // be triggered multiple times during single conference
2251
-            // (whenever statistics module is stopped). That includes
2252
-            // the case when Jicofo terminates the single person left in the
2253
-            // room. It will then restart the media session when someone
2254
-            // eventually join the room which will start the stats again.
2255
-            APP.conference.addConferenceListener(
2256
-                JitsiConferenceEvents.BEFORE_STATISTICS_DISPOSED,
2257
-                () => {
2258
-                    if (APP.logCollector) {
2259
-                        APP.logCollector.flush();
2260
-                    }
2261
-                }
2262
-            );
2263
-        }
2264
-
2265
         APP.UI.initConference();
2237
         APP.UI.initConference();
2266
 
2238
 
2267
         APP.keyboardshortcut.init();
2239
         APP.keyboardshortcut.init();

+ 2
- 0
modules/util/JitsiMeetInMemoryLogStorage.js Просмотреть файл

1
 /**
1
 /**
2
  * Implements in memory logs storage, used for testing/debugging.
2
  * Implements in memory logs storage, used for testing/debugging.
3
+ *
4
+ * FIXME: move to base/logging
3
  */
5
  */
4
 export default class JitsiMeetInMemoryLogStorage {
6
 export default class JitsiMeetInMemoryLogStorage {
5
 
7
 

+ 26
- 6
modules/util/JitsiMeetLogStorage.js Просмотреть файл

1
-/* global APP */
1
+import { getCurrentConference } from '../../react/features/base/conference';
2
 
2
 
3
 /**
3
 /**
4
  * Implements logs storage through the CallStats.
4
  * Implements logs storage through the CallStats.
5
+ *
6
+ * FIXME: move to base/logging
5
  */
7
  */
6
 export default class JitsiMeetLogStorage {
8
 export default class JitsiMeetLogStorage {
7
 
9
 
8
     /**
10
     /**
9
-     * Creates new <tt>JitsiMeetLogStorage</tt>
11
+     * Creates new <tt>JitsiMeetLogStorage</tt>.
12
+     *
13
+     * @param {Function} getState - the Redux store's {@code getState} method.
10
      */
14
      */
11
-    constructor() {
15
+    constructor(getState) {
12
         /**
16
         /**
13
          * Counts each log entry, increases on every batch log entry stored.
17
          * Counts each log entry, increases on every batch log entry stored.
14
          * @type {number}
18
          * @type {number}
15
          */
19
          */
16
         this.counter = 1;
20
         this.counter = 1;
21
+
22
+        /**
23
+         * The Redux store's {@code getState} method.
24
+         *
25
+         * @type {Function}
26
+         */
27
+        this.getState = getState;
17
     }
28
     }
18
 
29
 
19
     /**
30
     /**
31
+     * The JitsiMeetLogStorage is ready when the CallStats are started and
32
+     * before refactoring the code it was after the conference has been joined.
33
+     * A conference is considered joined when the 'conference' field is defined
34
+     * in the base/conference state.
35
+     *
20
      * @return {boolean} <tt>true</tt> when this storage is ready or
36
      * @return {boolean} <tt>true</tt> when this storage is ready or
21
      * <tt>false</tt> otherwise.
37
      * <tt>false</tt> otherwise.
22
      */
38
      */
23
     isReady() {
39
     isReady() {
24
-        return Boolean(APP.logCollectorStarted && APP.conference);
40
+        const { conference } = this.getState()['features/base/conference'];
41
+
42
+        return Boolean(conference);
25
     }
43
     }
26
 
44
 
27
     /**
45
     /**
31
      * representing log lines or aggregated lines objects.
49
      * representing log lines or aggregated lines objects.
32
      */
50
      */
33
     storeLogs(logEntries) {
51
     storeLogs(logEntries) {
52
+        const conference = getCurrentConference(this.getState());
34
 
53
 
35
-        if (!APP.conference.isCallstatsEnabled()) {
54
+        if (!conference || !conference.isCallstatsEnabled()) {
36
             // Discard the logs if CallStats is not enabled.
55
             // Discard the logs if CallStats is not enabled.
37
             return;
56
             return;
38
         }
57
         }
58
         // on the way that could be uninitialized if the storeLogs
77
         // on the way that could be uninitialized if the storeLogs
59
         // attempt would be made very early (which is unlikely)
78
         // attempt would be made very early (which is unlikely)
60
         try {
79
         try {
61
-            APP.conference._room.sendApplicationLog(logMessage);
80
+            conference.sendApplicationLog(logMessage);
62
         } catch (error) {
81
         } catch (error) {
82
+            // FIXME whole objects logged
63
             // NOTE console is intentional here
83
             // NOTE console is intentional here
64
             console.error(
84
             console.error(
65
                 'Failed to store the logs: ', logMessage, error);
85
                 'Failed to store the logs: ', logMessage, error);

+ 11
- 0
react/features/base/logging/actionTypes.js Просмотреть файл

1
+/**
2
+ * The type of redux action which stores the log collector that will be
3
+ * submitting the logs to CallStats.
4
+ *
5
+ * {
6
+ *     type: SET_LOG_COLLECTOR,
7
+ *     logCollector: Logger.LogCollector
8
+ * }
9
+ */
10
+export const SET_LOG_COLLECTOR = Symbol('SET_LOG_COLLECTOR');
11
+
1
 /**
12
 /**
2
  * The type of redux action which sets the configuration of the feature
13
  * The type of redux action which sets the configuration of the feature
3
  * base/logging.
14
  * base/logging.

+ 19
- 1
react/features/base/logging/actions.js Просмотреть файл

1
 /* @flow */
1
 /* @flow */
2
 
2
 
3
-import { SET_LOGGING_CONFIG } from './actionTypes';
3
+import { SET_LOG_COLLECTOR, SET_LOGGING_CONFIG } from './actionTypes';
4
+
5
+/**
6
+ * Stores a {@code Logger.LogCollector} instance which will be uploading logs
7
+ * to CallStats.
8
+ *
9
+ * @param {Logger.LogCollector} logCollector - The log collector instance to be
10
+ * stored in the Redux state of base/logging feature.
11
+ * @returns {{
12
+ *     type,
13
+ *     logCollector: Object
14
+ * }}
15
+ */
16
+export function setLogCollector(logCollector: ?Object) {
17
+    return {
18
+        type: SET_LOG_COLLECTOR,
19
+        logCollector
20
+    };
21
+}
4
 
22
 
5
 /**
23
 /**
6
  * Sets the configuration of the feature base/logging.
24
  * Sets the configuration of the feature base/logging.

+ 83
- 12
react/features/base/logging/middleware.js Просмотреть файл

3
 import Logger from 'jitsi-meet-logger';
3
 import Logger from 'jitsi-meet-logger';
4
 
4
 
5
 import { APP_WILL_MOUNT } from '../app';
5
 import { APP_WILL_MOUNT } from '../app';
6
-import JitsiMeetJS, { LIB_WILL_INIT } from '../lib-jitsi-meet';
6
+import { CONFERENCE_JOINED, getCurrentConference } from '../conference';
7
+import JitsiMeetJS, {
8
+    LIB_WILL_INIT,
9
+    JitsiConferenceEvents
10
+} from '../lib-jitsi-meet';
7
 import { MiddlewareRegistry } from '../redux';
11
 import { MiddlewareRegistry } from '../redux';
8
 
12
 
9
 import JitsiMeetInMemoryLogStorage
13
 import JitsiMeetInMemoryLogStorage
12
 
16
 
13
 import { isTestModeEnabled } from '../testing';
17
 import { isTestModeEnabled } from '../testing';
14
 
18
 
19
+import { setLogCollector } from './actions';
15
 import { SET_LOGGING_CONFIG } from './actionTypes';
20
 import { SET_LOGGING_CONFIG } from './actionTypes';
16
 
21
 
17
 declare var APP: Object;
22
 declare var APP: Object;
28
     case APP_WILL_MOUNT:
33
     case APP_WILL_MOUNT:
29
         return _appWillMount(store, next, action);
34
         return _appWillMount(store, next, action);
30
 
35
 
36
+    case CONFERENCE_JOINED:
37
+        return _conferenceJoined(store, next, action);
38
+
31
     case LIB_WILL_INIT:
39
     case LIB_WILL_INIT:
32
         return _libWillInit(store, next, action);
40
         return _libWillInit(store, next, action);
33
 
41
 
66
     return next(action);
74
     return next(action);
67
 }
75
 }
68
 
76
 
77
+/**
78
+ * Starts the log collector, after {@link CONFERENCE_JOINED} action is reduced.
79
+ *
80
+ * @param {Store} store - The Redux store in which the specified {@code action}
81
+ * is being dispatched.
82
+ * @param {Dispatch} next - The Redux {@code dispatch} function to dispatch the
83
+ * specified {@code action} to the specified {@code store}.
84
+ * @param {Action} action - The Redux action {@code CONFERENCE_JOINED} which is
85
+ * being dispatched in the specified {@code store}.
86
+ * @private
87
+ * @returns {*}
88
+ */
89
+function _conferenceJoined({ getState }, next, action) {
90
+
91
+    // Wait until the joined event is processed, so that the JitsiMeetLogStorage
92
+    // will be ready.
93
+    const result = next(action);
94
+
95
+    const { conference } = action;
96
+    const { logCollector } = getState()['features/base/logging'];
97
+
98
+    if (logCollector && conference === getCurrentConference(getState())) {
99
+        // Start the LogCollector's periodic "store logs" task
100
+        logCollector.start();
101
+
102
+        // Make an attempt to flush in case a lot of logs have been cached,
103
+        // before the collector was started.
104
+        logCollector.flush();
105
+
106
+        // This event listener will flush the logs, before the statistics module
107
+        // (CallStats) is stopped.
108
+        //
109
+        // NOTE The LogCollector is not stopped, because this event can be
110
+        // triggered multiple times during single conference (whenever
111
+        // statistics module is stopped). That includes the case when Jicofo
112
+        // terminates a single person conference (one person left in the room
113
+        // waiting for someone to join). It will then restart the media session
114
+        // when someone eventually joins the room which will start the stats
115
+        // again.
116
+        conference.on(
117
+            JitsiConferenceEvents.BEFORE_STATISTICS_DISPOSED,
118
+            () => logCollector.flush()
119
+        );
120
+    }
121
+
122
+    return result;
123
+}
124
+
69
 /**
125
 /**
70
  * Initializes logging in the app.
126
  * Initializes logging in the app.
71
  *
127
  *
128
+ * @param {Store} store - The Redux store in which context the logging is to be
129
+ * initialized.
72
  * @param {Object} loggingConfig - The configuration with which logging is to be
130
  * @param {Object} loggingConfig - The configuration with which logging is to be
73
  * initialized.
131
  * initialized.
74
  * @param {boolean} isTestingEnabled - Is debug logging enabled.
132
  * @param {boolean} isTestingEnabled - Is debug logging enabled.
75
  * @private
133
  * @private
76
  * @returns {void}
134
  * @returns {void}
77
  */
135
  */
78
-function _initLogging(loggingConfig, isTestingEnabled) {
136
+function _initLogging({ dispatch, getState }, loggingConfig, isTestingEnabled) {
137
+    const { logCollector } = getState()['features/base/logging'];
138
+
79
     // Create the LogCollector and register it as the global log transport. It
139
     // Create the LogCollector and register it as the global log transport. It
80
     // is done early to capture as much logs as possible. Captured logs will be
140
     // is done early to capture as much logs as possible. Captured logs will be
81
     // cached, before the JitsiMeetLogStorage gets ready (statistics module is
141
     // cached, before the JitsiMeetLogStorage gets ready (statistics module is
82
     // initialized).
142
     // initialized).
83
-    if (typeof APP === 'object'
84
-            && !APP.logCollector
85
-            && !loggingConfig.disableLogCollector) {
86
-        APP.logCollector = new Logger.LogCollector(new JitsiMeetLogStorage());
87
-        Logger.addGlobalTransport(APP.logCollector);
88
-        JitsiMeetJS.addGlobalLogTransport(APP.logCollector);
89
-
90
-        if (isTestingEnabled) {
143
+    if (!logCollector && !loggingConfig.disableLogCollector) {
144
+        const _logCollector
145
+            = new Logger.LogCollector(new JitsiMeetLogStorage(getState));
146
+
147
+        Logger.addGlobalTransport(_logCollector);
148
+        JitsiMeetJS.addGlobalLogTransport(_logCollector);
149
+        dispatch(setLogCollector(_logCollector));
150
+
151
+        // The JitsiMeetInMemoryLogStorage can not be accessed on mobile through
152
+        // the 'executeScript' method like it's done in torture tests for WEB.
153
+        if (isTestingEnabled && typeof APP === 'object') {
91
             APP.debugLogs = new JitsiMeetInMemoryLogStorage();
154
             APP.debugLogs = new JitsiMeetInMemoryLogStorage();
92
             const debugLogCollector = new Logger.LogCollector(
155
             const debugLogCollector = new Logger.LogCollector(
93
                 APP.debugLogs, { storeInterval: 1000 });
156
                 APP.debugLogs, { storeInterval: 1000 });
96
             JitsiMeetJS.addGlobalLogTransport(debugLogCollector);
159
             JitsiMeetJS.addGlobalLogTransport(debugLogCollector);
97
             debugLogCollector.start();
160
             debugLogCollector.start();
98
         }
161
         }
162
+    } else if (logCollector && loggingConfig.disableLogCollector) {
163
+        Logger.removeGlobalTransport(logCollector);
164
+        JitsiMeetJS.removeGlobalLogTransport(logCollector);
165
+        logCollector.stop();
166
+        dispatch(setLogCollector(undefined));
99
     }
167
     }
100
 }
168
 }
101
 
169
 
137
  * @returns {Object} The new state that is the result of the reduction of the
205
  * @returns {Object} The new state that is the result of the reduction of the
138
  * specified {@code action}.
206
  * specified {@code action}.
139
  */
207
  */
140
-function _setLoggingConfig({ getState }, next, action) {
208
+function _setLoggingConfig({ dispatch, getState }, next, action) {
141
     const result = next(action);
209
     const result = next(action);
142
     const newValue = getState()['features/base/logging'].config;
210
     const newValue = getState()['features/base/logging'].config;
143
     const isTestingEnabled = isTestModeEnabled(getState());
211
     const isTestingEnabled = isTestModeEnabled(getState());
151
     _setLogLevels(Logger, newValue);
219
     _setLogLevels(Logger, newValue);
152
     _setLogLevels(JitsiMeetJS, newValue);
220
     _setLogLevels(JitsiMeetJS, newValue);
153
 
221
 
154
-    _initLogging(newValue, isTestingEnabled);
222
+    _initLogging({
223
+        dispatch,
224
+        getState
225
+    }, newValue, isTestingEnabled);
155
 
226
 
156
     return result;
227
     return result;
157
 }
228
 }

+ 25
- 3
react/features/base/logging/reducer.js Просмотреть файл

1
 // @flow
1
 // @flow
2
 
2
 
3
-import { equals, ReducerRegistry } from '../redux';
3
+import { equals, ReducerRegistry, set } from '../redux';
4
 
4
 
5
-import { SET_LOGGING_CONFIG } from './actionTypes';
5
+import { SET_LOG_COLLECTOR, SET_LOGGING_CONFIG } from './actionTypes';
6
 
6
 
7
 /**
7
 /**
8
  * The default/initial redux state of the feature base/logging.
8
  * The default/initial redux state of the feature base/logging.
12
  * }}
12
  * }}
13
  */
13
  */
14
 const DEFAULT_STATE = {
14
 const DEFAULT_STATE = {
15
-    config: require('../../../../logging_config.js')
15
+    config: require('../../../../logging_config.js'),
16
+
17
+    /**
18
+     * The log collector.
19
+     */
20
+    logCollector: undefined
16
 };
21
 };
17
 
22
 
18
 ReducerRegistry.register(
23
 ReducerRegistry.register(
21
         switch (action.type) {
26
         switch (action.type) {
22
         case SET_LOGGING_CONFIG:
27
         case SET_LOGGING_CONFIG:
23
             return _setLoggingConfig(state, action);
28
             return _setLoggingConfig(state, action);
29
+        case SET_LOG_COLLECTOR: {
30
+            return _setLogCollector(state, action);
31
+        }
24
 
32
 
25
         default:
33
         default:
26
             return state;
34
             return state;
54
         config
62
         config
55
     };
63
     };
56
 }
64
 }
65
+
66
+/**
67
+ * Reduces a specific Redux action SET_LOG_COLLECTOR of the feature
68
+ * base/logging.
69
+ *
70
+ * @param {Object} state - The Redux state of the feature base/logging.
71
+ * @param {Action} action - The Redux action SET_LOG_COLLECTOR to reduce.
72
+ * @private
73
+ * @returns {Object} The new state of the feature base/logging after the
74
+ * reduction of the specified action.
75
+ */
76
+function _setLogCollector(state, action) {
77
+    return set(state, 'logCollector', action.logCollector);
78
+}

Загрузка…
Отмена
Сохранить