diff --git a/desktop/flipper-ui-core/src/sandy-chrome/LeftRail.tsx b/desktop/flipper-ui-core/src/sandy-chrome/LeftRail.tsx
index 3275da78e..b2227209c 100644
--- a/desktop/flipper-ui-core/src/sandy-chrome/LeftRail.tsx
+++ b/desktop/flipper-ui-core/src/sandy-chrome/LeftRail.tsx
@@ -62,6 +62,7 @@ import {
showOpenDialog,
startFileExport,
startLinkExport,
+ startLogsExport,
} from '../utils/exportData';
import {openDeeplinkDialog} from '../deeplink';
import {css} from '@emotion/css';
@@ -224,6 +225,11 @@ function ExtrasMenu() {
() => startFileExport(store.dispatch),
[store.dispatch],
);
+ const startLogsExportTracked = useTrackedCallback(
+ 'Logs export',
+ startLogsExport,
+ [],
+ );
const startLinkExportTracked = useTrackedCallback(
'Link export',
() => startLinkExport(store.dispatch),
@@ -259,6 +265,11 @@ function ExtrasMenu() {
key="extras"
title={} small />}
className={submenu}>
+ {canFileExport() ? (
+
+ Export Flipper logs
+
+ ) : null}
{canOpenDialog() ? (
Import Flipper file
diff --git a/desktop/flipper-ui-core/src/utils/exportData.tsx b/desktop/flipper-ui-core/src/utils/exportData.tsx
index 515f84180..20cf3aed7 100644
--- a/desktop/flipper-ui-core/src/utils/exportData.tsx
+++ b/desktop/flipper-ui-core/src/utils/exportData.tsx
@@ -32,6 +32,7 @@ import ShareSheetExportFile from '../chrome/ShareSheetExportFile';
import ExportDataPluginSheet from '../chrome/ExportDataPluginSheet';
import {getRenderHostInstance} from 'flipper-frontend-core';
import {uploadFlipperMedia} from '../fb-stubs/user';
+import {logsAtom} from '../chrome/ConsoleLogs';
export const IMPORT_FLIPPER_TRACE_EVENT = 'import-flipper-trace';
export const EXPORT_FLIPPER_TRACE_EVENT = 'export-flipper-trace';
@@ -604,6 +605,14 @@ export function canFileExport() {
return !!getRenderHostInstance().showSaveDialog;
}
+export async function startLogsExport() {
+ const serializedLogs = logsAtom
+ .get()
+ .map((item) => JSON.stringify(item))
+ .join('\n');
+ await getRenderHostInstance().exportFile?.(serializedLogs);
+}
+
export async function startFileExport(dispatch: Store['dispatch']) {
const file = await getRenderHostInstance().showSaveDialog?.({
title: 'FlipperExport',