@@ -5,7 +5,7 @@ import { reportError, addBreadcrumb } from './errors';
55
66import { spawn , ChildProcess } from 'child_process' ;
77import * as os from 'os' ;
8- import { promises as fs } from 'fs'
8+ import { promises as fs , createWriteStream , WriteStream } from 'fs'
99import * as net from 'net' ;
1010import * as path from 'path' ;
1111import { promisify } from 'util' ;
@@ -46,6 +46,7 @@ const APP_PATH = app.getAppPath();
4646const 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')
5758app . commandLine . appendSwitch ( 'disable-renderer-backgrounding' ) ;
5859app . 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