From d952737c42d5acd7b9df2d5f7ad3610d350819ef Mon Sep 17 00:00:00 2001 From: Neal Beeken Date: Fri, 22 Aug 2025 00:00:33 -0400 Subject: [PATCH 1/9] fix(logger): replace PassThrough with Writable for log handling CLOUDP-332732 --- packages/compass-web/src/logger.tsx | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/packages/compass-web/src/logger.tsx b/packages/compass-web/src/logger.tsx index bdffbde7e65..4236a58d09e 100644 --- a/packages/compass-web/src/logger.tsx +++ b/packages/compass-web/src/logger.tsx @@ -1,6 +1,6 @@ import type { Logger } from '@mongodb-js/compass-logging/provider'; import { MongoLogWriter } from 'mongodb-log-writer/mongo-log-writer'; -import { PassThrough } from 'stream'; +import type { Writable } from 'stream'; import { mongoLogId } from '@mongodb-js/compass-logging/provider'; import { useRef } from 'react'; @@ -62,13 +62,17 @@ export class CompassWebLogger implements Logger { }; } ) { - const passThrough = new PassThrough({ objectMode: true }); - this.log = new MongoLogWriter('', '', passThrough).bindComponent( - this.component - ); - passThrough.on('data', (line) => { - callbackRef.current.onLog?.(JSON.parse(line)); - }); + const target = { + write(line: string, callback: () => void) { + callbackRef.current.onLog?.(JSON.parse(line)); + callback(); + }, + end(callback: () => void) { + callback(); + }, + } as Writable; + + this.log = new MongoLogWriter('', '', target).bindComponent(this.component); this.debug = createCompassWebDebugger(this.component, this.callbackRef); } From 075a733ddeff3e27224f28a34fe2df60b07bad25 Mon Sep 17 00:00:00 2001 From: Neal Beeken Date: Fri, 22 Aug 2025 00:00:33 -0400 Subject: [PATCH 2/9] fix(logger): replace PassThrough with Writable for log handling CLOUDP-332732 --- packages/compass-web/src/logger.tsx | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/packages/compass-web/src/logger.tsx b/packages/compass-web/src/logger.tsx index bdffbde7e65..4236a58d09e 100644 --- a/packages/compass-web/src/logger.tsx +++ b/packages/compass-web/src/logger.tsx @@ -1,6 +1,6 @@ import type { Logger } from '@mongodb-js/compass-logging/provider'; import { MongoLogWriter } from 'mongodb-log-writer/mongo-log-writer'; -import { PassThrough } from 'stream'; +import type { Writable } from 'stream'; import { mongoLogId } from '@mongodb-js/compass-logging/provider'; import { useRef } from 'react'; @@ -62,13 +62,17 @@ export class CompassWebLogger implements Logger { }; } ) { - const passThrough = new PassThrough({ objectMode: true }); - this.log = new MongoLogWriter('', '', passThrough).bindComponent( - this.component - ); - passThrough.on('data', (line) => { - callbackRef.current.onLog?.(JSON.parse(line)); - }); + const target = { + write(line: string, callback: () => void) { + callbackRef.current.onLog?.(JSON.parse(line)); + callback(); + }, + end(callback: () => void) { + callback(); + }, + } as Writable; + + this.log = new MongoLogWriter('', '', target).bindComponent(this.component); this.debug = createCompassWebDebugger(this.component, this.callbackRef); } From 533f97a0fcbcd8de546243be19b6d65db0ca6097 Mon Sep 17 00:00:00 2001 From: Neal Beeken Date: Fri, 22 Aug 2025 15:19:20 -0400 Subject: [PATCH 3/9] test: synchronous log call --- packages/compass-web/src/logger.spec.tsx | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/packages/compass-web/src/logger.spec.tsx b/packages/compass-web/src/logger.spec.tsx index fbc3eff611b..1d060a56e26 100644 --- a/packages/compass-web/src/logger.spec.tsx +++ b/packages/compass-web/src/logger.spec.tsx @@ -59,4 +59,25 @@ describe('useCompassWebLogger', function () { }, ]); }); + + it('should call onLog hook synchronously', function () { + let callbackExecuted = false; + const onLog = Sinon.stub().callsFake(() => { + callbackExecuted = true; + }); + + const { + result: { current: logger }, + } = renderLoggerHook({ onLog }); + + // Callback should not have been called yet + expect(callbackExecuted).to.be.false; + + // Call the logger + logger.log.info(mongoLogId(456), 'Test', 'sync test'); + + // Callback should have been called synchronously before this assertion + expect(callbackExecuted).to.be.true; + expect(onLog).to.have.been.calledOnce; + }); }); From f039277c572c530f669ff00eec693b20167ad847 Mon Sep 17 00:00:00 2001 From: Simon Zhu Date: Fri, 22 Aug 2025 18:05:41 -0400 Subject: [PATCH 4/9] add events --- .../src/stores/connections-store-redux.ts | 16 ++++++- packages/data-service/src/data-service.ts | 46 ++++++++++++++++++- 2 files changed, 59 insertions(+), 3 deletions(-) diff --git a/packages/compass-connections/src/stores/connections-store-redux.ts b/packages/compass-connections/src/stores/connections-store-redux.ts index eeb259f906f..af19e34abb1 100644 --- a/packages/compass-connections/src/stores/connections-store-redux.ts +++ b/packages/compass-connections/src/stores/connections-store-redux.ts @@ -1581,7 +1581,11 @@ const connectWithOptions = ( mongoLogId(1_001_000_004), 'Connection UI', 'Initiating connection attempt', - { isAutoconnectAttempt } + { + isAutoconnectAttempt, + clusterName: connectionInfo.atlasMetadata?.clusterName, + connectionId: connectionInfo.id, + } ); // Connection form allows to start connecting with invalid connection @@ -1821,6 +1825,16 @@ const connectWithOptions = ( connectionInfo ); + log.info( + mongoLogId(1_001_000_006), + 'Compass Connection Attempt Succeeded', + 'Connection attempt succeeded', + { + clusterName: connectionInfo.atlasMetadata?.clusterName, + connectionId: connectionInfo.id, + } + ); + connectionProgress.openConnectionSucceededToast(connectionInfo); // Emit before changing state because some plugins rely on this diff --git a/packages/data-service/src/data-service.ts b/packages/data-service/src/data-service.ts index b0d9e87ad73..346ed7eead6 100644 --- a/packages/data-service/src/data-service.ts +++ b/packages/data-service/src/data-service.ts @@ -53,6 +53,8 @@ import type { ClientEncryptionCreateDataKeyProviderOptions, SearchIndexDescription, ReadPreferenceMode, + CommandStartedEvent, + ConnectionCreatedEvent, } from 'mongodb'; import { ReadPreference } from 'mongodb'; import ConnectionStringUrl from 'mongodb-connection-string-url'; @@ -1605,6 +1607,7 @@ class DataServiceImpl extends WithLogContext implements DataService { this._isConnecting = true; this._logger.info(mongoLogId(1_001_000_014), 'Connecting Started', { + clusterName: this._connectionOptions.lookup?.().clusterName, connectionId: this._id, url: redactConnectionString(this._connectionOptions.connectionString), csfle: this._csfleLogInformation(this._connectionOptions.fleOptions), @@ -1626,6 +1629,7 @@ class DataServiceImpl extends WithLogContext implements DataService { const attr = { connectionId: this._id, + clusterName: this._connectionOptions.lookup?.().clusterName, isWritable: this.isWritable(), isMongos: this.isMongos(), }; @@ -1660,6 +1664,7 @@ class DataServiceImpl extends WithLogContext implements DataService { } catch (error) { this._logger.info(mongoLogId(1_001_000_359), 'Connecting Failed', { connectionId: this._id, + clusterName: this._connectionOptions.lookup?.().clusterName, error: error && typeof error === 'object' && 'message' in error ? error?.message @@ -2474,6 +2479,18 @@ class DataServiceImpl extends WithLogContext implements DataService { private _setupListeners(client: MongoClient): void { if (client) { + client.on('connectionCreated', (evt: ConnectionCreatedEvent) => { + const { address, connectionId } = evt; + this._logger.info( + mongoLogId(1_001_000_027), + 'Driver connection created', + { + address, + serverConnectionId: connectionId, + } + ); + }); + client.on( 'serverDescriptionChanged', (evt: ServerDescriptionChangedEvent) => { @@ -2595,13 +2612,30 @@ class DataServiceImpl extends WithLogContext implements DataService { this._emitter.emit('serverHeartbeatFailed', evt); }); + client.on('commandStarted', (evt: CommandStartedEvent) => { + const { address, connectionId, requestId, commandName, databaseName } = + evt; + this._logger.debug( + mongoLogId(1_001_000_028), + 'Driver command started', + { + address, + databaseName, + serverConnectionId: connectionId, + requestId, + commandName, + } + ); + }); + client.on('commandSucceeded', (evt: CommandSucceededEvent) => { - const { address, connectionId, duration, commandName } = evt; + const { address, connectionId, duration, requestId, commandName } = evt; this._logger.debug( mongoLogId(1_001_000_029), 'Driver command succeeded', { address, + requestId, serverConnectionId: connectionId, duration, commandName, @@ -2610,11 +2644,19 @@ class DataServiceImpl extends WithLogContext implements DataService { }); client.on('commandFailed', (evt: CommandFailedEvent) => { - const { address, connectionId, duration, commandName, failure } = evt; + const { + address, + connectionId, + duration, + requestId, + commandName, + failure, + } = evt; this._logger.debug(mongoLogId(1_001_000_030), 'Driver command failed', { address, serverConnectionId: connectionId, duration, + requestId, commandName, failure: failure.message, }); From 05dd5e51f7c5e968420054169242136c2b39ae95 Mon Sep 17 00:00:00 2001 From: Simon Zhu Date: Mon, 25 Aug 2025 01:25:19 -0700 Subject: [PATCH 5/9] add more logs --- .../src/stores/connections-store-redux.ts | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/packages/compass-connections/src/stores/connections-store-redux.ts b/packages/compass-connections/src/stores/connections-store-redux.ts index af19e34abb1..6972e851708 100644 --- a/packages/compass-connections/src/stores/connections-store-redux.ts +++ b/packages/compass-connections/src/stores/connections-store-redux.ts @@ -1521,6 +1521,9 @@ const connectWithOptions = ( inflightConnection = (async () => { const deviceAuthAbortController = new AbortController(); + let cancelled = false; + let started = false; + let succeeded = false; try { if ( getCurrentConnectionStatus(getState(), connectionInfo.id) === @@ -1639,6 +1642,17 @@ const connectWithOptions = ( ); } + started = true; + log.info( + mongoLogId(1_001_000_005), + 'Compass Connection Attempt Started', + 'Connection attempt started', + { + clusterName: connectionInfo.atlasMetadata?.clusterName, + connectionId: connectionInfo.id, + } + ); + const connectionAttempt = createConnectionAttempt({ logger: log.unbound, proxyOptions: proxyPreferenceToProxyOptions( @@ -1659,6 +1673,16 @@ const connectWithOptions = ( // This is how connection attempt indicates that the connection was // aborted if (!dataService || connectionAttempt.isClosed()) { + cancelled = true; + log.info( + mongoLogId(1_001_000_007), + 'Compass Connection Attempt Cancelled', + 'Connection attempt cancelled', + { + clusterName: connectionInfo.atlasMetadata?.clusterName, + connectionId: connectionInfo.id, + } + ); dispatch({ type: ActionTypes.ConnectionAttemptCancelled, connectionId: connectionInfo.id, @@ -1825,6 +1849,7 @@ const connectWithOptions = ( connectionInfo ); + succeeded = true; log.info( mongoLogId(1_001_000_006), 'Compass Connection Attempt Succeeded', @@ -1870,6 +1895,18 @@ const connectWithOptions = ( ); } } catch (err) { + if (started && !succeeded && !cancelled) { + log.info( + mongoLogId(1_001_000_008), + 'Compass Connection Attempt Failed', + 'Connection attempt failed', + { + clusterName: connectionInfo.atlasMetadata?.clusterName, + connectionId: connectionInfo.id, + error: (err as Error).message, + } + ); + } dispatch(connectionAttemptError(connectionInfo, err)); } finally { deviceAuthAbortController.abort(); From 43838ce3f8ffbd80b532726b5de031b77f6c5907 Mon Sep 17 00:00:00 2001 From: Simon Zhu Date: Mon, 25 Aug 2025 15:24:51 -0700 Subject: [PATCH 6/9] remoce fields --- .../src/stores/connections-store-redux.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/packages/compass-connections/src/stores/connections-store-redux.ts b/packages/compass-connections/src/stores/connections-store-redux.ts index 6972e851708..79ba53fdea7 100644 --- a/packages/compass-connections/src/stores/connections-store-redux.ts +++ b/packages/compass-connections/src/stores/connections-store-redux.ts @@ -1584,11 +1584,7 @@ const connectWithOptions = ( mongoLogId(1_001_000_004), 'Connection UI', 'Initiating connection attempt', - { - isAutoconnectAttempt, - clusterName: connectionInfo.atlasMetadata?.clusterName, - connectionId: connectionInfo.id, - } + { isAutoconnectAttempt } ); // Connection form allows to start connecting with invalid connection From 2e3cb29fc15795f11071b5bafa2d72c1ec699689 Mon Sep 17 00:00:00 2001 From: Simon Zhu Date: Mon, 25 Aug 2025 17:21:14 -0700 Subject: [PATCH 7/9] fix test --- .../src/stores/connections-store-redux.ts | 3 +++ packages/data-service/src/data-service.spec.ts | 7 ++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/compass-connections/src/stores/connections-store-redux.ts b/packages/compass-connections/src/stores/connections-store-redux.ts index 79ba53fdea7..1eb08ec1a7e 100644 --- a/packages/compass-connections/src/stores/connections-store-redux.ts +++ b/packages/compass-connections/src/stores/connections-store-redux.ts @@ -1639,6 +1639,7 @@ const connectWithOptions = ( } started = true; + // This is used for Data Explorer connection latency tracing log.info( mongoLogId(1_001_000_005), 'Compass Connection Attempt Started', @@ -1670,6 +1671,7 @@ const connectWithOptions = ( // aborted if (!dataService || connectionAttempt.isClosed()) { cancelled = true; + // This is used for Data Explorer connection latency tracing log.info( mongoLogId(1_001_000_007), 'Compass Connection Attempt Cancelled', @@ -1846,6 +1848,7 @@ const connectWithOptions = ( ); succeeded = true; + // This is used for Data Explorer connection latency tracing log.info( mongoLogId(1_001_000_006), 'Compass Connection Attempt Succeeded', diff --git a/packages/data-service/src/data-service.spec.ts b/packages/data-service/src/data-service.spec.ts index 581c0ff7a89..07634e35e11 100644 --- a/packages/data-service/src/data-service.spec.ts +++ b/packages/data-service/src/data-service.spec.ts @@ -167,9 +167,10 @@ describe('DataService', function () { { connectionString: 'mongodb://iLoveJavascript?serverSelectionTimeoutMS=5', - lookup: () => { - throw new Error('test error'); - }, + lookup: () => ({ + wsURL: 'ws://localhost:12345/mongodb/atlas/websocket', + clusterName: 'iLoveJavascript', + }), }, logCollector ); From f24620dd948b68ea73f790ad5d3b3fb67939f43e Mon Sep 17 00:00:00 2001 From: Simon Zhu Date: Mon, 25 Aug 2025 17:59:55 -0700 Subject: [PATCH 8/9] fix logging test --- packages/data-service/src/data-service.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/data-service/src/data-service.ts b/packages/data-service/src/data-service.ts index 346ed7eead6..d63b2d78d89 100644 --- a/packages/data-service/src/data-service.ts +++ b/packages/data-service/src/data-service.ts @@ -1606,11 +1606,12 @@ class DataServiceImpl extends WithLogContext implements DataService { debug('connecting...'); this._isConnecting = true; + const clusterName = this._connectionOptions.lookup?.().clusterName; this._logger.info(mongoLogId(1_001_000_014), 'Connecting Started', { - clusterName: this._connectionOptions.lookup?.().clusterName, connectionId: this._id, url: redactConnectionString(this._connectionOptions.connectionString), csfle: this._csfleLogInformation(this._connectionOptions.fleOptions), + ...(clusterName && { clusterName }), }); try { @@ -1629,9 +1630,9 @@ class DataServiceImpl extends WithLogContext implements DataService { const attr = { connectionId: this._id, - clusterName: this._connectionOptions.lookup?.().clusterName, isWritable: this.isWritable(), isMongos: this.isMongos(), + ...(clusterName && { clusterName }), }; this._logger.info( @@ -1664,11 +1665,11 @@ class DataServiceImpl extends WithLogContext implements DataService { } catch (error) { this._logger.info(mongoLogId(1_001_000_359), 'Connecting Failed', { connectionId: this._id, - clusterName: this._connectionOptions.lookup?.().clusterName, error: error && typeof error === 'object' && 'message' in error ? error?.message : 'unknown error', + ...(clusterName && { clusterName }), }); throw error; } finally { From bc4b214431c7092e08fdc3bf51249ed15501dcf5 Mon Sep 17 00:00:00 2001 From: Simon Zhu Date: Mon, 25 Aug 2025 18:35:10 -0700 Subject: [PATCH 9/9] remove flags --- .../src/stores/connections-store-redux.ts | 28 +++++++------------ 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/packages/compass-connections/src/stores/connections-store-redux.ts b/packages/compass-connections/src/stores/connections-store-redux.ts index 1eb08ec1a7e..0bf61e99845 100644 --- a/packages/compass-connections/src/stores/connections-store-redux.ts +++ b/packages/compass-connections/src/stores/connections-store-redux.ts @@ -1521,9 +1521,6 @@ const connectWithOptions = ( inflightConnection = (async () => { const deviceAuthAbortController = new AbortController(); - let cancelled = false; - let started = false; - let succeeded = false; try { if ( getCurrentConnectionStatus(getState(), connectionInfo.id) === @@ -1638,7 +1635,6 @@ const connectWithOptions = ( ); } - started = true; // This is used for Data Explorer connection latency tracing log.info( mongoLogId(1_001_000_005), @@ -1670,7 +1666,6 @@ const connectWithOptions = ( // This is how connection attempt indicates that the connection was // aborted if (!dataService || connectionAttempt.isClosed()) { - cancelled = true; // This is used for Data Explorer connection latency tracing log.info( mongoLogId(1_001_000_007), @@ -1847,7 +1842,6 @@ const connectWithOptions = ( connectionInfo ); - succeeded = true; // This is used for Data Explorer connection latency tracing log.info( mongoLogId(1_001_000_006), @@ -1894,18 +1888,16 @@ const connectWithOptions = ( ); } } catch (err) { - if (started && !succeeded && !cancelled) { - log.info( - mongoLogId(1_001_000_008), - 'Compass Connection Attempt Failed', - 'Connection attempt failed', - { - clusterName: connectionInfo.atlasMetadata?.clusterName, - connectionId: connectionInfo.id, - error: (err as Error).message, - } - ); - } + log.info( + mongoLogId(1_001_000_008), + 'Compass Connection Attempt Failed', + 'Connection attempt failed', + { + clusterName: connectionInfo.atlasMetadata?.clusterName, + connectionId: connectionInfo.id, + error: (err as Error).message, + } + ); dispatch(connectionAttemptError(connectionInfo, err)); } finally { deviceAuthAbortController.abort();