Skip to content

Commit 6ef11d7

Browse files
feat(NODE-4810): define the new Logger (#3475)
Co-authored-by: Bailey Pearson <bailey.pearson@mongodb.com>
1 parent dfcc3d9 commit 6ef11d7

9 files changed

+934
-25
lines changed

src/connection_string.ts

+48-18
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import {
1414
MongoMissingCredentialsError,
1515
MongoParseError
1616
} from './error';
17-
import { Logger, LoggerLevel } from './logger';
17+
import { Logger as LegacyLogger, LoggerLevel as LegacyLoggerLevel } from './logger';
1818
import {
1919
DriverInfo,
2020
MongoClient,
@@ -24,6 +24,7 @@ import {
2424
ServerApi,
2525
ServerApiVersion
2626
} from './mongo_client';
27+
import { MongoLogger, MongoLoggerEnvOptions, MongoLoggerMongoClientOptions } from './mongo_logger';
2728
import { PromiseProvider } from './promise_provider';
2829
import { ReadConcern, ReadConcernLevel } from './read_concern';
2930
import { ReadPreference, ReadPreferenceMode } from './read_preference';
@@ -35,6 +36,7 @@ import {
3536
HostAddress,
3637
isRecord,
3738
makeClientMetadata,
39+
parseInteger,
3840
setDifference
3941
} from './utils';
4042
import { W, WriteConcern } from './write_concern';
@@ -199,15 +201,16 @@ function getBoolean(name: string, value: unknown): boolean {
199201
throw new MongoParseError(`Expected ${name} to be stringified boolean value, got: ${value}`);
200202
}
201203

202-
function getInt(name: string, value: unknown): number {
203-
if (typeof value === 'number') return Math.trunc(value);
204-
const parsedValue = Number.parseInt(String(value), 10);
205-
if (!Number.isNaN(parsedValue)) return parsedValue;
204+
function getIntFromOptions(name: string, value: unknown): number {
205+
const parsedInt = parseInteger(value);
206+
if (parsedInt != null) {
207+
return parsedInt;
208+
}
206209
throw new MongoParseError(`Expected ${name} to be stringified int value, got: ${value}`);
207210
}
208211

209-
function getUint(name: string, value: unknown): number {
210-
const parsedValue = getInt(name, value);
212+
function getUIntFromOptions(name: string, value: unknown): number {
213+
const parsedValue = getIntFromOptions(name, value);
211214
if (parsedValue < 0) {
212215
throw new MongoParseError(`${name} can only be a positive int value, got: ${value}`);
213216
}
@@ -507,6 +510,30 @@ export function parseOptions(
507510
);
508511
}
509512

513+
const loggerFeatureFlag = Symbol.for('@@mdb.enableMongoLogger');
514+
mongoOptions[loggerFeatureFlag] = mongoOptions[loggerFeatureFlag] ?? false;
515+
516+
let loggerEnvOptions: MongoLoggerEnvOptions = {};
517+
let loggerClientOptions: MongoLoggerMongoClientOptions = {};
518+
if (mongoOptions[loggerFeatureFlag]) {
519+
loggerEnvOptions = {
520+
MONGODB_LOG_COMMAND: process.env.MONGODB_LOG_COMMAND,
521+
MONGODB_LOG_TOPOLOGY: process.env.MONGODB_LOG_TOPOLOGY,
522+
MONGODB_LOG_SERVER_SELECTION: process.env.MONGODB_LOG_SERVER_SELECTION,
523+
MONGODB_LOG_CONNECTION: process.env.MONGODB_LOG_CONNECTION,
524+
MONGODB_LOG_ALL: process.env.MONGODB_LOG_ALL,
525+
MONGODB_LOG_MAX_DOCUMENT_LENGTH: process.env.MONGODB_LOG_MAX_DOCUMENT_LENGTH,
526+
MONGODB_LOG_PATH: process.env.MONGODB_LOG_PATH
527+
};
528+
loggerClientOptions = {
529+
mongodbLogPath: mongoOptions.mongodbLogPath
530+
};
531+
}
532+
mongoOptions.mongoLoggerOptions = MongoLogger.resolveOptions(
533+
loggerEnvOptions,
534+
loggerClientOptions
535+
);
536+
510537
return mongoOptions;
511538
}
512539

@@ -561,10 +588,10 @@ function setOption(
561588
mongoOptions[name] = getBoolean(name, values[0]);
562589
break;
563590
case 'int':
564-
mongoOptions[name] = getInt(name, values[0]);
591+
mongoOptions[name] = getIntFromOptions(name, values[0]);
565592
break;
566593
case 'uint':
567-
mongoOptions[name] = getUint(name, values[0]);
594+
mongoOptions[name] = getUIntFromOptions(name, values[0]);
568595
break;
569596
case 'string':
570597
if (values[0] == null) {
@@ -770,7 +797,7 @@ export const OPTIONS = {
770797
enableUtf8Validation: { type: 'boolean', default: true },
771798
family: {
772799
transform({ name, values: [value] }): 4 | 6 {
773-
const transformValue = getInt(name, value);
800+
const transformValue = getIntFromOptions(name, value);
774801
if (transformValue === 4 || transformValue === 6) {
775802
return transformValue;
776803
}
@@ -849,9 +876,9 @@ export const OPTIONS = {
849876
type: 'uint'
850877
},
851878
logger: {
852-
default: new Logger('MongoClient'),
879+
default: new LegacyLogger('MongoClient'),
853880
transform({ values: [value] }) {
854-
if (value instanceof Logger) {
881+
if (value instanceof LegacyLogger) {
855882
return value;
856883
}
857884
emitWarning('Alternative loggers might not be supported');
@@ -863,13 +890,13 @@ export const OPTIONS = {
863890
loggerLevel: {
864891
target: 'logger',
865892
transform({ values: [value] }) {
866-
return new Logger('MongoClient', { loggerLevel: value as LoggerLevel });
893+
return new LegacyLogger('MongoClient', { loggerLevel: value as LegacyLoggerLevel });
867894
}
868895
},
869896
maxConnecting: {
870897
default: 2,
871898
transform({ name, values: [value] }): number {
872-
const maxConnecting = getUint(name, value);
899+
const maxConnecting = getUIntFromOptions(name, value);
873900
if (maxConnecting === 0) {
874901
throw new MongoInvalidArgumentError('maxConnecting must be > 0 if specified');
875902
}
@@ -887,7 +914,7 @@ export const OPTIONS = {
887914
maxStalenessSeconds: {
888915
target: 'readPreference',
889916
transform({ name, options, values: [value] }) {
890-
const maxStalenessSeconds = getUint(name, value);
917+
const maxStalenessSeconds = getUIntFromOptions(name, value);
891918
if (options.readPreference) {
892919
return ReadPreference.fromOptions({
893920
readPreference: { ...options.readPreference, maxStalenessSeconds }
@@ -1206,7 +1233,7 @@ export const OPTIONS = {
12061233
const wc = WriteConcern.fromOptions({
12071234
writeConcern: {
12081235
...options.writeConcern,
1209-
wtimeout: getUint('wtimeout', value)
1236+
wtimeout: getUIntFromOptions('wtimeout', value)
12101237
}
12111238
});
12121239
if (wc) return wc;
@@ -1219,7 +1246,7 @@ export const OPTIONS = {
12191246
const wc = WriteConcern.fromOptions({
12201247
writeConcern: {
12211248
...options.writeConcern,
1222-
wtimeoutMS: getUint('wtimeoutMS', value)
1249+
wtimeoutMS: getUIntFromOptions('wtimeoutMS', value)
12231250
}
12241251
});
12251252
if (wc) return wc;
@@ -1274,4 +1301,7 @@ export const DEFAULT_OPTIONS = new CaseInsensitiveMap(
12741301
* Set of permitted feature flags
12751302
* @internal
12761303
*/
1277-
export const FEATURE_FLAGS = new Set([Symbol.for('@@mdb.skipPingOnConnect')]);
1304+
export const FEATURE_FLAGS = new Set([
1305+
Symbol.for('@@mdb.skipPingOnConnect'),
1306+
Symbol.for('@@mdb.enableMongoLogger')
1307+
]);

src/index.ts

+8
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,14 @@ export type {
300300
SupportedTLSSocketOptions,
301301
WithSessionCallback
302302
} from './mongo_client';
303+
export type {
304+
MongoLoggableComponent,
305+
MongoLogger,
306+
MongoLoggerEnvOptions,
307+
MongoLoggerMongoClientOptions,
308+
MongoLoggerOptions,
309+
SeverityLevel
310+
} from './mongo_logger';
303311
export type {
304312
CommonEvents,
305313
EventsDescription,

src/mongo_client.ts

+13-6
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ import { Db, DbOptions } from './db';
1515
import type { AutoEncrypter, AutoEncryptionOptions } from './deps';
1616
import type { Encrypter } from './encrypter';
1717
import { MongoInvalidArgumentError } from './error';
18-
import type { Logger, LoggerLevel } from './logger';
18+
import type { Logger as LegacyLogger, LoggerLevel as LegacyLoggerLevel } from './logger';
19+
import { MongoLogger, MongoLoggerOptions } from './mongo_logger';
1920
import { TypedEventEmitter } from './mongo_types';
2021
import type { ReadConcern, ReadConcernLevel, ReadConcernLike } from './read_concern';
2122
import { ReadPreference, ReadPreferenceMode } from './read_preference';
@@ -233,9 +234,9 @@ export interface MongoClientOptions extends BSONSerializeOptions, SupportedNodeC
233234
*/
234235
promiseLibrary?: any;
235236
/** The logging level */
236-
loggerLevel?: LoggerLevel;
237+
loggerLevel?: LegacyLoggerLevel;
237238
/** Custom logger object */
238-
logger?: Logger;
239+
logger?: LegacyLogger;
239240
/** Enable command monitoring for this client */
240241
monitorCommands?: boolean;
241242
/** Server API version */
@@ -296,7 +297,7 @@ export interface MongoClientPrivate {
296297
readonly readConcern?: ReadConcern;
297298
readonly writeConcern?: WriteConcern;
298299
readonly readPreference: ReadPreference;
299-
readonly logger: Logger;
300+
readonly logger: LegacyLogger;
300301
readonly isMongoClient: true;
301302
}
302303

@@ -334,6 +335,8 @@ export class MongoClient extends TypedEventEmitter<MongoClientEvents> {
334335
s: MongoClientPrivate;
335336
/** @internal */
336337
topology?: Topology;
338+
/** @internal */
339+
readonly mongoLogger: MongoLogger;
337340

338341
/**
339342
* The consolidate, parsed, transformed and merged options.
@@ -345,6 +348,7 @@ export class MongoClient extends TypedEventEmitter<MongoClientEvents> {
345348
super();
346349

347350
this[kOptions] = parseOptions(url, this, options);
351+
this.mongoLogger = new MongoLogger(this[kOptions].mongoLoggerOptions);
348352

349353
// eslint-disable-next-line @typescript-eslint/no-this-alias
350354
const client = this;
@@ -417,7 +421,7 @@ export class MongoClient extends TypedEventEmitter<MongoClientEvents> {
417421
return this.s.bsonOptions;
418422
}
419423

420-
get logger(): Logger {
424+
get logger(): LegacyLogger {
421425
return this.s.logger;
422426
}
423427

@@ -708,7 +712,7 @@ export class MongoClient extends TypedEventEmitter<MongoClientEvents> {
708712
}
709713

710714
/** Return the mongo client logger */
711-
getLogger(): Logger {
715+
getLogger(): LegacyLogger {
712716
return this.s.logger;
713717
}
714718
}
@@ -803,4 +807,7 @@ export interface MongoOptions
803807

804808
/** @internal */
805809
[featureFlag: symbol]: any;
810+
811+
/** @internal */
812+
mongoLoggerOptions: MongoLoggerOptions;
806813
}

0 commit comments

Comments
 (0)