Skip to content

Commit bb5fa43

Browse files
feat(NODE-5452): Logging Cosmos Document DB Info Message (#3902)
Co-authored-by: Durran Jordan <[email protected]>
1 parent 1c3dc02 commit bb5fa43

File tree

6 files changed

+108
-2
lines changed

6 files changed

+108
-2
lines changed

src/connection_string.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -523,6 +523,7 @@ export function parseOptions(
523523
MONGODB_LOG_TOPOLOGY: process.env.MONGODB_LOG_TOPOLOGY,
524524
MONGODB_LOG_SERVER_SELECTION: process.env.MONGODB_LOG_SERVER_SELECTION,
525525
MONGODB_LOG_CONNECTION: process.env.MONGODB_LOG_CONNECTION,
526+
MONGODB_LOG_CLIENT: process.env.MONGODB_LOG_CLIENT,
526527
MONGODB_LOG_ALL: process.env.MONGODB_LOG_ALL,
527528
MONGODB_LOG_MAX_DOCUMENT_LENGTH: process.env.MONGODB_LOG_MAX_DOCUMENT_LENGTH,
528529
MONGODB_LOG_PATH: process.env.MONGODB_LOG_PATH,

src/mongo_client.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,13 @@ import type { SrvPoller } from './sdam/srv_polling';
3333
import { Topology, type TopologyEvents } from './sdam/topology';
3434
import { ClientSession, type ClientSessionOptions, ServerSessionPool } from './sessions';
3535
import {
36+
COSMOS_DB_CHECK,
37+
COSMOS_DB_MSG,
38+
DOCUMENT_DB_CHECK,
39+
DOCUMENT_DB_MSG,
3640
type HostAddress,
3741
hostMatchesWildcards,
42+
isHostMatch,
3843
type MongoDBNamespace,
3944
ns,
4045
resolveOptions
@@ -364,6 +369,26 @@ export class MongoClient extends TypedEventEmitter<MongoClientEvents> {
364369
return true;
365370
}
366371
};
372+
this.checkForNonGenuineHosts();
373+
}
374+
375+
/** @internal */
376+
private checkForNonGenuineHosts() {
377+
const documentDBHostnames = this[kOptions].hosts.filter((hostAddress: HostAddress) =>
378+
isHostMatch(DOCUMENT_DB_CHECK, hostAddress.host)
379+
);
380+
const srvHostIsDocumentDB = isHostMatch(DOCUMENT_DB_CHECK, this[kOptions].srvHost);
381+
382+
const cosmosDBHostnames = this[kOptions].hosts.filter((hostAddress: HostAddress) =>
383+
isHostMatch(COSMOS_DB_CHECK, hostAddress.host)
384+
);
385+
const srvHostIsCosmosDB = isHostMatch(COSMOS_DB_CHECK, this[kOptions].srvHost);
386+
387+
if (documentDBHostnames.length !== 0 || srvHostIsDocumentDB) {
388+
this.mongoLogger.info('client', DOCUMENT_DB_MSG);
389+
} else if (cosmosDBHostnames.length !== 0 || srvHostIsCosmosDB) {
390+
this.mongoLogger.info('client', COSMOS_DB_MSG);
391+
}
367392
}
368393

369394
/** @see MongoOptions */

src/mongo_logger.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,8 @@ export const MongoLoggableComponent = Object.freeze({
9898
COMMAND: 'command',
9999
TOPOLOGY: 'topology',
100100
SERVER_SELECTION: 'serverSelection',
101-
CONNECTION: 'connection'
101+
CONNECTION: 'connection',
102+
CLIENT: 'client'
102103
} as const);
103104

104105
/** @internal */
@@ -115,6 +116,8 @@ export interface MongoLoggerEnvOptions {
115116
MONGODB_LOG_SERVER_SELECTION?: string;
116117
/** Severity level for CMAP */
117118
MONGODB_LOG_CONNECTION?: string;
119+
/** Severity level for client */
120+
MONGODB_LOG_CLIENT?: string;
118121
/** Default severity level to be if any of the above are unset */
119122
MONGODB_LOG_ALL?: string;
120123
/** Max length of embedded EJSON docs. Setting to 0 disables truncation. Defaults to 1000. */
@@ -140,6 +143,8 @@ export interface MongoLoggerOptions {
140143
serverSelection: SeverityLevel;
141144
/** Severity level for connection component */
142145
connection: SeverityLevel;
146+
/** Severity level for client component */
147+
client: SeverityLevel;
143148
/** Default severity level to be used if any of the above are unset */
144149
default: SeverityLevel;
145150
};
@@ -528,6 +533,7 @@ export class MongoLogger {
528533
parseSeverityFromString(combinedOptions.MONGODB_LOG_SERVER_SELECTION) ?? defaultSeverity,
529534
connection:
530535
parseSeverityFromString(combinedOptions.MONGODB_LOG_CONNECTION) ?? defaultSeverity,
536+
client: parseSeverityFromString(combinedOptions.MONGODB_LOG_CLIENT) ?? defaultSeverity,
531537
default: defaultSeverity
532538
},
533539
maxDocumentLength:

src/utils.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1282,3 +1282,20 @@ export class TimeoutController extends AbortController {
12821282
this.timeoutId = null;
12831283
}
12841284
}
1285+
1286+
/** @internal */
1287+
export const DOCUMENT_DB_CHECK = /(\.docdb\.amazonaws\.com$)|(\.docdb-elastic\.amazonaws\.com$)/;
1288+
/** @internal */
1289+
export const COSMOS_DB_CHECK = /\.cosmos\.azure\.com$/;
1290+
1291+
/** @internal */
1292+
export const DOCUMENT_DB_MSG =
1293+
'You appear to be connected to a DocumentDB cluster. For more information regarding feature compatibility and support please visit https://www.mongodb.com/supportability/documentdb';
1294+
/** @internal */
1295+
export const COSMOS_DB_MSG =
1296+
'You appear to be connected to a CosmosDB cluster. For more information regarding feature compatibility and support please visit https://www.mongodb.com/supportability/cosmosdb';
1297+
1298+
/** @internal */
1299+
export function isHostMatch(match: RegExp, host?: string): boolean {
1300+
return host && match.test(host.toLowerCase()) ? true : false;
1301+
}

test/unit/connection_string.test.ts

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ import { inspect } from 'util';
99
import {
1010
AUTH_MECHS_AUTH_SRC_EXTERNAL,
1111
AuthMechanism,
12+
COSMOS_DB_MSG,
1213
DEFAULT_ALLOWED_HOSTS,
14+
DOCUMENT_DB_MSG,
1315
FEATURE_FLAGS,
1416
type Log,
1517
MongoAPIError,
@@ -883,4 +885,58 @@ describe('Connection String', function () {
883885
});
884886
});
885887
});
888+
889+
describe('non-genuine hosts', () => {
890+
beforeEach(() => {
891+
process.env.MONGODB_LOG_CLIENT = 'info';
892+
});
893+
894+
afterEach(() => {
895+
process.env.MONGODB_LOG_CLIENT = undefined;
896+
});
897+
898+
const loggerFeatureFlag = Symbol.for('@@mdb.enableMongoLogger');
899+
const test_cases = [
900+
['non-SRV example uri', 'mongodb://a.example.com:27017,b.example.com:27017/', ''],
901+
['non-SRV default uri', 'mongodb://a.mongodb.net:27017', ''],
902+
['SRV example uri', 'mongodb+srv://a.example.com/', ''],
903+
['SRV default uri', 'mongodb+srv://a.mongodb.net/', ''],
904+
// ensure case insensitity
905+
['non-SRV cosmosDB uri', 'mongodb://a.mongo.COSmos.aZure.com:19555/', COSMOS_DB_MSG],
906+
['non-SRV documentDB uri', 'mongodb://a.docDB.AmazonAws.com:27017/', DOCUMENT_DB_MSG],
907+
[
908+
'non-SRV documentDB uri ',
909+
'mongodb://a.docdB-eLasTic.amazonaws.com:27017/',
910+
DOCUMENT_DB_MSG
911+
],
912+
['SRV cosmosDB uri', 'mongodb+srv://a.mongo.COSmos.aZure.com/', COSMOS_DB_MSG],
913+
['SRV documentDB uri', 'mongodb+srv://a.docDB.AmazonAws.com/', DOCUMENT_DB_MSG],
914+
['SRV documentDB uri 2', 'mongodb+srv://a.docdB-eLastic.amazonaws.com/', DOCUMENT_DB_MSG]
915+
];
916+
917+
context('when logging is turned on', () => {
918+
for (const [name, uri, message] of test_cases) {
919+
it(`${name} triggers ${message.length === 0 ? 'no' : 'correct info'} msg`, () => {
920+
const stream = {
921+
buffer: [],
922+
write(log) {
923+
this.buffer.push(log);
924+
}
925+
};
926+
new MongoClient(uri, {
927+
[loggerFeatureFlag]: true,
928+
mongodbLogPath: stream
929+
});
930+
931+
if (message.length > 0) {
932+
expect(stream.buffer).to.have.lengthOf(1);
933+
expect(stream.buffer[0]).to.have.property('c', 'client');
934+
expect(stream.buffer[0]).to.have.property('message', message);
935+
} else {
936+
expect(stream.buffer).to.have.lengthOf(0);
937+
}
938+
});
939+
}
940+
});
941+
});
886942
});

test/unit/mongo_logger.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,8 @@ describe('class MongoLogger', function () {
116116
['MONGODB_LOG_COMMAND', 'command'],
117117
['MONGODB_LOG_TOPOLOGY', 'topology'],
118118
['MONGODB_LOG_SERVER_SELECTION', 'serverSelection'],
119-
['MONGODB_LOG_CONNECTION', 'connection']
119+
['MONGODB_LOG_CONNECTION', 'connection'],
120+
['MONGODB_LOG_CLIENT', 'client']
120121
]);
121122

122123
function* makeValidOptions(): Generator<[string, string]> {

0 commit comments

Comments
 (0)