Skip to content

Commit ae14f89

Browse files
authored
Merge pull request #1024 from synonymdev/fix/export-logs
fix(recovery): export LDK logs
2 parents deb7a31 + d5e4b33 commit ae14f89

File tree

2 files changed

+81
-36
lines changed

2 files changed

+81
-36
lines changed

src/screens/Recovery/Recovery.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ const Recovery = ({
3535
}, []);
3636

3737
const onExportLogs = async (): Promise<void> => {
38-
const result = await zipLogs();
38+
const result = await zipLogs({ limit: 20, allAccounts: true });
3939
if (result.isErr()) {
4040
showErrorNotification({
4141
title: t('lightning:error_logs'),

src/utils/lightning/logs.ts

Lines changed: 80 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -6,74 +6,119 @@ import { err, ok, Result } from '@synonymdev/result';
66
/**
77
* Zips up the newest LDK logs and returns base64 of zip file
88
* @param {number} limit
9+
* @param {allAccounts} boolean
910
*/
10-
export const zipLogs = async (limit: number = 10): Promise<Result<string>> => {
11-
const logFilePrefix = 'bitkit_ldk_logs';
11+
export const zipLogs = async ({
12+
limit = 10,
13+
allAccounts = false,
14+
}: {
15+
limit?: number;
16+
allAccounts?: boolean;
17+
} = {}): Promise<Result<string>> => {
1218
const time = new Date().getTime();
13-
const fileName = `${logFilePrefix}_${time}`;
14-
15-
const logsPath = `${RNFS.DocumentDirectoryPath}/ldk/${lm.account.name}/logs`;
16-
const tempPath = `${logsPath}/share`;
17-
const zipPath = `${tempPath}/${fileName}.zip`;
19+
const logFilePrefix = 'bitkit_ldk_logs';
20+
const ldkPath = `${RNFS.DocumentDirectoryPath}/ldk`;
21+
const tempPath = `${RNFS.DocumentDirectoryPath}/bitkit_temp`;
22+
const zipFileName = `${logFilePrefix}_${time}`;
23+
const zipPath = `${tempPath}/${zipFileName}.zip`;
1824

1925
try {
20-
const logs = await listLogs(logsPath, limit);
21-
22-
//Copy to dir to be zipped
26+
// Create temporary folder
2327
await rm(tempPath);
24-
await mkdir(tempPath);
25-
for (let index = 0; index < logs.length; index++) {
26-
const logPath = logs[index];
27-
let filename = logPath.substring(logPath.lastIndexOf('/') + 1);
28-
await copyFile(logPath, `${tempPath}/${filename}`);
29-
}
28+
await mkdir(`${tempPath}/${zipFileName}`);
3029

31-
await zip(logs, zipPath);
32-
33-
//Cleanup duplicate logs after zips
34-
listLogs(tempPath, limit).then((newFiles) => {
35-
newFiles.forEach((f) => rm(f));
30+
const accounts = await listLogs({
31+
path: ldkPath,
32+
limit,
33+
accountName: allAccounts ? undefined : lm.account.name,
3634
});
3735

38-
return ok(zipPath);
36+
// Copy files to temporary folder to be zipped
37+
for (const account of accounts) {
38+
// Make a subfolder for each account
39+
const accountFolder = `${tempPath}/${zipFileName}/${account.id}`;
40+
await mkdir(accountFolder);
41+
42+
// Copy each log file to the account folder
43+
for (const logPath of account.files) {
44+
const fileName = logPath.substring(logPath.lastIndexOf('/') + 1);
45+
await copyFile(logPath, `${accountFolder}/${fileName}`);
46+
}
47+
}
48+
49+
// Zip up files
50+
const result = await zip(tempPath, zipPath);
51+
52+
return ok(result);
3953
} catch (error) {
4054
return err(error);
4155
}
4256
};
4357

4458
/**
45-
* Deletes a file or dir and ignores any errors
46-
* @param path
47-
* @returns {Promise<void>}
59+
* Lists .log files for all LDK accounts sorted by newest first
60+
* @param {string} path
61+
* @param {number} limit
62+
* @param {string} [accountName]
4863
*/
49-
const rm = async (path: string): Promise<void> => {
50-
try {
51-
if (await exists(path)) {
52-
await unlink(path);
53-
}
54-
} catch (e) {}
64+
const listLogs = async ({
65+
path,
66+
limit,
67+
accountName,
68+
}: {
69+
path: string;
70+
limit: number;
71+
accountName?: string;
72+
}): Promise<{ id: string; files: string[] }[]> => {
73+
const ldkPathItems = await RNFS.readDir(path);
74+
const filter = accountName ?? 'account';
75+
const accounts = ldkPathItems.filter((item) => item.path.endsWith(filter));
76+
77+
const promises = accounts.map(async (account) => {
78+
const files = await listLogsForAccount(`${account.path}/logs`, limit);
79+
return { id: account.name, files };
80+
});
81+
82+
return Promise.all(promises);
5583
};
5684

5785
/**
58-
* Lists .log files in a given directory and returns newest files first
86+
* Lists .log files for an LDK account sorted by newest first
5987
* @param path
6088
* @param limit
6189
* @returns {Promise<string[]>}
6290
*/
63-
const listLogs = async (path: string, limit: number): Promise<string[]> => {
91+
const listLogsForAccount = async (
92+
path: string,
93+
limit: number,
94+
): Promise<string[]> => {
6495
let list = await RNFS.readDir(path);
6596

66-
//Filter for log files only
97+
// Filter for log files only
6798
list = list.filter((f) => {
6899
return f.isFile() && f.name.indexOf('.log') > -1 && f.size > 0;
69100
});
70101

71-
//Newest first
102+
// Newest first
72103
list.sort((a, b) => {
73104
return (
74105
(b.mtime ?? new Date()).getTime() - (a.mtime ?? new Date()).getTime()
75106
);
76107
});
77108

109+
// Limit number of files
78110
return list.slice(0, limit).map((f) => f.path);
79111
};
112+
113+
/**
114+
* Deletes a file or dir and ignores any errors
115+
* @param path
116+
* @returns {Promise<void>}
117+
*/
118+
const rm = async (path: string): Promise<void> => {
119+
try {
120+
if (await exists(path)) {
121+
await unlink(path);
122+
}
123+
} catch (e) {}
124+
};

0 commit comments

Comments
 (0)