Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 2 additions & 12 deletions client/electron/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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) => {
Expand Down
23 changes: 9 additions & 14 deletions client/src/components/misc/BugReportModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
<ion-toggle
v-model="includeLogs"
@ion-change="logToggled"
:disabled="aggregatingLogs"
class="report-logs__toggle"
/>
<div class="report-logs-text">
Expand Down Expand Up @@ -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';
Expand All @@ -87,7 +87,8 @@ const includeLogs = ref(false);
const listInputRef = useTemplateRef<InstanceType<typeof FileInputList>>('listInput');
const sendingReport = ref(false);
const sendError = ref('');
const logs = ref<Array<LogEntry>>([]);
const logs = ref<string>('');
const aggregatingLogs = ref(false);

const canSend = computed(() => {
return emailInputRef.value && emailInputRef.value.validity === Validity.Valid && description.value.length > 0 && email.value.length > 0;
Expand All @@ -104,18 +105,12 @@ onMounted(async () => {

async function logToggled(): Promise<void> {
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<LogEntry>) => {
logs.value = logRecords;
});

async function readFile(file: File): Promise<Uint8Array> {
return new Promise((resolve, reject) => {
const reader = new FileReader();
Expand Down Expand Up @@ -150,7 +145,7 @@ async function sendBugReport(): Promise<boolean> {
description: description.value,
},
{
logs: includeLogs.value ? logs.value.map((entry) => formatLogEntry(entry)) : undefined,
logs: includeLogs.value ? logs.value : undefined,
files: files,
},
);
Expand Down
43 changes: 10 additions & 33 deletions client/src/components/misc/LogDisplay.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,12 @@
class="logs"
v-if="!loading"
>
<ms-report-text
v-for="(record, index) of logs"
:key="index"
:theme="LevelThemeMapping[record.level]"
class="log-entry"
>
<div class="log-entry-text">
<ion-text class="log-entry-text__message body">{{ record.message }}</ion-text>
<ion-text class="log-entry-text__timestamp body-sm">{{ record.timestamp }}</ion-text>
</div>
</ms-report-text>
<textarea
v-show="logs.length > 0"
class="log-area"
readonly
:value="logs"
/>
<ms-report-text
v-show="logs.length === 0"
:theme="MsReportTheme.Info"
Expand Down Expand Up @@ -45,35 +40,17 @@
</template>

<script setup lang="ts">
import { isWeb } from '@/parsec';
import { LogEntry, WebLogger } from '@/services/webLogger';
import { IonSkeletonText, IonText } from '@ionic/vue';
import { getLogs } from '@/components/misc/utils';
import { IonSkeletonText } from '@ionic/vue';
import { MsReportText, MsReportTheme } from 'megashark-lib';
import { onMounted, ref } from 'vue';

const LevelThemeMapping = {
['debug']: MsReportTheme.Info,
['info']: MsReportTheme.Info,
['warn']: MsReportTheme.Warning,
['error']: MsReportTheme.Error,
['critical']: MsReportTheme.Error,
};

const logs = ref<Array<LogEntry>>([]);
const logs = ref<string>('');
const loading = ref(true);

onMounted(async () => {
loading.value = true;
if (isWeb()) {
logs.value = (await WebLogger.getEntries()).reverse();
loading.value = false;
} else {
window.electronAPI.getLogs();
}
});

window.electronAPI.receive('parsec-log-records', async (logRecords: Array<LogEntry>) => {
logs.value = logRecords.reverse();
logs.value = await getLogs();
loading.value = false;
});
</script>
Expand Down
24 changes: 24 additions & 0 deletions client/src/components/misc/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand Down Expand Up @@ -32,3 +34,25 @@ export async function openBugReportModal(): Promise<MsModalResult> {
await modal.dismiss();
return (role as MsModalResult) ?? MsModalResult.Cancel;
}

export async function getLogs(): Promise<string> {
if (isWeb()) {
const logEntries = await WebLogger.getEntries();
return logEntries.map((entry) => formatLogEntry(entry)).join('\n');
} else {
const logs = await new Promise<string>((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;
}
}
4 changes: 2 additions & 2 deletions client/src/services/bms/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -738,7 +738,7 @@ export interface FileData {
}

interface BugReportOptions {
logs?: Array<string>;
logs?: string;
includeScreenshot?: boolean;
files?: Array<FileData>;
}
Expand All @@ -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) {
Expand Down
Loading