@@ -5,7 +5,7 @@ import { reportError, addBreadcrumb } from './errors';
5
5
6
6
import { spawn , ChildProcess } from 'child_process' ;
7
7
import * as os from 'os' ;
8
- import { promises as fs } from 'fs'
8
+ import { promises as fs , createWriteStream , WriteStream } from 'fs'
9
9
import * as net from 'net' ;
10
10
import * as path from 'path' ;
11
11
import { promisify } from 'util' ;
@@ -46,6 +46,7 @@ const APP_PATH = app.getAppPath();
46
46
const RESOURCES_PATH = APP_PATH . endsWith ( 'app.asar' )
47
47
? path . dirname ( APP_PATH ) // If we're bundled, resources are above the bundle
48
48
: APP_PATH ; // Otherwise everything is in the root of the app
49
+ const LOGS_PATH = app . getPath ( 'logs' ) ;
49
50
50
51
// Keep a global reference of the window object, if you don't, the window will
51
52
// be closed automatically when the JavaScript object is garbage collected.
@@ -57,7 +58,7 @@ app.commandLine.appendSwitch('ignore-connections-limit', 'app.httptoolkit.tech')
57
58
app . commandLine . appendSwitch ( 'disable-renderer-backgrounding' ) ;
58
59
app . commandLine . appendSwitch ( 'js-flags' , '--expose-gc' ) ; // Expose window.gc in the UI
59
60
60
- const createWindow = ( ) => {
61
+ const createWindow = ( logStream : WriteStream ) => {
61
62
// Load the previous window state, falling back to defaults
62
63
let windowState = windowStateKeeper ( {
63
64
defaultWidth : 1366 ,
@@ -90,9 +91,19 @@ const createWindow = () => {
90
91
}
91
92
92
93
windows . push ( window ) ;
93
-
94
94
windowState . manage ( window ) ;
95
95
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
+
96
107
window . loadURL ( APP_URL + '?' + querystring . stringify ( {
97
108
authToken : AUTH_TOKEN ,
98
109
desktopVersion : DESKTOP_VERSION
@@ -116,6 +127,8 @@ if (!amMainInstance) {
116
127
console . log ( 'Not the main instance - quitting' ) ;
117
128
app . quit ( ) ;
118
129
} else {
130
+ const logStream = createWriteStream ( path . join ( LOGS_PATH , 'last-run.log' ) ) ;
131
+
119
132
const args = yargs
120
133
. option ( 'with-forwarding' , {
121
134
type : 'string' ,
@@ -146,16 +159,20 @@ if (!amMainInstance) {
146
159
147
160
try {
148
161
await stopServer ( server , AUTH_TOKEN ) ;
149
- // We've done our best - now shut down for real.
150
- app . quit ( ) ;
151
162
} catch ( error ) {
152
163
console . log ( 'Failed to kill server' , error ) ;
153
164
reportError ( error ) ;
165
+ } finally {
166
+ // We've done our best - now shut down for real.
154
167
app . quit ( ) ;
155
168
}
156
169
}
157
170
} ) ;
158
171
172
+ app . on ( 'quit' , ( ) => {
173
+ logStream . close ( ) ; // Explicitly close the logstream, to flush everything to disk.
174
+ } ) ;
175
+
159
176
app . on ( 'web-contents-created' , ( _event , contents ) => {
160
177
function injectValue ( name : string , value : string ) {
161
178
// Set a variable globally, and self-postmessage it too (to ping
@@ -349,18 +366,20 @@ if (!amMainInstance) {
349
366
} ) ;
350
367
351
368
// 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 ! ;
354
371
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 ) ;
357
376
358
377
server . stdout ! . on ( 'data' , ( data ) => {
359
378
addBreadcrumb ( { category : 'server-stdout' , message : data . toString ( 'utf8' ) , level : < any > 'info' } ) ;
360
379
} ) ;
361
380
362
381
let lastError : string | undefined = undefined ;
363
- stderr . on ( 'data' , ( data ) => {
382
+ serverStderr . on ( 'data' , ( data ) => {
364
383
const errorOutput = data . toString ( 'utf8' ) ;
365
384
addBreadcrumb ( { category : 'server-stderr' , message : errorOutput , level : < any > 'warning' } ) ;
366
385
@@ -505,13 +524,13 @@ if (!amMainInstance) {
505
524
506
525
Promise . all ( [ appReady . promise , portCheck ] ) . then ( ( ) => {
507
526
Menu . setApplicationMenu ( getMenu ( windows ) ) ;
508
- createWindow ( ) ;
527
+ createWindow ( logStream ) ;
509
528
} ) ;
510
529
511
530
// We use a single process instance to manage the server, but we
512
531
// do allow multiple windows.
513
532
app . on ( 'second-instance' , ( ) =>
514
- appReady . promise . then ( ( ) => createWindow ( ) )
533
+ appReady . promise . then ( ( ) => createWindow ( logStream ) )
515
534
) ;
516
535
517
536
app . on ( 'activate' , ( ) => {
@@ -520,7 +539,7 @@ if (!amMainInstance) {
520
539
if ( windows . length === 0 ) {
521
540
// Wait until the ready event - it's possible that this can fire
522
541
// before the app is ready (not sure how) in which case things break!
523
- appReady . promise . then ( ( ) => createWindow ( ) ) ;
542
+ appReady . promise . then ( ( ) => createWindow ( logStream ) ) ;
524
543
}
525
544
} ) ;
526
545
0 commit comments