Skip to content

Commit ee56dd4

Browse files
committed
Log all browser and server output to a last-run logfile on disk
1 parent 68786f3 commit ee56dd4

File tree

1 file changed

+32
-13
lines changed

1 file changed

+32
-13
lines changed

src/index.ts

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { reportError, addBreadcrumb } from './errors';
55

66
import { spawn, ChildProcess } from 'child_process';
77
import * as os from 'os';
8-
import { promises as fs } from 'fs'
8+
import { promises as fs, createWriteStream, WriteStream } from 'fs'
99
import * as net from 'net';
1010
import * as path from 'path';
1111
import { promisify } from 'util';
@@ -46,6 +46,7 @@ const APP_PATH = app.getAppPath();
4646
const RESOURCES_PATH = APP_PATH.endsWith('app.asar')
4747
? path.dirname(APP_PATH) // If we're bundled, resources are above the bundle
4848
: APP_PATH; // Otherwise everything is in the root of the app
49+
const LOGS_PATH = app.getPath('logs');
4950

5051
// Keep a global reference of the window object, if you don't, the window will
5152
// be closed automatically when the JavaScript object is garbage collected.
@@ -57,7 +58,7 @@ app.commandLine.appendSwitch('ignore-connections-limit', 'app.httptoolkit.tech')
5758
app.commandLine.appendSwitch('disable-renderer-backgrounding');
5859
app.commandLine.appendSwitch('js-flags', '--expose-gc'); // Expose window.gc in the UI
5960

60-
const createWindow = () => {
61+
const createWindow = (logStream: WriteStream) => {
6162
// Load the previous window state, falling back to defaults
6263
let windowState = windowStateKeeper({
6364
defaultWidth: 1366,
@@ -90,9 +91,19 @@ const createWindow = () => {
9091
}
9192

9293
windows.push(window);
93-
9494
windowState.manage(window);
9595

96+
// Stream renderer console output directly into our log file:
97+
window.webContents.on('console-message', (_event, level, message) => {
98+
const levelName = [
99+
'VERBOSE',
100+
'INFO',
101+
'WARN',
102+
'ERROR'
103+
][level];
104+
logStream.write(`${levelName}: ${message}\n`);
105+
});
106+
96107
window.loadURL(APP_URL + '?' + querystring.stringify({
97108
authToken: AUTH_TOKEN,
98109
desktopVersion: DESKTOP_VERSION
@@ -116,6 +127,8 @@ if (!amMainInstance) {
116127
console.log('Not the main instance - quitting');
117128
app.quit();
118129
} else {
130+
const logStream = createWriteStream(path.join(LOGS_PATH, 'last-run.log'));
131+
119132
const args = yargs
120133
.option('with-forwarding', {
121134
type: 'string',
@@ -146,16 +159,20 @@ if (!amMainInstance) {
146159

147160
try {
148161
await stopServer(server, AUTH_TOKEN);
149-
// We've done our best - now shut down for real.
150-
app.quit();
151162
} catch (error) {
152163
console.log('Failed to kill server', error);
153164
reportError(error);
165+
} finally {
166+
// We've done our best - now shut down for real.
154167
app.quit();
155168
}
156169
}
157170
});
158171

172+
app.on('quit', () => {
173+
logStream.close(); // Explicitly close the logstream, to flush everything to disk.
174+
});
175+
159176
app.on('web-contents-created', (_event, contents) => {
160177
function injectValue(name: string, value: string) {
161178
// Set a variable globally, and self-postmessage it too (to ping
@@ -349,18 +366,20 @@ if (!amMainInstance) {
349366
});
350367

351368
// Both not null because we pass 'pipe' for args 2 & 3 above.
352-
const stdout = server.stdout!;
353-
const stderr = server.stderr!;
369+
const serverStdout = server.stdout!;
370+
const serverStderr = server.stderr!;
354371

355-
stdout.pipe(process.stdout);
356-
stderr.pipe(process.stderr);
372+
serverStdout.pipe(process.stdout);
373+
serverStderr.pipe(process.stderr);
374+
serverStdout.pipe(logStream);
375+
serverStderr.pipe(logStream);
357376

358377
server.stdout!.on('data', (data) => {
359378
addBreadcrumb({ category: 'server-stdout', message: data.toString('utf8'), level: <any>'info' });
360379
});
361380

362381
let lastError: string | undefined = undefined;
363-
stderr.on('data', (data) => {
382+
serverStderr.on('data', (data) => {
364383
const errorOutput = data.toString('utf8');
365384
addBreadcrumb({ category: 'server-stderr', message: errorOutput, level: <any>'warning' });
366385

@@ -505,13 +524,13 @@ if (!amMainInstance) {
505524

506525
Promise.all([appReady.promise, portCheck]).then(() => {
507526
Menu.setApplicationMenu(getMenu(windows));
508-
createWindow();
527+
createWindow(logStream);
509528
});
510529

511530
// We use a single process instance to manage the server, but we
512531
// do allow multiple windows.
513532
app.on('second-instance', () =>
514-
appReady.promise.then(() => createWindow())
533+
appReady.promise.then(() => createWindow(logStream))
515534
);
516535

517536
app.on('activate', () => {
@@ -520,7 +539,7 @@ if (!amMainInstance) {
520539
if (windows.length === 0) {
521540
// Wait until the ready event - it's possible that this can fire
522541
// before the app is ready (not sure how) in which case things break!
523-
appReady.promise.then(() => createWindow());
542+
appReady.promise.then(() => createWindow(logStream));
524543
}
525544
});
526545

0 commit comments

Comments
 (0)