Introduced first class console to help users debugging issues (#1479)
Summary: Handling issues typically start with: did you look at the Electron logs? Since Flipper is such an extensible tool, running in varying environments I think the console should be support as first class concept. Many errors are currently not shown to the user. This PR is a first attempt to fix that. The implementation is based on https://github.com/samdenty/console-feed, which is used by quite some web based IDE like tools (like codesandbox), and offers a lot of goodies out of the box, like collapsing errors, objects, etc. Edit: also added a counter keeping track of the amount of errors N.B. no need to immediately review this diff, I'll import it to phabricator as soon as I can :) ## Changelog changelog: Introduce 'Debug Logs' section to help users to troubleshoot issues or to provide more accurate reports. Pull Request resolved: https://github.com/facebook/flipper/pull/1479 Test Plan:  Reviewed By: jknoxville Differential Revision: D23198103 Pulled By: passy fbshipit-source-id: a2505f9fa59e10676a44ffa33312efe83c7be55d
This commit is contained in:
committed by
Facebook GitHub Bot
parent
baa29d0b49
commit
dd15cffa64
@@ -23,6 +23,7 @@
|
||||
"archiver": "^5.0.0",
|
||||
"async-mutex": "^0.1.3",
|
||||
"axios": "^0.19.2",
|
||||
"console-feed": "^3.0.1",
|
||||
"deep-equal": "^2.0.1",
|
||||
"emotion": "^10.0.23",
|
||||
"expand-tilde": "^2.0.2",
|
||||
|
||||
93
desktop/app/src/chrome/ConsoleLogs.tsx
Normal file
93
desktop/app/src/chrome/ConsoleLogs.tsx
Normal file
@@ -0,0 +1,93 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its 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 {useMemo} from 'react';
|
||||
import {Button, Toolbar, ButtonGroup, Layout} from '../ui';
|
||||
import React from 'react';
|
||||
import {Console, Hook} from 'console-feed';
|
||||
import type {Methods} from 'console-feed/lib/definitions/Methods';
|
||||
import {createState, useValue} from 'flipper-plugin';
|
||||
import {useLocalStorage} from '../utils/useLocalStorage';
|
||||
|
||||
const logsAtom = createState<any[]>([]);
|
||||
export const errorCounterAtom = createState(0);
|
||||
|
||||
export function enableConsoleHook() {
|
||||
console.log('enabling hooks');
|
||||
Hook(
|
||||
window.console,
|
||||
(log) => {
|
||||
logsAtom.set([...logsAtom.get(), log]);
|
||||
if (log.method === 'error' || log.method === 'assert') {
|
||||
errorCounterAtom.set(errorCounterAtom.get() + 1);
|
||||
}
|
||||
},
|
||||
false,
|
||||
);
|
||||
}
|
||||
|
||||
function clearLogs() {
|
||||
logsAtom.set([]);
|
||||
errorCounterAtom.set(0);
|
||||
}
|
||||
|
||||
const allLogLevels: Methods[] = [
|
||||
'log',
|
||||
'debug',
|
||||
'info',
|
||||
'warn',
|
||||
'error',
|
||||
'table',
|
||||
'clear',
|
||||
'time',
|
||||
'timeEnd',
|
||||
'count',
|
||||
'assert',
|
||||
];
|
||||
|
||||
const defaultLogLevels: Methods[] = ['warn', 'error', 'table', 'assert'];
|
||||
|
||||
export function ConsoleLogs() {
|
||||
const logs = useValue(logsAtom);
|
||||
const [logLevels, setLogLevels] = useLocalStorage<Methods[]>(
|
||||
'console-logs-loglevels',
|
||||
defaultLogLevels,
|
||||
);
|
||||
|
||||
const dropdown = useMemo(() => {
|
||||
return allLogLevels.map(
|
||||
(l): Electron.MenuItemConstructorOptions => ({
|
||||
label: l,
|
||||
checked: logLevels.includes(l),
|
||||
type: 'checkbox',
|
||||
click() {
|
||||
setLogLevels((state) =>
|
||||
state.includes(l)
|
||||
? state.filter((level) => level !== l)
|
||||
: [l, ...state],
|
||||
);
|
||||
},
|
||||
}),
|
||||
);
|
||||
}, [logLevels, setLogLevels]);
|
||||
|
||||
return (
|
||||
<Layout.Top scrollable>
|
||||
<Toolbar>
|
||||
<ButtonGroup>
|
||||
<Button onClick={clearLogs} icon="trash">
|
||||
Clear Logs
|
||||
</Button>
|
||||
<Button dropdown={dropdown}>Log Levels</Button>
|
||||
</ButtonGroup>
|
||||
</Toolbar>
|
||||
<Console logs={logs} filter={logLevels} variant="light" />
|
||||
</Layout.Top>
|
||||
);
|
||||
}
|
||||
@@ -29,6 +29,8 @@ import {
|
||||
} from './sidebarUtils';
|
||||
import {Group} from '../../reducers/supportForm';
|
||||
import {getInstance} from '../../fb-stubs/Logger';
|
||||
import {ConsoleLogs, errorCounterAtom} from '../ConsoleLogs';
|
||||
import {useValue} from 'flipper-plugin';
|
||||
|
||||
type OwnProps = {};
|
||||
|
||||
@@ -103,6 +105,7 @@ function MainSidebarUtilsSection({
|
||||
/>
|
||||
Manage Plugins
|
||||
</ListItem>
|
||||
<DebugLogsEntry staticView={staticView} setStaticView={setStaticView} />
|
||||
{config.showLogin && <UserAccount />}
|
||||
</div>
|
||||
);
|
||||
@@ -171,3 +174,26 @@ const RenderNotificationsEntry = connect<
|
||||
</ListItem>
|
||||
);
|
||||
});
|
||||
|
||||
function DebugLogsEntry({
|
||||
staticView,
|
||||
setStaticView,
|
||||
}: {
|
||||
staticView: StaticView;
|
||||
setStaticView: (payload: StaticView) => void;
|
||||
}) {
|
||||
const active = isStaticViewActive(staticView, ConsoleLogs);
|
||||
const errorCount = useValue(errorCounterAtom);
|
||||
return (
|
||||
<ListItem onClick={() => setStaticView(ConsoleLogs)} active={active}>
|
||||
<PluginIcon
|
||||
name="caution-octagon"
|
||||
color={colors.light50}
|
||||
isActive={active}
|
||||
/>
|
||||
<PluginName count={errorCount} isActive={active}>
|
||||
Debug Logs
|
||||
</PluginName>
|
||||
</ListItem>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -85,6 +85,7 @@ const PluginShape = styled(FlexBox)<{
|
||||
|
||||
export const PluginName = styled(Text)<{isActive?: boolean; count?: number}>(
|
||||
(props) => ({
|
||||
cursor: 'default',
|
||||
minWidth: 0,
|
||||
textOverflow: 'ellipsis',
|
||||
whiteSpace: 'nowrap',
|
||||
|
||||
@@ -38,6 +38,7 @@ import os from 'os';
|
||||
import QuickPerformanceLogger, {FLIPPER_QPL_EVENTS} from './fb-stubs/QPL';
|
||||
import {PopoverProvider} from './ui/components/PopoverProvider';
|
||||
import {initializeFlipperLibImplementation} from './utils/flipperLibImplementation';
|
||||
import {enableConsoleHook} from './chrome/ConsoleLogs';
|
||||
|
||||
if (process.env.NODE_ENV === 'development' && os.platform() === 'darwin') {
|
||||
// By default Node.JS has its internal certificate storage and doesn't use
|
||||
@@ -119,6 +120,7 @@ function init() {
|
||||
const sessionId = store.getState().application.sessionId;
|
||||
initCrashReporter(sessionId || '');
|
||||
registerRecordingHooks(store);
|
||||
enableConsoleHook();
|
||||
window.flipperGlobalStoreDispatch = store.dispatch;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,13 +27,15 @@ import {getPluginKey, isDevicePluginDefinition} from '../utils/pluginUtils';
|
||||
import {deconstructClientId} from '../utils/clientUtils';
|
||||
import {PluginDefinition} from '../plugin';
|
||||
import {RegisterPluginAction} from './plugins';
|
||||
import {ConsoleLogs} from '../chrome/ConsoleLogs';
|
||||
|
||||
export type StaticView =
|
||||
| null
|
||||
| typeof WelcomeScreen
|
||||
| typeof NotificationScreen
|
||||
| typeof SupportRequestFormV2
|
||||
| typeof SupportRequestDetails;
|
||||
| typeof SupportRequestDetails
|
||||
| typeof ConsoleLogs;
|
||||
|
||||
export type FlipperError = {
|
||||
occurrences?: number;
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
16
|
||||
],
|
||||
"caution-octagon": [
|
||||
12,
|
||||
16,
|
||||
20
|
||||
],
|
||||
|
||||
@@ -1240,10 +1240,10 @@
|
||||
"@emotion/utils" "0.11.3"
|
||||
"@emotion/weak-memoize" "0.2.5"
|
||||
|
||||
"@emotion/core@^10.0.22":
|
||||
version "10.0.28"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/core/-/core-10.0.28.tgz#bb65af7262a234593a9e952c041d0f1c9b9bef3d"
|
||||
integrity sha512-pH8UueKYO5jgg0Iq+AmCLxBsvuGtvlmiDCOuv8fGNYn3cowFpLN98L8zO56U0H1PjDIyAlXymgL3Wu7u7v6hbA==
|
||||
"@emotion/core@^10.0.10", "@emotion/core@^10.0.22":
|
||||
version "10.0.35"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/core/-/core-10.0.35.tgz#513fcf2e22cd4dfe9d3894ed138c9d7a859af9b3"
|
||||
integrity sha512-sH++vJCdk025fBlRZSAhkRlSUoqSqgCzYf5fMOmqqi3bM6how+sQpg3hkgJonj8GxXM4WbD7dRO+4tegDB9fUw==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.5.5"
|
||||
"@emotion/cache" "^10.0.27"
|
||||
@@ -1304,7 +1304,7 @@
|
||||
"@emotion/serialize" "^0.11.15"
|
||||
"@emotion/utils" "0.11.3"
|
||||
|
||||
"@emotion/styled@^10.0.23":
|
||||
"@emotion/styled@^10.0.12", "@emotion/styled@^10.0.23":
|
||||
version "10.0.27"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/styled/-/styled-10.0.27.tgz#12cb67e91f7ad7431e1875b1d83a94b814133eaf"
|
||||
integrity sha512-iK/8Sh7+NLJzyp9a5+vIQIXTYxfT4yB/OJbjzQanB2RZpvmzBQOHZWhpAMZWYEKRNNbsD6WfBw5sVWkb6WzS/Q==
|
||||
@@ -4134,6 +4134,17 @@ connect@^3.6.5:
|
||||
parseurl "~1.3.3"
|
||||
utils-merge "1.0.1"
|
||||
|
||||
console-feed@^3.0.1:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/console-feed/-/console-feed-3.0.1.tgz#2ca6dec57aee15ff3af300c323008fba542536a0"
|
||||
integrity sha512-RD49E64OOm9qRAsbvTB0UnMFTtjEo7fKW8cSwqcgA9B45EraNFtFJjWppje+YPZpfhHHX579u+RtzLFm77mhTA==
|
||||
dependencies:
|
||||
"@emotion/core" "^10.0.10"
|
||||
"@emotion/styled" "^10.0.12"
|
||||
emotion-theming "^10.0.10"
|
||||
linkifyjs "^2.1.6"
|
||||
react-inspector "^3.0.2"
|
||||
|
||||
contains-path@^0.1.0:
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a"
|
||||
@@ -4966,6 +4977,15 @@ emoji-regex@^9.0.0:
|
||||
resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.0.0.tgz#48a2309cc8a1d2e9d23bc6a67c39b63032e76ea4"
|
||||
integrity sha512-6p1NII1Vm62wni/VR/cUMauVQoxmLVb9csqQlvLz+hO2gk8U2UYDfXHQSUYIBKmZwAKz867IDqG7B+u0mj+M6w==
|
||||
|
||||
emotion-theming@^10.0.10:
|
||||
version "10.0.27"
|
||||
resolved "https://registry.yarnpkg.com/emotion-theming/-/emotion-theming-10.0.27.tgz#1887baaec15199862c89b1b984b79806f2b9ab10"
|
||||
integrity sha512-MlF1yu/gYh8u+sLUqA0YuA9JX0P4Hb69WlKc/9OLo+WCXuX6sy/KoIa+qJimgmr2dWqnypYKYPX37esjDBbhdw==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.5.5"
|
||||
"@emotion/weak-memoize" "0.2.5"
|
||||
hoist-non-react-statics "^3.3.0"
|
||||
|
||||
emotion@^10.0.23:
|
||||
version "10.0.27"
|
||||
resolved "https://registry.yarnpkg.com/emotion/-/emotion-10.0.27.tgz#f9ca5df98630980a23c819a56262560562e5d75e"
|
||||
@@ -6827,6 +6847,14 @@ is-docker@^2.0.0:
|
||||
resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.0.0.tgz#2cb0df0e75e2d064fe1864c37cdeacb7b2dcf25b"
|
||||
integrity sha512-pJEdRugimx4fBMra5z2/5iRdZ63OhYV0vr0Dwm5+xtW4D1FvRkB8hamMIhnWfyJeDdyr/aa7BDyNbtG38VxgoQ==
|
||||
|
||||
is-dom@^1.0.9:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/is-dom/-/is-dom-1.1.0.tgz#af1fced292742443bb59ca3f76ab5e80907b4e8a"
|
||||
integrity sha512-u82f6mvhYxRPKpw8V1N0W8ce1xXwOrQtgGcxl6UCL5zBmZu3is/18K0rR7uFCnMDuAsS/3W54mGL4vsaFUQlEQ==
|
||||
dependencies:
|
||||
is-object "^1.0.1"
|
||||
is-window "^1.0.2"
|
||||
|
||||
is-extendable@^0.1.0, is-extendable@^0.1.1:
|
||||
version "0.1.1"
|
||||
resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89"
|
||||
@@ -6916,6 +6944,11 @@ is-obj@^2.0.0:
|
||||
resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-2.0.0.tgz#473fb05d973705e3fd9620545018ca8e22ef4982"
|
||||
integrity sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==
|
||||
|
||||
is-object@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.1.tgz#8952688c5ec2ffd6b03ecc85e769e02903083470"
|
||||
integrity sha1-iVJojF7C/9awPsyF52ngKQMINHA=
|
||||
|
||||
is-path-inside@^3.0.1:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.2.tgz#f5220fc82a3e233757291dddc9c5877f2a1f3017"
|
||||
@@ -7012,6 +7045,11 @@ is-whitespace-character@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/is-whitespace-character/-/is-whitespace-character-1.0.4.tgz#0858edd94a95594c7c9dd0b5c174ec6e45ee4aa7"
|
||||
integrity sha512-SDweEzfIZM0SJV0EUga669UTKlmL0Pq8Lno0QDQsPnvECB3IM2aP0gdx5TrU0A01MAPfViaZiI2V1QMZLaKK5w==
|
||||
|
||||
is-window@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/is-window/-/is-window-1.0.2.tgz#2c896ca53db97de45d3c33133a65d8c9f563480d"
|
||||
integrity sha1-LIlspT25feRdPDMTOmXYyfVjSA0=
|
||||
|
||||
is-windows@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d"
|
||||
@@ -8194,6 +8232,11 @@ linked-list@0.1.0:
|
||||
resolved "https://registry.yarnpkg.com/linked-list/-/linked-list-0.1.0.tgz#798b0ff97d1b92a4fd08480f55aea4e9d49d37bf"
|
||||
integrity sha1-eYsP+X0bkqT9CEgPVa6k6dSdN78=
|
||||
|
||||
linkifyjs@^2.1.6:
|
||||
version "2.1.9"
|
||||
resolved "https://registry.yarnpkg.com/linkifyjs/-/linkifyjs-2.1.9.tgz#af06e45a2866ff06c4766582590d098a4d584702"
|
||||
integrity sha512-74ivurkK6WHvHFozVaGtQWV38FzBwSTGNmJolEgFp7QgR2bl6ArUWlvT4GcHKbPe1z3nWYi+VUdDZk16zDOVug==
|
||||
|
||||
live-plugin-manager@^0.14.1:
|
||||
version "0.14.1"
|
||||
resolved "https://registry.yarnpkg.com/live-plugin-manager/-/live-plugin-manager-0.14.1.tgz#34b6bb8f3d2062ec2557c857ca028fea9dc2b6db"
|
||||
@@ -9797,7 +9840,7 @@ prompts@^2.0.1:
|
||||
kleur "^3.0.3"
|
||||
sisteransi "^1.0.3"
|
||||
|
||||
prop-types@^15.5.10, prop-types@^15.5.6, prop-types@^15.6.0, prop-types@^15.6.2, prop-types@^15.7.2:
|
||||
prop-types@^15.5.10, prop-types@^15.5.6, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2:
|
||||
version "15.7.2"
|
||||
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5"
|
||||
integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==
|
||||
@@ -9995,6 +10038,15 @@ react-dom@^16.13.0:
|
||||
prop-types "^15.6.2"
|
||||
scheduler "^0.19.1"
|
||||
|
||||
react-inspector@^3.0.2:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/react-inspector/-/react-inspector-3.0.2.tgz#c530a06101f562475537e47df428e1d7aff16ed8"
|
||||
integrity sha512-PSR8xDoGFN8R3LKmq1NT+hBBwhxjd9Qwz8yKY+5NXY/CHpxXHm01CVabxzI7zFwFav/M3JoC/Z0Ro2kSX6Ef2Q==
|
||||
dependencies:
|
||||
babel-runtime "^6.26.0"
|
||||
is-dom "^1.0.9"
|
||||
prop-types "^15.6.1"
|
||||
|
||||
react-is@^16.12.0, react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.6, react-is@^16.9.0:
|
||||
version "16.13.1"
|
||||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
|
||||
|
||||
Reference in New Issue
Block a user