diff --git a/client/electron/src/index.ts b/client/electron/src/index.ts
index e81c8ca46b0..207dae76918 100644
--- a/client/electron/src/index.ts
+++ b/client/electron/src/index.ts
@@ -280,18 +280,8 @@ ipcMain.on(PageToWindowChannel.CriticalError, async (_event, message: string, er
});
ipcMain.on(PageToWindowChannel.GetLogs, async () => {
- const RE = /^\[(.+)\] \[(debug|info|warn|error|critical)\] (.+)$/;
- const logs = log.transports.file.readAllLogs().flatMap((v) => {
- return v.lines
- .map((line) => {
- const match = line.match(RE);
- if (match && match.length === 4) {
- return { message: match[3], level: match[2], timestamp: match[1] };
- }
- })
- .filter((record) => record !== undefined);
- });
- parsecApp.sendEvent(WindowToPageChannel.LogRecords, logs);
+ const content = fs.readFileSync(log.transports.file.getFile().path, { encoding: 'utf-8', flag: 'r' });
+ parsecApp.sendEvent(WindowToPageChannel.LogRecords, content);
});
ipcMain.on(PageToWindowChannel.OpenPopup, async (_event, url: string) => {
diff --git a/client/src/components/misc/BugReportModal.vue b/client/src/components/misc/BugReportModal.vue
index 345ccf2d253..761747126cb 100644
--- a/client/src/components/misc/BugReportModal.vue
+++ b/client/src/components/misc/BugReportModal.vue
@@ -41,6 +41,7 @@
@@ -72,10 +73,9 @@
import { getMimeTypeFromBuffer } from '@/common/fileTypes';
import { emailValidator } from '@/common/validators';
import { FileInputList } from '@/components/files';
-import { openLogDisplayModal } from '@/components/misc';
-import { isWeb, ParsecAccount } from '@/parsec';
+import { getLogs, openLogDisplayModal } from '@/components/misc';
+import { ParsecAccount } from '@/parsec';
import { BmsApi, FileData } from '@/services/bms';
-import { formatLogEntry, LogEntry, WebLogger } from '@/services/webLogger';
import { IonButton, IonText, IonToggle, modalController } from '@ionic/vue';
import { MsInput, MsModal, MsModalResult, MsReportText, MsReportTheme, MsTextarea, Validity } from 'megashark-lib';
import { computed, onMounted, ref, useTemplateRef } from 'vue';
@@ -87,7 +87,8 @@ const includeLogs = ref(false);
const listInputRef = useTemplateRef
>('listInput');
const sendingReport = ref(false);
const sendError = ref('');
-const logs = ref>([]);
+const logs = ref('');
+const aggregatingLogs = ref(false);
const canSend = computed(() => {
return emailInputRef.value && emailInputRef.value.validity === Validity.Valid && description.value.length > 0 && email.value.length > 0;
@@ -104,18 +105,12 @@ onMounted(async () => {
async function logToggled(): Promise {
if (includeLogs.value) {
- if (isWeb()) {
- logs.value = await WebLogger.getEntries();
- } else {
- window.electronAPI.getLogs();
- }
+ aggregatingLogs.value = true;
+ logs.value = await getLogs();
+ aggregatingLogs.value = false;
}
}
-window.electronAPI.receive('parsec-log-records', async (logRecords: Array) => {
- logs.value = logRecords;
-});
-
async function readFile(file: File): Promise {
return new Promise((resolve, reject) => {
const reader = new FileReader();
@@ -150,7 +145,7 @@ async function sendBugReport(): Promise {
description: description.value,
},
{
- logs: includeLogs.value ? logs.value.map((entry) => formatLogEntry(entry)) : undefined,
+ logs: includeLogs.value ? logs.value : undefined,
files: files,
},
);
diff --git a/client/src/components/misc/LogDisplay.vue b/client/src/components/misc/LogDisplay.vue
index caa9fa5c5e0..c30680f6a9e 100644
--- a/client/src/components/misc/LogDisplay.vue
+++ b/client/src/components/misc/LogDisplay.vue
@@ -6,17 +6,12 @@
class="logs"
v-if="!loading"
>
-
-
- {{ record.message }}
- {{ record.timestamp }}
-
-
+
diff --git a/client/src/components/misc/utils.ts b/client/src/components/misc/utils.ts
index f65188782c5..49afad5f339 100644
--- a/client/src/components/misc/utils.ts
+++ b/client/src/components/misc/utils.ts
@@ -2,6 +2,8 @@
import BugReportModal from '@/components/misc/BugReportModal.vue';
import LogDisplayModal from '@/components/misc/LogDisplayModal.vue';
+import { isWeb } from '@/parsec';
+import { formatLogEntry, WebLogger } from '@/services/webLogger';
import { modalController } from '@ionic/vue';
import { MsModalResult } from 'megashark-lib';
@@ -32,3 +34,25 @@ export async function openBugReportModal(): Promise {
await modal.dismiss();
return (role as MsModalResult) ?? MsModalResult.Cancel;
}
+
+export async function getLogs(): Promise {
+ if (isWeb()) {
+ const logEntries = await WebLogger.getEntries();
+ return logEntries.map((entry) => formatLogEntry(entry)).join('\n');
+ } else {
+ const logs = await new Promise((resolve) => {
+ const timeoutId = setTimeout(() => {
+ window.electronAPI.log('warn', 'Took too long to retrieve the logs.');
+ resolve('');
+ }, 10000);
+
+ window.electronAPI.receive('parsec-log-records', async (logs: string) => {
+ clearTimeout(timeoutId);
+ resolve(logs);
+ });
+
+ window.electronAPI.getLogs();
+ });
+ return logs;
+ }
+}
diff --git a/client/src/services/bms/api.ts b/client/src/services/bms/api.ts
index 38c85d1586e..8696f34ca82 100644
--- a/client/src/services/bms/api.ts
+++ b/client/src/services/bms/api.ts
@@ -738,7 +738,7 @@ export interface FileData {
}
interface BugReportOptions {
- logs?: Array;
+ logs?: string;
includeScreenshot?: boolean;
files?: Array;
}
@@ -760,7 +760,7 @@ async function reportBug(query: BugReportQueryData, opts?: BugReportOptions): Pr
formData.append('description', query.description);
formData.append('version', APP_VERSION);
if (opts?.logs) {
- formData.append('logs', new Blob([JSON.stringify(opts?.logs)], { type: 'application/json' }), 'logs');
+ formData.append('logs', new Blob([opts.logs], { type: 'text/plain' }), 'logs.txt');
}
// For later
// if (opts.includeScreenshot) {