Skip to content

Commit

Permalink
feat(NODE-5452): Logging Cosmos Document DB Info Message (#3902)
Browse files Browse the repository at this point in the history
Co-authored-by: Durran Jordan <durran@gmail.com>
  • Loading branch information
aditi-khare-mongoDB and durran committed Nov 3, 2023
1 parent 1c3dc02 commit bb5fa43
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 2 deletions.
1 change: 1 addition & 0 deletions src/connection_string.ts
Original file line number Diff line number Diff line change
Expand Up @@ -523,6 +523,7 @@ export function parseOptions(
MONGODB_LOG_TOPOLOGY: process.env.MONGODB_LOG_TOPOLOGY,
MONGODB_LOG_SERVER_SELECTION: process.env.MONGODB_LOG_SERVER_SELECTION,
MONGODB_LOG_CONNECTION: process.env.MONGODB_LOG_CONNECTION,
MONGODB_LOG_CLIENT: process.env.MONGODB_LOG_CLIENT,
MONGODB_LOG_ALL: process.env.MONGODB_LOG_ALL,
MONGODB_LOG_MAX_DOCUMENT_LENGTH: process.env.MONGODB_LOG_MAX_DOCUMENT_LENGTH,
MONGODB_LOG_PATH: process.env.MONGODB_LOG_PATH,
Expand Down
25 changes: 25 additions & 0 deletions src/mongo_client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,13 @@ import type { SrvPoller } from './sdam/srv_polling';
import { Topology, type TopologyEvents } from './sdam/topology';
import { ClientSession, type ClientSessionOptions, ServerSessionPool } from './sessions';
import {
COSMOS_DB_CHECK,
COSMOS_DB_MSG,
DOCUMENT_DB_CHECK,
DOCUMENT_DB_MSG,
type HostAddress,
hostMatchesWildcards,
isHostMatch,
type MongoDBNamespace,
ns,
resolveOptions
Expand Down Expand Up @@ -364,6 +369,26 @@ export class MongoClient extends TypedEventEmitter<MongoClientEvents> {
return true;
}
};
this.checkForNonGenuineHosts();
}

/** @internal */
private checkForNonGenuineHosts() {
const documentDBHostnames = this[kOptions].hosts.filter((hostAddress: HostAddress) =>
isHostMatch(DOCUMENT_DB_CHECK, hostAddress.host)
);
const srvHostIsDocumentDB = isHostMatch(DOCUMENT_DB_CHECK, this[kOptions].srvHost);

const cosmosDBHostnames = this[kOptions].hosts.filter((hostAddress: HostAddress) =>
isHostMatch(COSMOS_DB_CHECK, hostAddress.host)
);
const srvHostIsCosmosDB = isHostMatch(COSMOS_DB_CHECK, this[kOptions].srvHost);

if (documentDBHostnames.length !== 0 || srvHostIsDocumentDB) {
this.mongoLogger.info('client', DOCUMENT_DB_MSG);
} else if (cosmosDBHostnames.length !== 0 || srvHostIsCosmosDB) {
this.mongoLogger.info('client', COSMOS_DB_MSG);
}
}

/** @see MongoOptions */
Expand Down
8 changes: 7 additions & 1 deletion src/mongo_logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,8 @@ export const MongoLoggableComponent = Object.freeze({
COMMAND: 'command',
TOPOLOGY: 'topology',
SERVER_SELECTION: 'serverSelection',
CONNECTION: 'connection'
CONNECTION: 'connection',
CLIENT: 'client'
} as const);

/** @internal */
Expand All @@ -115,6 +116,8 @@ export interface MongoLoggerEnvOptions {
MONGODB_LOG_SERVER_SELECTION?: string;
/** Severity level for CMAP */
MONGODB_LOG_CONNECTION?: string;
/** Severity level for client */
MONGODB_LOG_CLIENT?: string;
/** Default severity level to be if any of the above are unset */
MONGODB_LOG_ALL?: string;
/** Max length of embedded EJSON docs. Setting to 0 disables truncation. Defaults to 1000. */
Expand All @@ -140,6 +143,8 @@ export interface MongoLoggerOptions {
serverSelection: SeverityLevel;
/** Severity level for connection component */
connection: SeverityLevel;
/** Severity level for client component */
client: SeverityLevel;
/** Default severity level to be used if any of the above are unset */
default: SeverityLevel;
};
Expand Down Expand Up @@ -528,6 +533,7 @@ export class MongoLogger {
parseSeverityFromString(combinedOptions.MONGODB_LOG_SERVER_SELECTION) ?? defaultSeverity,
connection:
parseSeverityFromString(combinedOptions.MONGODB_LOG_CONNECTION) ?? defaultSeverity,
client: parseSeverityFromString(combinedOptions.MONGODB_LOG_CLIENT) ?? defaultSeverity,
default: defaultSeverity
},
maxDocumentLength:
Expand Down
17 changes: 17 additions & 0 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1282,3 +1282,20 @@ export class TimeoutController extends AbortController {
this.timeoutId = null;
}
}

/** @internal */
export const DOCUMENT_DB_CHECK = /(\.docdb\.amazonaws\.com$)|(\.docdb-elastic\.amazonaws\.com$)/;
/** @internal */
export const COSMOS_DB_CHECK = /\.cosmos\.azure\.com$/;

/** @internal */
export const DOCUMENT_DB_MSG =
'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';
/** @internal */
export const COSMOS_DB_MSG =
'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';

/** @internal */
export function isHostMatch(match: RegExp, host?: string): boolean {
return host && match.test(host.toLowerCase()) ? true : false;
}
56 changes: 56 additions & 0 deletions test/unit/connection_string.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ import { inspect } from 'util';
import {
AUTH_MECHS_AUTH_SRC_EXTERNAL,
AuthMechanism,
COSMOS_DB_MSG,
DEFAULT_ALLOWED_HOSTS,
DOCUMENT_DB_MSG,
FEATURE_FLAGS,
type Log,
MongoAPIError,
Expand Down Expand Up @@ -883,4 +885,58 @@ describe('Connection String', function () {
});
});
});

describe('non-genuine hosts', () => {
beforeEach(() => {
process.env.MONGODB_LOG_CLIENT = 'info';
});

afterEach(() => {
process.env.MONGODB_LOG_CLIENT = undefined;
});

const loggerFeatureFlag = Symbol.for('@@mdb.enableMongoLogger');
const test_cases = [
['non-SRV example uri', 'mongodb://a.example.com:27017,b.example.com:27017/', ''],
['non-SRV default uri', 'mongodb://a.mongodb.net:27017', ''],
['SRV example uri', 'mongodb+srv://a.example.com/', ''],
['SRV default uri', 'mongodb+srv://a.mongodb.net/', ''],
// ensure case insensitity
['non-SRV cosmosDB uri', 'mongodb://a.mongo.COSmos.aZure.com:19555/', COSMOS_DB_MSG],
['non-SRV documentDB uri', 'mongodb://a.docDB.AmazonAws.com:27017/', DOCUMENT_DB_MSG],
[
'non-SRV documentDB uri ',
'mongodb://a.docdB-eLasTic.amazonaws.com:27017/',
DOCUMENT_DB_MSG
],
['SRV cosmosDB uri', 'mongodb+srv://a.mongo.COSmos.aZure.com/', COSMOS_DB_MSG],
['SRV documentDB uri', 'mongodb+srv://a.docDB.AmazonAws.com/', DOCUMENT_DB_MSG],
['SRV documentDB uri 2', 'mongodb+srv://a.docdB-eLastic.amazonaws.com/', DOCUMENT_DB_MSG]
];

context('when logging is turned on', () => {
for (const [name, uri, message] of test_cases) {
it(`${name} triggers ${message.length === 0 ? 'no' : 'correct info'} msg`, () => {
const stream = {
buffer: [],
write(log) {
this.buffer.push(log);
}
};
new MongoClient(uri, {
[loggerFeatureFlag]: true,
mongodbLogPath: stream
});

if (message.length > 0) {
expect(stream.buffer).to.have.lengthOf(1);
expect(stream.buffer[0]).to.have.property('c', 'client');
expect(stream.buffer[0]).to.have.property('message', message);
} else {
expect(stream.buffer).to.have.lengthOf(0);
}
});
}
});
});
});
3 changes: 2 additions & 1 deletion test/unit/mongo_logger.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,8 @@ describe('class MongoLogger', function () {
['MONGODB_LOG_COMMAND', 'command'],
['MONGODB_LOG_TOPOLOGY', 'topology'],
['MONGODB_LOG_SERVER_SELECTION', 'serverSelection'],
['MONGODB_LOG_CONNECTION', 'connection']
['MONGODB_LOG_CONNECTION', 'connection'],
['MONGODB_LOG_CLIENT', 'client']
]);

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

0 comments on commit bb5fa43

Please sign in to comment.