Stop storing device logs on the device object and in the plugin
Summary: Logs were stored hardcoded on the Device object first, this diff makes it normal plugin state. This makes sure that we can use the same abstractions as in all plugins that store large data sets, and that we can leverage the upcoming DataSource abstraction. Reviewed By: nikoant Differential Revision: D26127243 fbshipit-source-id: 7c386a615fa7989f35ba0df5b7c1d218d37b57a2
This commit is contained in:
committed by
Facebook GitHub Bot
parent
f2ade40239
commit
7cc55daf34
@@ -7,8 +7,10 @@
|
||||
* @format
|
||||
*/
|
||||
|
||||
import {sleep, TestUtils} from 'flipper-plugin';
|
||||
import {addEntriesToState, processEntry} from '../index';
|
||||
import {DeviceLogEntry} from 'flipper';
|
||||
import * as LogsPlugin from '../index';
|
||||
|
||||
const entry: DeviceLogEntry = {
|
||||
tag: 'OpenGLRenderer',
|
||||
@@ -83,3 +85,70 @@ test('addEntriesToState with reversed direction (add to front)', () => {
|
||||
expect(newState.entries.length).toBe(2);
|
||||
expect(newState.rows.length).toBe(2);
|
||||
});
|
||||
|
||||
test('export / import plugin does work', async () => {
|
||||
const {
|
||||
instance,
|
||||
exportStateAsync,
|
||||
sendLogEntry,
|
||||
} = TestUtils.startDevicePlugin(LogsPlugin);
|
||||
|
||||
sendLogEntry({
|
||||
date: new Date(1611854112859),
|
||||
message: 'test1',
|
||||
pid: 0,
|
||||
tag: 'test',
|
||||
tid: 1,
|
||||
type: 'error',
|
||||
app: 'X',
|
||||
});
|
||||
sendLogEntry({
|
||||
date: new Date(1611854117859),
|
||||
message: 'test2',
|
||||
pid: 2,
|
||||
tag: 'test',
|
||||
tid: 3,
|
||||
type: 'warn',
|
||||
app: 'Y',
|
||||
});
|
||||
|
||||
// batching and storage is async atm
|
||||
await sleep(500);
|
||||
|
||||
const data = await exportStateAsync();
|
||||
expect(data).toMatchInlineSnapshot(`
|
||||
Object {
|
||||
"logs": Array [
|
||||
Object {
|
||||
"app": "X",
|
||||
"date": 1611854112859,
|
||||
"message": "test1",
|
||||
"pid": 0,
|
||||
"tag": "test",
|
||||
"tid": 1,
|
||||
"type": "error",
|
||||
},
|
||||
Object {
|
||||
"app": "Y",
|
||||
"date": 1611854117859,
|
||||
"message": "test2",
|
||||
"pid": 2,
|
||||
"tag": "test",
|
||||
"tid": 3,
|
||||
"type": "warn",
|
||||
},
|
||||
],
|
||||
}
|
||||
`);
|
||||
|
||||
expect(instance.rows.get().length).toBe(2);
|
||||
|
||||
// Run a second import
|
||||
{
|
||||
const {exportStateAsync} = TestUtils.startDevicePlugin(LogsPlugin, {
|
||||
initialState: data,
|
||||
});
|
||||
|
||||
expect(await exportStateAsync()).toEqual(data);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -320,6 +320,10 @@ export function supportsDevice(device: Device) {
|
||||
);
|
||||
}
|
||||
|
||||
type ExportedState = {
|
||||
logs: (Omit<DeviceLogEntry, 'date'> & {date: number})[];
|
||||
};
|
||||
|
||||
export function devicePlugin(client: DevicePluginClient) {
|
||||
let counter = 0;
|
||||
let batch: Array<{
|
||||
@@ -330,22 +334,41 @@ export function devicePlugin(client: DevicePluginClient) {
|
||||
let batchTimer: NodeJS.Timeout | undefined;
|
||||
const tableRef: MutableRefObject<ManagedTableClass | null> = createRef();
|
||||
|
||||
// TODO T70688226: this can be removed once plugin stores logs,
|
||||
// rather than the device.
|
||||
|
||||
const initialState = addEntriesToState(
|
||||
client.device.realDevice
|
||||
.getLogs()
|
||||
.map((log: DeviceLogEntry) => processEntry(log, '' + counter++)),
|
||||
);
|
||||
|
||||
const rows = createState<ReadonlyArray<TableBodyRow>>(initialState.rows);
|
||||
const rows = createState<ReadonlyArray<TableBodyRow>>([]);
|
||||
const entries = createState<Entries>([]);
|
||||
const highlightedRows = createState<ReadonlySet<string>>(new Set());
|
||||
const counters = createState<ReadonlyArray<Counter>>(restoreSavedCounters());
|
||||
const timeDirection = createState<'up' | 'down'>('up');
|
||||
const isDeeplinked = createState(false);
|
||||
|
||||
client.onExport<ExportedState>(async () => {
|
||||
return {
|
||||
logs: entries
|
||||
.get()
|
||||
.slice(-10000)
|
||||
.map((e) => ({
|
||||
...e.entry,
|
||||
date: e.entry.date.getTime(),
|
||||
})),
|
||||
};
|
||||
});
|
||||
|
||||
client.onImport<ExportedState>((data) => {
|
||||
const imported = addEntriesToState(
|
||||
data.logs.map((log) =>
|
||||
processEntry(
|
||||
{
|
||||
...log,
|
||||
date: new Date(log.date),
|
||||
},
|
||||
'' + counter++,
|
||||
),
|
||||
),
|
||||
);
|
||||
rows.set(imported.rows);
|
||||
entries.set(imported.entries);
|
||||
});
|
||||
|
||||
client.onDeepLink((payload: unknown) => {
|
||||
if (typeof payload === 'string') {
|
||||
highlightedRows.set(calculateHighlightedRows(payload, rows.get()));
|
||||
@@ -485,10 +508,6 @@ export function devicePlugin(client: DevicePluginClient) {
|
||||
}
|
||||
|
||||
function clearLogs() {
|
||||
// TODO T70688226: implement this when the store is local
|
||||
client.device.realDevice.clearLogs().catch((e: any) => {
|
||||
console.error('Failed to clear logs: ', e);
|
||||
});
|
||||
entries.set([]);
|
||||
rows.set([]);
|
||||
highlightedRows.set(new Set());
|
||||
|
||||
Reference in New Issue
Block a user