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:
John Knox
2019-01-15 09:39:37 -08:00
committed by Facebook Github Bot
parent e71804fe9e
commit 3bcb079f87
9 changed files with 31 additions and 75 deletions

View File

@@ -10,14 +10,14 @@ import {Provider} from 'react-redux';
import renderer from 'react-test-renderer';
import reducers from '../reducers/index.js';
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';
// create redux store with initial state
const mockStore = configureStore([])(reducers(undefined, {type: 'INIT'}));
test('Empty app state matches snapshot', () => {
const logger = new Logger();
const logger = initLogger();
const bugReporter = new BugReporter(logger, mockStore);
const component = renderer.create(

View File

@@ -6,7 +6,7 @@
*/
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 configureStore from 'redux-mock-store';
import path from 'path';
@@ -23,7 +23,8 @@ beforeAll(() => {
fs.mkdirSync(flipperDir);
}
server = new Server(new LogManager(), mockStore);
const logger = initLogger();
server = new Server(logger, mockStore);
return server.init();
});

View File

@@ -81,11 +81,7 @@ export default (store: Store, logger: Logger) => {
},
);
}
const clientPromise = recordSuccessMetric(
createClient(),
'createADBClient',
logger,
);
const clientPromise = recordSuccessMetric(createClient(), 'createADBClient');
const watchAndroidDevices = () => {
// get emulators

View File

@@ -5,7 +5,7 @@
* @format
*/
import LogManager from './Logger';
import type LogManager from './Logger';
import type {Store} from '../reducers/index.js';

View File

@@ -9,6 +9,8 @@ export type LogTypes = 'error' | 'warn' | 'info' | 'debug';
export type TrackType = 'duration' | 'usage' | 'performance' | 'success-rate';
import ScribeLogger from './ScribeLogger';
var instance: ?LogManager = null;
export default class LogManager {
constructor(store: ?Store) {
this.scribeLogger = new ScribeLogger(this);
@@ -28,3 +30,20 @@ export default class LogManager {
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;
}

View File

@@ -10,7 +10,7 @@ import ReactDOM from 'react-dom';
import {ContextMenuProvider} from 'flipper';
import {precachedIcons} from './utils/icons.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 BugReporter from './fb-stubs/BugReporter.js';
import {createStore} from 'redux';
@@ -26,7 +26,7 @@ const store = createStore(
);
persistStore(store);
const logger = new Logger(store);
const logger = initLogger(store);
const bugReporter = new BugReporter(logger, store);
dispatcher(store, logger);
GK.init();

View File

@@ -185,7 +185,6 @@ export default class Server extends EventEmitter {
destination,
),
'processCertificateSigningRequest',
this.logger,
)
.then(result => {
subscriber.onComplete({

View File

@@ -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,
);
});
});

View File

@@ -5,7 +5,7 @@
* @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
@@ -15,15 +15,14 @@ import type Logger from '../fb-stubs/Logger';
export function recordSuccessMetric(
promise: Promise<*>,
name: string,
logger: Logger,
): Promise<*> {
return promise.then(
fulfilledValue => {
logger.track('success-rate', name, 1);
getInstance().track('success-rate', name, 1);
return fulfilledValue;
},
rejectionReason => {
logger.track('success-rate', name, 0);
getInstance().track('success-rate', name, 0);
return Promise.reject(rejectionReason);
},
);