Connectivity Logs moved outside from TroubleshootingHub
Summary: Move it to its own space. Reviewed By: antonk52 Differential Revision: D47914495 fbshipit-source-id: 8d655a8f0fc9ed87adbb4c31dfb04e72aa6f5770
This commit is contained in:
committed by
Facebook GitHub Bot
parent
778eaf2038
commit
9ba93ad26b
185
desktop/flipper-ui-core/src/chrome/ConnectivityLogs.tsx
Normal file
185
desktop/flipper-ui-core/src/chrome/ConnectivityLogs.tsx
Normal file
@@ -0,0 +1,185 @@
|
|||||||
|
/**
|
||||||
|
* 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 {Layout} from '../ui';
|
||||||
|
import React, {CSSProperties, useState} from 'react';
|
||||||
|
import {
|
||||||
|
createDataSource,
|
||||||
|
DataFormatter,
|
||||||
|
DataInspector,
|
||||||
|
DataTable,
|
||||||
|
DataTableColumn,
|
||||||
|
theme,
|
||||||
|
styled,
|
||||||
|
} from 'flipper-plugin';
|
||||||
|
import {CloseCircleFilled, DeleteOutlined} from '@ant-design/icons';
|
||||||
|
import {
|
||||||
|
CommandRecordEntry,
|
||||||
|
ConnectionRecordEntry,
|
||||||
|
FlipperServer,
|
||||||
|
} from 'flipper-common';
|
||||||
|
import {Button} from 'antd';
|
||||||
|
|
||||||
|
const rows = createDataSource<ConnectionRecordEntry>([], {
|
||||||
|
limit: 200000,
|
||||||
|
persist: 'connectivity-logs',
|
||||||
|
});
|
||||||
|
|
||||||
|
export function enableConnectivityHook(flipperServer: FlipperServer) {
|
||||||
|
flipperServer.on(
|
||||||
|
'connectivity-troubleshoot-log',
|
||||||
|
(entry: ConnectionRecordEntry) => {
|
||||||
|
rows.append(entry);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
flipperServer.on(
|
||||||
|
'connectivity-troubleshoot-cmd',
|
||||||
|
(entry: CommandRecordEntry) => {
|
||||||
|
rows.append(entry);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const iconStyle = {
|
||||||
|
fontSize: '16px',
|
||||||
|
};
|
||||||
|
|
||||||
|
const baseRowStyle = {
|
||||||
|
...theme.monospace,
|
||||||
|
};
|
||||||
|
|
||||||
|
const logTypes: {
|
||||||
|
[level: string]: {
|
||||||
|
label: string;
|
||||||
|
icon?: React.ReactNode;
|
||||||
|
style?: CSSProperties;
|
||||||
|
enabled: boolean;
|
||||||
|
};
|
||||||
|
} = {
|
||||||
|
log: {
|
||||||
|
label: 'Log',
|
||||||
|
enabled: true,
|
||||||
|
},
|
||||||
|
cmd: {
|
||||||
|
label: 'Shell',
|
||||||
|
enabled: true,
|
||||||
|
style: {
|
||||||
|
...baseRowStyle,
|
||||||
|
color: theme.primaryColor,
|
||||||
|
},
|
||||||
|
icon: <CloseCircleFilled style={iconStyle} />,
|
||||||
|
},
|
||||||
|
error: {
|
||||||
|
label: 'Error',
|
||||||
|
style: {
|
||||||
|
...baseRowStyle,
|
||||||
|
color: theme.errorColor,
|
||||||
|
},
|
||||||
|
icon: <CloseCircleFilled style={iconStyle} />,
|
||||||
|
enabled: true,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
function createColumnConfig(): DataTableColumn<ConnectionRecordEntry>[] {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
key: 'time',
|
||||||
|
title: 'Time',
|
||||||
|
width: 160,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'device',
|
||||||
|
title: 'Device',
|
||||||
|
width: 160,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'app',
|
||||||
|
title: 'App',
|
||||||
|
width: 160,
|
||||||
|
visible: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'medium',
|
||||||
|
title: 'Medium',
|
||||||
|
width: 80,
|
||||||
|
visible: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'message',
|
||||||
|
title: 'Message',
|
||||||
|
wrap: true,
|
||||||
|
formatters: [
|
||||||
|
DataFormatter.truncate(400),
|
||||||
|
DataFormatter.prettyPrintJson,
|
||||||
|
DataFormatter.linkify,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
const columns = createColumnConfig();
|
||||||
|
|
||||||
|
function getRowStyle(entry: ConnectionRecordEntry): CSSProperties | undefined {
|
||||||
|
return (logTypes[entry.type]?.style as any) ?? baseRowStyle;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Placeholder = styled(Layout.Container)({
|
||||||
|
center: true,
|
||||||
|
color: theme.textColorPlaceholder,
|
||||||
|
fontSize: 18,
|
||||||
|
});
|
||||||
|
|
||||||
|
function Sidebar({selection}: {selection: undefined | ConnectionRecordEntry}) {
|
||||||
|
return (
|
||||||
|
<Layout.ScrollContainer pad>
|
||||||
|
{selection != null ? (
|
||||||
|
<DataInspector data={selection} expandRoot />
|
||||||
|
) : (
|
||||||
|
<Placeholder grow pad="large">
|
||||||
|
Select an entry to visualize details
|
||||||
|
</Placeholder>
|
||||||
|
)}
|
||||||
|
</Layout.ScrollContainer>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearMessages() {
|
||||||
|
rows.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
export const ConnectivityLogs = () => {
|
||||||
|
const [selection, setSelection] = useState<
|
||||||
|
ConnectionRecordEntry | undefined
|
||||||
|
>();
|
||||||
|
|
||||||
|
const clearButton = (
|
||||||
|
<Button
|
||||||
|
title="Clear logs"
|
||||||
|
onClick={() => {
|
||||||
|
setSelection(undefined);
|
||||||
|
clearMessages();
|
||||||
|
}}>
|
||||||
|
<DeleteOutlined />
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Layout.Right resizable width={400}>
|
||||||
|
<DataTable<ConnectionRecordEntry>
|
||||||
|
dataSource={rows}
|
||||||
|
columns={columns}
|
||||||
|
enableAutoScroll
|
||||||
|
onRowStyle={getRowStyle}
|
||||||
|
onSelect={setSelection}
|
||||||
|
extraActions={clearButton}
|
||||||
|
/>
|
||||||
|
<Sidebar selection={selection} />
|
||||||
|
</Layout.Right>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -8,186 +8,12 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {Layout} from '../ui';
|
import {Layout} from '../ui';
|
||||||
import React, {CSSProperties, useState} from 'react';
|
import React from 'react';
|
||||||
import {
|
import {Tab, Tabs} from 'flipper-plugin';
|
||||||
createDataSource,
|
|
||||||
DataFormatter,
|
|
||||||
DataInspector,
|
|
||||||
DataTable,
|
|
||||||
DataTableColumn,
|
|
||||||
Tab,
|
|
||||||
Tabs,
|
|
||||||
theme,
|
|
||||||
styled,
|
|
||||||
} from 'flipper-plugin';
|
|
||||||
import {CloseCircleFilled, DeleteOutlined} from '@ant-design/icons';
|
|
||||||
import {
|
|
||||||
CommandRecordEntry,
|
|
||||||
ConnectionRecordEntry,
|
|
||||||
FlipperServer,
|
|
||||||
} from 'flipper-common';
|
|
||||||
import SetupDoctorScreen from '../sandy-chrome/SetupDoctorScreen';
|
import SetupDoctorScreen from '../sandy-chrome/SetupDoctorScreen';
|
||||||
import {ConsoleLogs} from './ConsoleLogs';
|
import {ConsoleLogs} from './ConsoleLogs';
|
||||||
import {FlipperMessages} from './FlipperMessages';
|
import {FlipperMessages} from './FlipperMessages';
|
||||||
import {Button} from 'antd';
|
import {ConnectivityLogs} from './ConnectivityLogs';
|
||||||
|
|
||||||
const rows = createDataSource<ConnectionRecordEntry>([], {
|
|
||||||
limit: 200000,
|
|
||||||
persist: 'connectivity-logs',
|
|
||||||
});
|
|
||||||
|
|
||||||
export function enableConnectivityHook(flipperServer: FlipperServer) {
|
|
||||||
flipperServer.on(
|
|
||||||
'connectivity-troubleshoot-log',
|
|
||||||
(entry: ConnectionRecordEntry) => {
|
|
||||||
rows.append(entry);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
flipperServer.on(
|
|
||||||
'connectivity-troubleshoot-cmd',
|
|
||||||
(entry: CommandRecordEntry) => {
|
|
||||||
rows.append(entry);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const iconStyle = {
|
|
||||||
fontSize: '16px',
|
|
||||||
};
|
|
||||||
|
|
||||||
const baseRowStyle = {
|
|
||||||
...theme.monospace,
|
|
||||||
};
|
|
||||||
|
|
||||||
const logTypes: {
|
|
||||||
[level: string]: {
|
|
||||||
label: string;
|
|
||||||
icon?: React.ReactNode;
|
|
||||||
style?: CSSProperties;
|
|
||||||
enabled: boolean;
|
|
||||||
};
|
|
||||||
} = {
|
|
||||||
log: {
|
|
||||||
label: 'Log',
|
|
||||||
enabled: true,
|
|
||||||
},
|
|
||||||
cmd: {
|
|
||||||
label: 'Shell',
|
|
||||||
enabled: true,
|
|
||||||
style: {
|
|
||||||
...baseRowStyle,
|
|
||||||
color: theme.primaryColor,
|
|
||||||
},
|
|
||||||
icon: <CloseCircleFilled style={iconStyle} />,
|
|
||||||
},
|
|
||||||
error: {
|
|
||||||
label: 'Error',
|
|
||||||
style: {
|
|
||||||
...baseRowStyle,
|
|
||||||
color: theme.errorColor,
|
|
||||||
},
|
|
||||||
icon: <CloseCircleFilled style={iconStyle} />,
|
|
||||||
enabled: true,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
function createColumnConfig(): DataTableColumn<ConnectionRecordEntry>[] {
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
key: 'time',
|
|
||||||
title: 'Time',
|
|
||||||
width: 160,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'device',
|
|
||||||
title: 'Device',
|
|
||||||
width: 160,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'app',
|
|
||||||
title: 'App',
|
|
||||||
width: 160,
|
|
||||||
visible: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'medium',
|
|
||||||
title: 'Medium',
|
|
||||||
width: 80,
|
|
||||||
visible: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'message',
|
|
||||||
title: 'Message',
|
|
||||||
wrap: true,
|
|
||||||
formatters: [
|
|
||||||
DataFormatter.truncate(400),
|
|
||||||
DataFormatter.prettyPrintJson,
|
|
||||||
DataFormatter.linkify,
|
|
||||||
],
|
|
||||||
},
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
const columns = createColumnConfig();
|
|
||||||
|
|
||||||
function getRowStyle(entry: ConnectionRecordEntry): CSSProperties | undefined {
|
|
||||||
return (logTypes[entry.type]?.style as any) ?? baseRowStyle;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Placeholder = styled(Layout.Container)({
|
|
||||||
center: true,
|
|
||||||
color: theme.textColorPlaceholder,
|
|
||||||
fontSize: 18,
|
|
||||||
});
|
|
||||||
|
|
||||||
function Sidebar({selection}: {selection: undefined | ConnectionRecordEntry}) {
|
|
||||||
return (
|
|
||||||
<Layout.ScrollContainer pad>
|
|
||||||
{selection != null ? (
|
|
||||||
<DataInspector data={selection} expandRoot />
|
|
||||||
) : (
|
|
||||||
<Placeholder grow pad="large">
|
|
||||||
Select an entry to visualize details
|
|
||||||
</Placeholder>
|
|
||||||
)}
|
|
||||||
</Layout.ScrollContainer>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function clearMessages() {
|
|
||||||
rows.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
const LogView = () => {
|
|
||||||
const [selection, setSelection] = useState<
|
|
||||||
ConnectionRecordEntry | undefined
|
|
||||||
>();
|
|
||||||
|
|
||||||
const clearButton = (
|
|
||||||
<Button
|
|
||||||
title="Clear logs"
|
|
||||||
onClick={() => {
|
|
||||||
setSelection(undefined);
|
|
||||||
clearMessages();
|
|
||||||
}}>
|
|
||||||
<DeleteOutlined />
|
|
||||||
</Button>
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Layout.Right resizable width={400}>
|
|
||||||
<DataTable<ConnectionRecordEntry>
|
|
||||||
dataSource={rows}
|
|
||||||
columns={columns}
|
|
||||||
enableAutoScroll
|
|
||||||
onRowStyle={getRowStyle}
|
|
||||||
onSelect={setSelection}
|
|
||||||
extraActions={clearButton}
|
|
||||||
/>
|
|
||||||
<Sidebar selection={selection} />
|
|
||||||
</Layout.Right>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export function TroubleshootingHub() {
|
export function TroubleshootingHub() {
|
||||||
return (
|
return (
|
||||||
@@ -197,7 +23,7 @@ export function TroubleshootingHub() {
|
|||||||
<SetupDoctorScreen visible modal={false} onClose={() => {}} />
|
<SetupDoctorScreen visible modal={false} onClose={() => {}} />
|
||||||
</Tab>
|
</Tab>
|
||||||
<Tab tab="Connectivity Logs" tabKey="connectivity-logs">
|
<Tab tab="Connectivity Logs" tabKey="connectivity-logs">
|
||||||
<LogView />
|
<ConnectivityLogs />
|
||||||
</Tab>
|
</Tab>
|
||||||
<Tab tab="Console Logs" tabKey="console-logs">
|
<Tab tab="Console Logs" tabKey="console-logs">
|
||||||
<ConsoleLogs />
|
<ConsoleLogs />
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ import {getRenderHostInstance} from 'flipper-frontend-core';
|
|||||||
import {startGlobalErrorHandling} from './utils/globalErrorHandling';
|
import {startGlobalErrorHandling} from './utils/globalErrorHandling';
|
||||||
import {loadTheme} from './utils/loadTheme';
|
import {loadTheme} from './utils/loadTheme';
|
||||||
import {connectFlipperServerToStore} from './dispatcher/flipperServer';
|
import {connectFlipperServerToStore} from './dispatcher/flipperServer';
|
||||||
import {enableConnectivityHook} from './chrome/TroubleshootingHub';
|
import {enableConnectivityHook} from './chrome/ConnectivityLogs';
|
||||||
import ReactDOM from 'react-dom';
|
import ReactDOM from 'react-dom';
|
||||||
|
|
||||||
class AppFrame extends React.Component<
|
class AppFrame extends React.Component<
|
||||||
|
|||||||
Reference in New Issue
Block a user