Define global logger instance to be used for all logging
Summary: The advantage of this is that anyone can now log without needing to carry around a Logger object. Primary reason is for making metrics less intrusive in the codebase. Reviewed By: passy Differential Revision: D13671368 fbshipit-source-id: 162ab1351a124683aef13983fc3bcec01385cd1a
This commit is contained in:
committed by
Facebook Github Bot
parent
e71804fe9e
commit
3bcb079f87
@@ -10,14 +10,14 @@ import {Provider} from 'react-redux';
|
|||||||
import renderer from 'react-test-renderer';
|
import renderer from 'react-test-renderer';
|
||||||
import reducers from '../reducers/index.js';
|
import reducers from '../reducers/index.js';
|
||||||
import configureStore from 'redux-mock-store';
|
import configureStore from 'redux-mock-store';
|
||||||
import Logger from '../fb-stubs/Logger.js';
|
import {init as initLogger} from '../fb-stubs/Logger';
|
||||||
import BugReporter from '../fb-stubs/BugReporter.js';
|
import BugReporter from '../fb-stubs/BugReporter.js';
|
||||||
|
|
||||||
// create redux store with initial state
|
// create redux store with initial state
|
||||||
const mockStore = configureStore([])(reducers(undefined, {type: 'INIT'}));
|
const mockStore = configureStore([])(reducers(undefined, {type: 'INIT'}));
|
||||||
|
|
||||||
test('Empty app state matches snapshot', () => {
|
test('Empty app state matches snapshot', () => {
|
||||||
const logger = new Logger();
|
const logger = initLogger();
|
||||||
const bugReporter = new BugReporter(logger, mockStore);
|
const bugReporter = new BugReporter(logger, mockStore);
|
||||||
|
|
||||||
const component = renderer.create(
|
const component = renderer.create(
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import Server, {SECURE_PORT, INSECURE_PORT} from '../server.js';
|
import Server, {SECURE_PORT, INSECURE_PORT} from '../server.js';
|
||||||
import LogManager from '../fb-stubs/Logger';
|
import {init as initLogger} from '../fb-stubs/Logger';
|
||||||
import reducers from '../reducers/index.js';
|
import reducers from '../reducers/index.js';
|
||||||
import configureStore from 'redux-mock-store';
|
import configureStore from 'redux-mock-store';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
@@ -23,7 +23,8 @@ beforeAll(() => {
|
|||||||
fs.mkdirSync(flipperDir);
|
fs.mkdirSync(flipperDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
server = new Server(new LogManager(), mockStore);
|
const logger = initLogger();
|
||||||
|
server = new Server(logger, mockStore);
|
||||||
return server.init();
|
return server.init();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -81,11 +81,7 @@ export default (store: Store, logger: Logger) => {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
const clientPromise = recordSuccessMetric(
|
const clientPromise = recordSuccessMetric(createClient(), 'createADBClient');
|
||||||
createClient(),
|
|
||||||
'createADBClient',
|
|
||||||
logger,
|
|
||||||
);
|
|
||||||
|
|
||||||
const watchAndroidDevices = () => {
|
const watchAndroidDevices = () => {
|
||||||
// get emulators
|
// get emulators
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
* @format
|
* @format
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import LogManager from './Logger';
|
import type LogManager from './Logger';
|
||||||
|
|
||||||
import type {Store} from '../reducers/index.js';
|
import type {Store} from '../reducers/index.js';
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ export type LogTypes = 'error' | 'warn' | 'info' | 'debug';
|
|||||||
export type TrackType = 'duration' | 'usage' | 'performance' | 'success-rate';
|
export type TrackType = 'duration' | 'usage' | 'performance' | 'success-rate';
|
||||||
import ScribeLogger from './ScribeLogger';
|
import ScribeLogger from './ScribeLogger';
|
||||||
|
|
||||||
|
var instance: ?LogManager = null;
|
||||||
|
|
||||||
export default class LogManager {
|
export default class LogManager {
|
||||||
constructor(store: ?Store) {
|
constructor(store: ?Store) {
|
||||||
this.scribeLogger = new ScribeLogger(this);
|
this.scribeLogger = new ScribeLogger(this);
|
||||||
@@ -28,3 +30,20 @@ export default class LogManager {
|
|||||||
|
|
||||||
debug(data: any, category: string) {}
|
debug(data: any, category: string) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function init(store: Store): LogManager {
|
||||||
|
if (instance) {
|
||||||
|
throw new Error('Attempted to initialize Logger when already initialized');
|
||||||
|
}
|
||||||
|
instance = new LogManager(store);
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getInstance(): LogManager {
|
||||||
|
if (!instance) {
|
||||||
|
throw new Error(
|
||||||
|
'Requested Logger instance without initializing it. Make sure init() is called at app start',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import ReactDOM from 'react-dom';
|
|||||||
import {ContextMenuProvider} from 'flipper';
|
import {ContextMenuProvider} from 'flipper';
|
||||||
import {precachedIcons} from './utils/icons.js';
|
import {precachedIcons} from './utils/icons.js';
|
||||||
import GK from './fb-stubs/GK.js';
|
import GK from './fb-stubs/GK.js';
|
||||||
import Logger from './fb-stubs/Logger.js';
|
import {init as initLogger} from './fb-stubs/Logger';
|
||||||
import App from './App.js';
|
import App from './App.js';
|
||||||
import BugReporter from './fb-stubs/BugReporter.js';
|
import BugReporter from './fb-stubs/BugReporter.js';
|
||||||
import {createStore} from 'redux';
|
import {createStore} from 'redux';
|
||||||
@@ -26,7 +26,7 @@ const store = createStore(
|
|||||||
);
|
);
|
||||||
persistStore(store);
|
persistStore(store);
|
||||||
|
|
||||||
const logger = new Logger(store);
|
const logger = initLogger(store);
|
||||||
const bugReporter = new BugReporter(logger, store);
|
const bugReporter = new BugReporter(logger, store);
|
||||||
dispatcher(store, logger);
|
dispatcher(store, logger);
|
||||||
GK.init();
|
GK.init();
|
||||||
|
|||||||
@@ -185,7 +185,6 @@ export default class Server extends EventEmitter {
|
|||||||
destination,
|
destination,
|
||||||
),
|
),
|
||||||
'processCertificateSigningRequest',
|
'processCertificateSigningRequest',
|
||||||
this.logger,
|
|
||||||
)
|
)
|
||||||
.then(result => {
|
.then(result => {
|
||||||
subscriber.onComplete({
|
subscriber.onComplete({
|
||||||
|
|||||||
@@ -1,58 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright 2018-present Facebook.
|
|
||||||
* This source code is licensed under the MIT license found in the
|
|
||||||
* LICENSE file in the root directory of this source tree.
|
|
||||||
* @format
|
|
||||||
*/
|
|
||||||
import {recordSuccessMetric} from '../metrics';
|
|
||||||
import type Logger from '../../fb-stubs/Logger';
|
|
||||||
|
|
||||||
//$FlowFixMe pretend logger is the right type
|
|
||||||
const logger: Logger = {
|
|
||||||
track: jest.fn(),
|
|
||||||
};
|
|
||||||
|
|
||||||
beforeAll(() => {
|
|
||||||
logger.track.mockClear();
|
|
||||||
});
|
|
||||||
|
|
||||||
test('Wrapping a successful promise preserves result and logs correctly', () => {
|
|
||||||
const successPromise = Promise.resolve('Yay!');
|
|
||||||
const wrappedPromise = recordSuccessMetric(
|
|
||||||
successPromise,
|
|
||||||
'test metric',
|
|
||||||
logger,
|
|
||||||
);
|
|
||||||
return wrappedPromise
|
|
||||||
.then(wrappedValue => {
|
|
||||||
expect(wrappedValue).toBe('Yay!');
|
|
||||||
})
|
|
||||||
.then(() => {
|
|
||||||
expect(logger.track).toHaveBeenCalledWith(
|
|
||||||
'success-rate',
|
|
||||||
'test metric',
|
|
||||||
1,
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
test('Wrapping a rejected promise preserves result and logs correctly', () => {
|
|
||||||
const successPromise = Promise.reject('Oh no!');
|
|
||||||
const wrappedPromise = recordSuccessMetric(
|
|
||||||
successPromise,
|
|
||||||
'test metric',
|
|
||||||
logger,
|
|
||||||
);
|
|
||||||
expect.assertions(2); // Make sure to fail if catch block isn't visited
|
|
||||||
return wrappedPromise
|
|
||||||
.catch(wrappedValue => {
|
|
||||||
expect(wrappedValue).toBe('Oh no!');
|
|
||||||
})
|
|
||||||
.then(() => {
|
|
||||||
expect(logger.track).toHaveBeenCalledWith(
|
|
||||||
'success-rate',
|
|
||||||
'test metric',
|
|
||||||
0,
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
* @format
|
* @format
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type Logger from '../fb-stubs/Logger';
|
import {getInstance} from '../fb-stubs/Logger';
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Wraps a Promise, preserving it's functionality but logging the success or
|
* Wraps a Promise, preserving it's functionality but logging the success or
|
||||||
@@ -15,15 +15,14 @@ import type Logger from '../fb-stubs/Logger';
|
|||||||
export function recordSuccessMetric(
|
export function recordSuccessMetric(
|
||||||
promise: Promise<*>,
|
promise: Promise<*>,
|
||||||
name: string,
|
name: string,
|
||||||
logger: Logger,
|
|
||||||
): Promise<*> {
|
): Promise<*> {
|
||||||
return promise.then(
|
return promise.then(
|
||||||
fulfilledValue => {
|
fulfilledValue => {
|
||||||
logger.track('success-rate', name, 1);
|
getInstance().track('success-rate', name, 1);
|
||||||
return fulfilledValue;
|
return fulfilledValue;
|
||||||
},
|
},
|
||||||
rejectionReason => {
|
rejectionReason => {
|
||||||
logger.track('success-rate', name, 0);
|
getInstance().track('success-rate', name, 0);
|
||||||
return Promise.reject(rejectionReason);
|
return Promise.reject(rejectionReason);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user