From 64a4b3a8991aac1c3f0b9680571e87d5b4fef02f Mon Sep 17 00:00:00 2001 From: Lorenzo Blasa Date: Tue, 22 Aug 2023 05:16:20 -0700 Subject: [PATCH] Log tailer moved to flipper-common Summary: Log tailer is/could/will be used in different places, move to a centralised place. Reviewed By: antonk52 Differential Revision: D48524579 fbshipit-source-id: 81d6c4670572284ba2821a93011f5daa133b21fa --- .../flipper-common/src/utils/LoggerTailer.tsx | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 desktop/flipper-common/src/utils/LoggerTailer.tsx diff --git a/desktop/flipper-common/src/utils/LoggerTailer.tsx b/desktop/flipper-common/src/utils/LoggerTailer.tsx new file mode 100644 index 000000000..3d1fe3f53 --- /dev/null +++ b/desktop/flipper-common/src/utils/LoggerTailer.tsx @@ -0,0 +1,56 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @format + */ + +import {LoggerTypes} from './Logger'; + +export const logLevels: LoggerTypes[] = ['debug', 'info', 'warn', 'error']; +export type LogTailer = (level: LoggerTypes, ...data: Array) => void; + +const logTailers: LogTailer[] = []; +let initialized = false; + +export function addLogTailer(handler: LogTailer) { + logTailers.push(handler); +} + +export function initLogTailer() { + if (initialized) { + return; + } + + initialized = true; + + const originalConsole: {[key: string]: any} = console; + // Store the raw console log functions here + const originalConsoleLogFunctions: {[key: string]: (...args: any) => void} = + {} as { + [key: string]: (...args: any) => void; + }; + + // React Devtools also patches the console methods: + // https://github.com/facebook/react/blob/206d61f72214e8ae5b935f0bf8628491cb7f0797/packages/react-devtools-shared/src/backend/console.js#L141 + // Not using a proxy object here because it isn't compatible with their patching process. + // Instead replace the methods on the console itself. + // Doesn't matter who patches first, single thread means it will be consistent. + for (const level of logLevels) { + const originalConsoleLogFunction = originalConsole[level]; + originalConsoleLogFunctions[level] = originalConsoleLogFunction; + const overrideMethod = (...args: Array) => { + const newConsoleLogFunction = originalConsoleLogFunctions[level]; + const result = newConsoleLogFunction(...args); + logTailers.forEach((handler) => { + handler(level, ...args); + }); + return result; + }; + + overrideMethod.__FLIPPER_ORIGINAL_METHOD__ = originalConsoleLogFunction; + originalConsole[level] = overrideMethod; + } +}