Skip to content

Commit 6ef11d7

Browse files
andyminabaileympearson
andauthoredDec 15, 2022
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
}

‎src/mongo_logger.ts

+201
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
import { Writable } from 'stream';
2+
3+
import { parseUnsignedInteger } from './utils';
4+
5+
/** @internal */
6+
export const SeverityLevel = Object.freeze({
7+
EMERGENCY: 'emergency',
8+
ALERT: 'alert',
9+
CRITICAL: 'critical',
10+
ERROR: 'error',
11+
WARNING: 'warn',
12+
NOTICE: 'notice',
13+
INFORMATIONAL: 'info',
14+
DEBUG: 'debug',
15+
TRACE: 'trace',
16+
OFF: 'off'
17+
} as const);
18+
19+
/** @internal */
20+
export type SeverityLevel = typeof SeverityLevel[keyof typeof SeverityLevel];
21+
22+
/** @internal */
23+
export const MongoLoggableComponent = Object.freeze({
24+
COMMAND: 'command',
25+
TOPOLOGY: 'topology',
26+
SERVER_SELECTION: 'serverSelection',
27+
CONNECTION: 'connection'
28+
} as const);
29+
30+
/** @internal */
31+
export type MongoLoggableComponent =
32+
typeof MongoLoggableComponent[keyof typeof MongoLoggableComponent];
33+
34+
/** @internal */
35+
export interface MongoLoggerEnvOptions {
36+
/** Severity level for command component */
37+
MONGODB_LOG_COMMAND?: string;
38+
/** Severity level for topology component */
39+
MONGODB_LOG_TOPOLOGY?: string;
40+
/** Severity level for server selection component */
41+
MONGODB_LOG_SERVER_SELECTION?: string;
42+
/** Severity level for CMAP */
43+
MONGODB_LOG_CONNECTION?: string;
44+
/** Default severity level to be if any of the above are unset */
45+
MONGODB_LOG_ALL?: string;
46+
/** Max length of embedded EJSON docs. Setting to 0 disables truncation. Defaults to 1000. */
47+
MONGODB_LOG_MAX_DOCUMENT_LENGTH?: string;
48+
/** Destination for log messages. Must be 'stderr', 'stdout'. Defaults to 'stderr'. */
49+
MONGODB_LOG_PATH?: string;
50+
}
51+
52+
/** @internal */
53+
export interface MongoLoggerMongoClientOptions {
54+
/** Destination for log messages */
55+
mongodbLogPath?: 'stdout' | 'stderr' | Writable;
56+
}
57+
58+
/** @internal */
59+
export interface MongoLoggerOptions {
60+
componentSeverities: {
61+
/** Severity level for command component */
62+
command: SeverityLevel;
63+
/** Severity level for topology component */
64+
topology: SeverityLevel;
65+
/** Severity level for server selection component */
66+
serverSelection: SeverityLevel;
67+
/** Severity level for connection component */
68+
connection: SeverityLevel;
69+
/** Default severity level to be used if any of the above are unset */
70+
default: SeverityLevel;
71+
};
72+
73+
/** Max length of embedded EJSON docs. Setting to 0 disables truncation. Defaults to 1000. */
74+
maxDocumentLength: number;
75+
/** Destination for log messages. */
76+
logDestination: Writable;
77+
}
78+
79+
/**
80+
* Parses a string as one of SeverityLevel
81+
*
82+
* @param s - the value to be parsed
83+
* @returns one of SeverityLevel if value can be parsed as such, otherwise null
84+
*/
85+
function parseSeverityFromString(s?: string): SeverityLevel | null {
86+
const validSeverities: string[] = Object.values(SeverityLevel);
87+
const lowerSeverity = s?.toLowerCase();
88+
89+
if (lowerSeverity != null && validSeverities.includes(lowerSeverity)) {
90+
return lowerSeverity as SeverityLevel;
91+
}
92+
93+
return null;
94+
}
95+
96+
/**
97+
* resolves the MONGODB_LOG_PATH and mongodbLogPath options from the environment and the
98+
* mongo client options respectively.
99+
*
100+
* @returns the Writable stream to write logs to
101+
*/
102+
function resolveLogPath(
103+
{ MONGODB_LOG_PATH }: MongoLoggerEnvOptions,
104+
{
105+
mongodbLogPath
106+
}: {
107+
mongodbLogPath?: unknown;
108+
}
109+
): Writable {
110+
const isValidLogDestinationString = (destination: string) =>
111+
['stdout', 'stderr'].includes(destination.toLowerCase());
112+
if (typeof mongodbLogPath === 'string' && isValidLogDestinationString(mongodbLogPath)) {
113+
return mongodbLogPath.toLowerCase() === 'stderr' ? process.stderr : process.stdout;
114+
}
115+
116+
// TODO(NODE-4813): check for minimal interface instead of instanceof Writable
117+
if (typeof mongodbLogPath === 'object' && mongodbLogPath instanceof Writable) {
118+
return mongodbLogPath;
119+
}
120+
121+
if (typeof MONGODB_LOG_PATH === 'string' && isValidLogDestinationString(MONGODB_LOG_PATH)) {
122+
return MONGODB_LOG_PATH.toLowerCase() === 'stderr' ? process.stderr : process.stdout;
123+
}
124+
125+
return process.stderr;
126+
}
127+
128+
/** @internal */
129+
export class MongoLogger {
130+
componentSeverities: Record<MongoLoggableComponent, SeverityLevel>;
131+
maxDocumentLength: number;
132+
logDestination: Writable;
133+
134+
constructor(options: MongoLoggerOptions) {
135+
this.componentSeverities = options.componentSeverities;
136+
this.maxDocumentLength = options.maxDocumentLength;
137+
this.logDestination = options.logDestination;
138+
}
139+
140+
/* eslint-disable @typescript-eslint/no-unused-vars */
141+
/* eslint-disable @typescript-eslint/no-empty-function */
142+
emergency(component: any, message: any): void {}
143+
144+
alert(component: any, message: any): void {}
145+
146+
critical(component: any, message: any): void {}
147+
148+
error(component: any, message: any): void {}
149+
150+
warn(component: any, message: any): void {}
151+
152+
notice(component: any, message: any): void {}
153+
154+
info(component: any, message: any): void {}
155+
156+
debug(component: any, message: any): void {}
157+
158+
trace(component: any, message: any): void {}
159+
160+
/**
161+
* Merges options set through environment variables and the MongoClient, preferring environment
162+
* variables when both are set, and substituting defaults for values not set. Options set in
163+
* constructor take precedence over both environment variables and MongoClient options.
164+
*
165+
* @remarks
166+
* When parsing component severity levels, invalid values are treated as unset and replaced with
167+
* the default severity.
168+
*
169+
* @param envOptions - options set for the logger from the environment
170+
* @param clientOptions - options set for the logger in the MongoClient options
171+
* @returns a MongoLoggerOptions object to be used when instantiating a new MongoLogger
172+
*/
173+
static resolveOptions(
174+
envOptions: MongoLoggerEnvOptions,
175+
clientOptions: MongoLoggerMongoClientOptions
176+
): MongoLoggerOptions {
177+
// client options take precedence over env options
178+
const combinedOptions = {
179+
...envOptions,
180+
...clientOptions,
181+
mongodbLogPath: resolveLogPath(envOptions, clientOptions)
182+
};
183+
const defaultSeverity =
184+
parseSeverityFromString(combinedOptions.MONGODB_LOG_ALL) ?? SeverityLevel.OFF;
185+
186+
return {
187+
componentSeverities: {
188+
command: parseSeverityFromString(combinedOptions.MONGODB_LOG_COMMAND) ?? defaultSeverity,
189+
topology: parseSeverityFromString(combinedOptions.MONGODB_LOG_TOPOLOGY) ?? defaultSeverity,
190+
serverSelection:
191+
parseSeverityFromString(combinedOptions.MONGODB_LOG_SERVER_SELECTION) ?? defaultSeverity,
192+
connection:
193+
parseSeverityFromString(combinedOptions.MONGODB_LOG_CONNECTION) ?? defaultSeverity,
194+
default: defaultSeverity
195+
},
196+
maxDocumentLength:
197+
parseUnsignedInteger(combinedOptions.MONGODB_LOG_MAX_DOCUMENT_LENGTH) ?? 1000,
198+
logDestination: combinedOptions.mongodbLogPath
199+
};
200+
}
201+
}

‎src/utils.ts

+13
Original file line numberDiff line numberDiff line change
@@ -1421,3 +1421,16 @@ export function compareObjectId(oid1?: ObjectId | null, oid2?: ObjectId | null):
14211421

14221422
return oid1.id.compare(oid2.id);
14231423
}
1424+
1425+
export function parseInteger(value: unknown): number | null {
1426+
if (typeof value === 'number') return Math.trunc(value);
1427+
const parsedValue = Number.parseInt(String(value), 10);
1428+
1429+
return Number.isNaN(parsedValue) ? null : parsedValue;
1430+
}
1431+
1432+
export function parseUnsignedInteger(value: unknown): number | null {
1433+
const parsedInt = parseInteger(value);
1434+
1435+
return parsedInt != null && parsedInt >= 0 ? parsedInt : null;
1436+
}

‎test/integration/node-specific/feature_flags.test.ts

+99
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import { expect } from 'chai';
22

3+
import { MongoClient } from '../../../src';
4+
import { MongoLoggableComponent, SeverityLevel } from '../../../src/mongo_logger';
5+
36
describe('Feature Flags', () => {
47
describe('@@mdb.skipPingOnConnect', () => {
58
beforeEach(function () {
@@ -42,4 +45,100 @@ describe('Feature Flags', () => {
4245
});
4346
}
4447
});
48+
49+
describe('@@mdb.enableMongoLogger', () => {
50+
let cachedEnv;
51+
const loggerFeatureFlag = Symbol.for('@@mdb.enableMongoLogger');
52+
const components: Array<MongoLoggableComponent | 'default'> = [
53+
'default',
54+
'topology',
55+
'serverSelection',
56+
'connection',
57+
'command'
58+
];
59+
60+
before(() => {
61+
cachedEnv = process.env;
62+
});
63+
64+
after(() => {
65+
process.env = cachedEnv;
66+
});
67+
68+
context('when enabled', () => {
69+
context('when logging is enabled for any component', () => {
70+
before(() => {
71+
process.env.MONGODB_LOG_COMMAND = SeverityLevel.EMERGENCY;
72+
});
73+
74+
it('enables logging for the specified component', () => {
75+
const client = new MongoClient('mongodb://localhost:27017', {
76+
[loggerFeatureFlag]: true
77+
});
78+
expect(client.mongoLogger.componentSeverities).to.have.property(
79+
'command',
80+
SeverityLevel.EMERGENCY
81+
);
82+
});
83+
});
84+
85+
context('when logging is not enabled for any component', () => {
86+
before(() => {
87+
process.env = {};
88+
});
89+
90+
it('does not enable logging for any component', () => {
91+
const client = new MongoClient('mongodb://localhost:27017', {
92+
[loggerFeatureFlag]: true
93+
});
94+
for (const component of components) {
95+
expect(client.mongoLogger.componentSeverities).to.have.property(
96+
component,
97+
SeverityLevel.OFF
98+
);
99+
}
100+
});
101+
});
102+
});
103+
104+
for (const featureFlagValue of [false, undefined]) {
105+
context(`when set to ${featureFlagValue}`, () => {
106+
context('when logging is enabled for a component', () => {
107+
before(() => {
108+
process.env['MONGODB_LOG_COMMAND'] = SeverityLevel.EMERGENCY;
109+
});
110+
111+
it('does not enable logging', () => {
112+
const client = new MongoClient('mongodb://localhost:27017', {
113+
[loggerFeatureFlag]: featureFlagValue
114+
});
115+
for (const component of components) {
116+
expect(client.mongoLogger.componentSeverities).to.have.property(
117+
component,
118+
SeverityLevel.OFF
119+
);
120+
}
121+
});
122+
});
123+
124+
context('when logging is not enabled for any component', () => {
125+
before(() => {
126+
process.env = {};
127+
});
128+
129+
it('does not enable logging', () => {
130+
const client = new MongoClient('mongodb://localhost:27017', {
131+
[loggerFeatureFlag]: featureFlagValue
132+
});
133+
for (const component of components) {
134+
expect(client.mongoLogger.componentSeverities).to.have.property(
135+
component,
136+
SeverityLevel.OFF
137+
);
138+
}
139+
});
140+
});
141+
});
142+
}
143+
});
45144
});

‎test/unit/connection_string.test.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -539,8 +539,9 @@ describe('Connection String', function () {
539539

540540
describe('feature flags', () => {
541541
it('should be stored in the FEATURE_FLAGS Set', () => {
542-
expect(FEATURE_FLAGS.size).to.equal(1);
542+
expect(FEATURE_FLAGS.size).to.equal(2);
543543
expect(FEATURE_FLAGS.has(Symbol.for('@@mdb.skipPingOnConnect'))).to.be.true;
544+
expect(FEATURE_FLAGS.has(Symbol.for('@@mdb.enableMongoLogger'))).to.be.true;
544545
// Add more flags here
545546
});
546547

‎test/unit/mongo_client.test.js

+25
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ const { ReadPreference } = require('../../src/read_preference');
1010
const { Logger } = require('../../src/logger');
1111
const { MongoCredentials } = require('../../src/cmap/auth/mongo_credentials');
1212
const { MongoClient, MongoParseError, ServerApiVersion } = require('../../src');
13+
const { MongoLogger } = require('../../src/mongo_logger');
14+
const sinon = require('sinon');
15+
const { Writable } = require('stream');
1316

1417
describe('MongoOptions', function () {
1518
it('MongoClient should always freeze public options', function () {
@@ -847,4 +850,26 @@ describe('MongoOptions', function () {
847850
});
848851
});
849852
});
853+
854+
context('loggingOptions', function () {
855+
const expectedLoggingObject = {
856+
maxDocumentLength: 20,
857+
logDestination: new Writable()
858+
};
859+
860+
before(() => {
861+
sinon.stub(MongoLogger, 'resolveOptions').callsFake(() => {
862+
return expectedLoggingObject;
863+
});
864+
});
865+
866+
after(() => {
867+
sinon.restore();
868+
});
869+
870+
it('assigns the parsed options to the mongoLoggerOptions option', function () {
871+
const client = new MongoClient('mongodb://localhost:27017');
872+
expect(client.options).to.have.property('mongoLoggerOptions').to.equal(expectedLoggingObject);
873+
});
874+
});
850875
});

‎test/unit/mongo_logger.test.ts

+525
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)
Please sign in to comment.