diff --git a/app/ipc/ipc_main.ts b/app/ipc/ipc_main.ts index a1d3c7e5..2abec826 100644 --- a/app/ipc/ipc_main.ts +++ b/app/ipc/ipc_main.ts @@ -6,7 +6,7 @@ import { setMenuBar, showMenuBar, showContextMenu } from '../main_process/menu'; import { sendAll } from '../main_process/windowList'; import { serverInfo } from '../main_process/server'; import { ServerInfo } from '../main_process/types'; -import { logLine, logFilePath, LogLevel, LogSource } from '../src/util/log'; +import { logFilePath } from '../src/util/log'; ipcMain.handle('open-file', (event, options) => { const win = BrowserWindow.fromWebContents(event.sender); @@ -104,8 +104,3 @@ export function exportDebugLog(window: BrowserWindow): void { ipcMain.handle('get-home-path', () => { return app.getPath('home'); }); - -ipcMain.handle('log-line', (_event, source: LogSource, level: LogLevel, ...args: any[]) => { - assertSome(logLine); - logLine(source, level, ...args.map((x) => JSON.stringify(x))); -}); diff --git a/app/main_process/index.ts b/app/main_process/index.ts index 601d4fd1..1a578553 100644 --- a/app/main_process/index.ts +++ b/app/main_process/index.ts @@ -24,6 +24,14 @@ export const createWindow = (): void => { show: false, }); + let dontSendLog = false; + window.webContents.on('console-message', (_e, level, message) => { + if (message == 'server stderr') dontSendLog = true; + logLine && !dontSendLog && logLine(LogSource.RendererProcess, NumericLogLevels[level], message); + + if (message == 'console.groupEnd') dontSendLog = false; + }); + window.webContents.on('new-window', (event, url, frameName, disposition, options) => { if (frameName === 'modal') { event.preventDefault(); @@ -151,4 +159,4 @@ import './server'; import { windowList } from './windowList'; import { applyMenuBar, setMenuBar } from './menu'; import { isRunningInTest } from '../src/util'; -import { initMainProcessLog } from '../src/util/log'; +import { LogSource, NumericLogLevels, initMainProcessLog, logLine } from '../src/util/log'; diff --git a/app/main_process/server.ts b/app/main_process/server.ts index 85b53d45..9137da2e 100644 --- a/app/main_process/server.ts +++ b/app/main_process/server.ts @@ -6,6 +6,7 @@ import { app, dialog } from 'electron'; import { publishServerInfo, publishServerStderr } from '../ipc/ipc_main'; import { ServerInfo } from './types'; import { isRunningInTest } from '../src/util'; +import { LogLevel, LogSource, logLine } from '../src/util/log'; function findServer() { const possibilities = [ @@ -74,7 +75,7 @@ function startServer() { return; } serverProcess.stdout.on('data', (data: Buffer) => { - console.log('server-stdout', data.toString()); + logLine && logLine(LogSource.ServerProcess, LogLevel.Log, data); try { const parsed_data: ServerStartingMessage | ServerStartedMessage = JSON.parse(data.toString()); if (parsed_data.msg == 'server_starting') { @@ -88,7 +89,7 @@ function startServer() { }); serverProcess.stderr.on('data', (data: Buffer) => { - console.log(`server-stderr: \n${data}`); + logLine && logLine(LogSource.ServerProcess, LogLevel.Error, data); publishServerStderr(data.toString()); }); diff --git a/app/scripts/dev.js b/app/scripts/dev.js index 36eee4d9..2e3f5e79 100644 --- a/app/scripts/dev.js +++ b/app/scripts/dev.js @@ -1,14 +1,13 @@ -const { createServer, build, createLogger } = require('vite'); +const { createServer, build } = require('vite'); const electronPath = require('electron'); const { spawn } = require('child_process'); const mode = (process.env.MODE = process.env.MODE || 'development'); -const LOG_LEVEL = 'warn'; const sharedConfig = { mode, build: { watch: {}, }, - logLevel: LOG_LEVEL, + logLevel: 'warn', }; const getWatcher = ({ name, configFile, writeBundle }) => { @@ -29,10 +28,6 @@ const setupMainPackageWatcher = (viteDevServer) => { process.env.VITE_DEV_SERVER_URL = `${protocol}//${host}:${port}${path}`; } - const logger = createLogger(LOG_LEVEL, { - prefix: '[main]', - }); - let spawnProcess = null; return getWatcher({ @@ -44,18 +39,10 @@ const setupMainPackageWatcher = (viteDevServer) => { spawnProcess = null; } - spawnProcess = spawn(String(electronPath), [ - `${dir}/start.cjs.js`, - `--remote-debugging-port=${process.env.DEBUGGER_PORT}`, - ]); - - spawnProcess.stdout.on( - 'data', - (d) => d.toString().trim() && logger.warn(d.toString(), { timestamp: true }) - ); - spawnProcess.stderr.on( - 'data', - (d) => d.toString().trim() && logger.error(d.toString(), { timestamp: true }) + spawnProcess = spawn( + String(electronPath), + [`${dir}/start.cjs.js`, `--remote-debugging-port=${process.env.DEBUGGER_PORT}`], + { stdio: 'inherit' } ); }, }); diff --git a/app/src/index.tsx b/app/src/index.tsx index e8c20ad5..2da3faf1 100644 --- a/app/src/index.tsx +++ b/app/src/index.tsx @@ -4,11 +4,9 @@ import * as ReactDOM from 'react-dom'; import './index.css'; import App from './components/App'; -import { exportDebugLogsToDisk, initRendererLog } from './util/log'; +import { exportDebugLogsToDisk } from './util/log'; import { subscribeExportDebugLog } from '../ipc/ipc_renderer'; -initRendererLog(); - subscribeExportDebugLog((event, mainProcessLogPath) => exportDebugLogsToDisk(mainProcessLogPath)); const anyModule = module as any; diff --git a/app/src/util/log.ts b/app/src/util/log.ts index d243528a..21459ef3 100644 --- a/app/src/util/log.ts +++ b/app/src/util/log.ts @@ -1,29 +1,41 @@ import fs, { createWriteStream } from 'fs'; import path from 'path'; import JSZip from 'jszip'; -import { getHomePath, saveFile, sendLogLine } from '../../ipc/ipc_renderer'; +import { getHomePath, saveFile } from '../../ipc/ipc_renderer'; import { isRunningInTest } from './index'; import glob from 'glob'; import { app } from 'electron'; export enum LogLevel { Log, - Trace, - Debug, Info, Warn, Error, - GroupCollapsed, - GroupEnd, } +export const NumericLogLevels = [LogLevel.Log, LogLevel.Info, LogLevel.Warn, LogLevel.Error]; + export enum LogSource { MainProcess, RendererProcess, + ServerProcess, } export let logFilePath: string | null = null; -let oldLog: ((...args: any[]) => void) | null = null; + +const buffer: string[] = []; +function write(str: string) { + buffer.push(str); + + const try_fn = () => { + if (process.stdout.writableLength == 0) { + process.stdout.write(buffer.shift() || ''); + } else { + setTimeout(try_fn, 10); + } + }; + try_fn(); +} function log(file: number, source: LogSource, level: LogLevel, ...args: any[]) { const date = new Date().toISOString(); @@ -36,7 +48,23 @@ function log(file: number, source: LogSource, level: LogLevel, ...args: any[]) { level: level_str, args: string_args, }); - if (oldLog !== null) oldLog(log_line); + + const FgGreen = '\x1b[32m'; + const FgBlue = '\x1b[34m'; + const FgYellow = '\x1b[33m'; + const Reset = '\x1b[0m'; + const source_color = [FgGreen, FgBlue, FgYellow][source]; + + write( + args + .join('\n') + .split('\n') + .map( + (line) => + `${source_color}[${source_str.substring(0, 4)}]${Reset} ${level_str.padEnd(5)} | ${line}` + ) + .join('\n') + '\n' + ); fs.writeSync(file, log_line + '\n'); fs.fsyncSync(file); } @@ -64,24 +92,15 @@ export function initMainProcessLog(): void { logFilePath = path.join(log_dir, fileName); const file = fs.openSync(logFilePath, 'w'); console.log('Init logging into', logFilePath); - oldLog = console.log; console.log = (...args) => log(file, LogSource.MainProcess, LogLevel.Log, ...args); - console.trace = (...args) => log(file, LogSource.MainProcess, LogLevel.Trace, ...args); - console.debug = (...args) => log(file, LogSource.MainProcess, LogLevel.Debug, ...args); + console.trace = (...args) => log(file, LogSource.MainProcess, LogLevel.Log, ...args); + console.debug = (...args) => log(file, LogSource.MainProcess, LogLevel.Log, ...args); console.info = (...args) => log(file, LogSource.MainProcess, LogLevel.Info, ...args); console.warn = (...args) => log(file, LogSource.MainProcess, LogLevel.Warn, ...args); console.error = (...args) => log(file, LogSource.MainProcess, LogLevel.Error, ...args); logLine = (...args) => log(file, ...args); - const oldGroupCollapsed = console.groupCollapsed; - console.groupCollapsed = (...args) => { - log(file, LogSource.MainProcess, LogLevel.GroupCollapsed, ...args); - oldGroupCollapsed(...args); - }; - const oldGroupEnd = console.groupEnd; - console.groupEnd = (...args) => { - log(file, LogSource.MainProcess, LogLevel.GroupEnd, ...args); - oldGroupEnd(...args); - }; + console.groupCollapsed = () => {}; + console.groupEnd = () => {}; } export async function exportDebugLogsToDisk(file: string): Promise { @@ -108,25 +127,3 @@ export async function exportDebugLogsToDisk(file: string): Promise { .on('error', reject); }); } - -type KeyOfType = keyof { - [P in keyof T as T[P] extends V ? P : never]: any; -}; - -function _mapLogFn(key: KeyOfType void>, level: LogLevel) { - const _oldFn: (...args: any[]) => void = console[key]; - console[key] = (...args: any[]) => { - _oldFn(...args); - sendLogLine(level, ...args); - }; -} -export function initRendererLog(): void { - _mapLogFn('log', LogLevel.Log); - _mapLogFn('trace', LogLevel.Trace); - _mapLogFn('debug', LogLevel.Debug); - _mapLogFn('info', LogLevel.Info); - _mapLogFn('warn', LogLevel.Warn); - _mapLogFn('error', LogLevel.Error); - _mapLogFn('groupCollapsed', LogLevel.GroupCollapsed); - _mapLogFn('groupEnd', LogLevel.GroupEnd); -}