@@ -18,7 +18,7 @@ import {
1818import {
1919 expect ,
2020 fakeTTYProps ,
21- readReplLogfile ,
21+ readReplLogFile ,
2222 tick ,
2323 useTmpdir ,
2424 waitBus ,
@@ -31,6 +31,9 @@ import { CliRepl } from './cli-repl';
3131import { CliReplErrors } from './error-codes' ;
3232import type { DevtoolsConnectOptions } from '@mongosh/service-provider-node-driver' ;
3333import type { AddressInfo } from 'net' ;
34+ import sinon from 'sinon' ;
35+ import type { CliUserConfig } from '@mongosh/types' ;
36+ import { MongoLogWriter , MongoLogManager } from 'mongodb-log-writer' ;
3437const { EJSON } = bson ;
3538
3639const delay = promisify ( setTimeout ) ;
@@ -53,7 +56,7 @@ describe('CliRepl', function () {
5356 async function log ( ) : Promise < any [ ] > {
5457 if ( ! cliRepl . logWriter ?. logFilePath ) return [ ] ;
5558 await cliRepl . logWriter . flush ( ) ; // Ensure any pending data is written first
56- return readReplLogfile ( cliRepl . logWriter . logFilePath ) ;
59+ return readReplLogFile ( cliRepl . logWriter . logFilePath ) ;
5760 }
5861
5962 async function startWithExpectedImmediateExit (
@@ -235,6 +238,27 @@ describe('CliRepl', function () {
235238 } ) ;
236239 } ) ;
237240
241+ it ( 'does not write to log syntax errors if logging is disabled' , async function ( ) {
242+ expect (
243+ ( await log ( ) ) . filter ( ( entry ) =>
244+ entry . attr ?. stack ?. startsWith ( 'SyntaxError:' )
245+ )
246+ ) . to . have . lengthOf ( 0 ) ;
247+ input . write ( 'config.set("disableLogging", true)\n' ) ;
248+ await waitEval ( cliRepl . bus ) ;
249+ expect ( output ) . includes ( 'Setting "disableLogging" has been changed' ) ;
250+
251+ input . write ( '<cat>\n' ) ;
252+ await waitBus ( cliRepl . bus , 'mongosh:error' ) ;
253+ await eventually ( async ( ) => {
254+ expect (
255+ ( await log ( ) ) . filter ( ( entry ) =>
256+ entry . attr ?. stack ?. startsWith ( 'SyntaxError:' )
257+ )
258+ ) . to . have . lengthOf ( 0 ) ;
259+ } ) ;
260+ } ) ;
261+
238262 it ( 'writes JS errors to the log file' , async function ( ) {
239263 input . write ( 'throw new Error("plain js error")\n' ) ;
240264 await waitBus ( cliRepl . bus , 'mongosh:error' ) ;
@@ -297,7 +321,8 @@ describe('CliRepl', function () {
297321 'oidcTrustedEndpoints' ,
298322 'browser' ,
299323 'updateURL' ,
300- ] ) ;
324+ 'disableLogging' ,
325+ ] satisfies ( keyof CliUserConfig ) [ ] ) ;
301326 } ) ;
302327
303328 it ( 'fails when trying to overwrite mongosh-owned config settings' , async function ( ) {
@@ -453,12 +478,14 @@ describe('CliRepl', function () {
453478 cliRepl = new CliRepl ( cliReplOptions ) ;
454479 await cliRepl . start ( '' , { } ) ;
455480 await fs . stat ( newerlogfile ) ;
456- try {
457- await fs . stat ( oldlogfile ) ;
458- expect . fail ( 'missed exception' ) ;
459- } catch ( err : any ) {
460- expect ( err . code ) . to . equal ( 'ENOENT' ) ;
461- }
481+ await eventually ( async ( ) => {
482+ try {
483+ await fs . stat ( oldlogfile ) ;
484+ expect . fail ( 'missed exception' ) ;
485+ } catch ( err : any ) {
486+ expect ( err . code ) . to . equal ( 'ENOENT' ) ;
487+ }
488+ } ) ;
462489 } ) ;
463490
464491 it ( 'verifies the Node.js version' , async function ( ) {
@@ -1309,7 +1336,6 @@ describe('CliRepl', function () {
13091336 hasCollectionNames : true ,
13101337 hasDatabaseNames : true ,
13111338 } ) ;
1312-
13131339 context ( 'analytics integration' , function ( ) {
13141340 context ( 'with network connectivity' , function ( ) {
13151341 let srv : http . Server ;
@@ -1333,6 +1359,7 @@ describe('CliRepl', function () {
13331359 . on ( 'data' , ( chunk ) => {
13341360 body += chunk ;
13351361 } )
1362+ // eslint-disable-next-line @typescript-eslint/no-misused-promises
13361363 . on ( 'end' , async ( ) => {
13371364 requests . push ( { req, body } ) ;
13381365 totalEventsTracked += JSON . parse ( body ) . batch . length ;
@@ -1343,7 +1370,7 @@ describe('CliRepl', function () {
13431370 } )
13441371 . listen ( 0 ) ;
13451372 await once ( srv , 'listening' ) ;
1346- host = `http://localhost:${ ( srv . address ( ) as any ) . port } ` ;
1373+ host = `http://localhost:${ ( srv . address ( ) as AddressInfo ) . port } ` ;
13471374 cliReplOptions . analyticsOptions = {
13481375 host,
13491376 apiKey : '🔑' ,
@@ -1357,6 +1384,48 @@ describe('CliRepl', function () {
13571384 srv . close ( ) ;
13581385 await once ( srv , 'close' ) ;
13591386 setTelemetryDelay ( 0 ) ;
1387+ sinon . restore ( ) ;
1388+ } ) ;
1389+
1390+ context ( 'logging configuration' , function ( ) {
1391+ it ( 'logging is enabled by default and event is called' , async function ( ) {
1392+ const onLogInitialized = sinon . stub ( ) ;
1393+ cliRepl . bus . on ( 'mongosh:log-initialized' , onLogInitialized ) ;
1394+
1395+ await cliRepl . start ( await testServer . connectionString ( ) , { } ) ;
1396+
1397+ expect ( await cliRepl . getConfig ( 'disableLogging' ) ) . is . false ;
1398+
1399+ expect ( onLogInitialized ) . calledOnce ;
1400+ expect ( cliRepl . logWriter ) . is . instanceOf ( MongoLogWriter ) ;
1401+ } ) ;
1402+
1403+ it ( 'does not initialize logging when it is disabled' , async function ( ) {
1404+ cliRepl . config . disableLogging = true ;
1405+ const onLogInitialized = sinon . stub ( ) ;
1406+ cliRepl . bus . on ( 'mongosh:log-initialized' , onLogInitialized ) ;
1407+
1408+ await cliRepl . start ( await testServer . connectionString ( ) , { } ) ;
1409+
1410+ expect ( await cliRepl . getConfig ( 'disableLogging' ) ) . is . true ;
1411+ expect ( onLogInitialized ) . not . called ;
1412+
1413+ expect ( cliRepl . logWriter ) . is . undefined ;
1414+ } ) ;
1415+
1416+ it ( 'logs cleanup errors' , async function ( ) {
1417+ sinon
1418+ . stub ( MongoLogManager . prototype , 'cleanupOldLogFiles' )
1419+ . rejects ( new Error ( 'Method not implemented' ) ) ;
1420+ await cliRepl . start ( await testServer . connectionString ( ) , { } ) ;
1421+ expect (
1422+ ( await log ( ) ) . filter (
1423+ ( entry ) =>
1424+ entry . ctx === 'log' &&
1425+ entry . msg === 'Error: Method not implemented'
1426+ )
1427+ ) . to . have . lengthOf ( 1 ) ;
1428+ } ) ;
13601429 } ) ;
13611430
13621431 it ( 'times out fast' , async function ( ) {
@@ -1507,11 +1576,11 @@ describe('CliRepl', function () {
15071576
15081577 it ( 'includes a statement about flushed telemetry in the log' , async function ( ) {
15091578 await cliRepl . start ( await testServer . connectionString ( ) , { } ) ;
1510- const { logFilePath } = cliRepl . logWriter ! ;
1579+ const { logFilePath } = cliRepl . logWriter as MongoLogWriter ;
15111580 input . write ( 'db.hello()\n' ) ;
15121581 input . write ( 'exit\n' ) ;
15131582 await waitBus ( cliRepl . bus , 'mongosh:closed' ) ;
1514- const flushEntry = ( await readReplLogfile ( logFilePath ) ) . find (
1583+ const flushEntry = ( await readReplLogFile ( logFilePath ) ) . find (
15151584 ( entry : any ) => entry . id === 1_000_000_045
15161585 ) ;
15171586 expect ( flushEntry . attr . flushError ) . to . equal ( null ) ;
0 commit comments