Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(NODE-4814): implement remaining severity logging methods #3629

Merged
28 changes: 26 additions & 2 deletions src/mongo_logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -442,14 +442,38 @@ export class MongoLogger {
maxDocumentLength: number;
logDestination: MongoDBLogWritable | Writable;

/**
* This method should be used when logging errors that do not have a public driver API for
* reporting errors.
*/
error = this.log.bind(this, 'error');
/**
* This method should be used to log situations where undesirable application behaviour might
* occur. For example, failing to end sessions on `MongoClient.close`.
*/
warn = this.log.bind(this, 'warn');
/**
* This method should be used to report high-level information about normal driver behaviour.
* For example, the creation of a `MongoClient`.
*/
info = this.log.bind(this, 'info');
/**
* This method should be used to report information that would be helpful when debugging an
* application. For example, a command starting, succeeding or failing.
*/
debug = this.log.bind(this, 'debug');
/**
* This method should be used to report fine-grained details related to logic flow. For example,
* entering and exiting a function body.
*/
trace = this.log.bind(this, 'trace');

constructor(options: MongoLoggerOptions) {
this.componentSeverities = options.componentSeverities;
this.maxDocumentLength = options.maxDocumentLength;
this.logDestination = options.logDestination;
}

emergency = this.log.bind(this, 'emergency');

private log(
severity: SeverityLevel,
component: MongoLoggableComponent,
Expand Down
85 changes: 36 additions & 49 deletions test/unit/mongo_logger.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import {
MongoDBLogWritable,
MongoLogger,
MongoLoggerOptions,
SEVERITY_LEVEL_MAP,
SeverityLevel,
stringifyWithMaxLen
} from '../mongodb';
Expand Down Expand Up @@ -81,11 +80,11 @@ describe('class MongoLogger', function () {
}
} as { buffer: any[]; write: (log: Log) => void };
const logger = new MongoLogger({
componentSeverities: { command: 'emergency' } as any,
componentSeverities: { command: 'error' } as any,
logDestination
} as any);

logger.emergency('command', 'Hello world!');
logger.error('command', 'Hello world!');
expect(logDestination.buffer).to.have.lengthOf(1);
});
});
Expand All @@ -101,11 +100,11 @@ describe('class MongoLogger', function () {
});

const logger = new MongoLogger({
componentSeverities: { command: 'emergency' } as any,
componentSeverities: { command: 'error' } as any,
logDestination
} as any);

logger.emergency('command', 'Hello world!');
logger.error('command', 'Hello world!');
expect(buffer).to.have.lengthOf(1);
});
});
Expand All @@ -121,8 +120,8 @@ describe('class MongoLogger', function () {
]);

function* makeValidOptions(): Generator<[string, string]> {
const validOptions = Object.values(SeverityLevel).filter(
option => option !== SeverityLevel.OFF
const validOptions = Object.values(SeverityLevel).filter(option =>
['error', 'warn', 'info', 'debug', 'trace'].includes(option)
);
for (const option of validOptions) {
yield [option, option];
Expand Down Expand Up @@ -429,11 +428,11 @@ describe('class MongoLogger', function () {
const options = MongoLogger.resolveOptions(
{
MONGODB_LOG_PATH: unsetEnvironmentOption,
MONGODB_LOG_COMMAND: 'emergency'
MONGODB_LOG_COMMAND: 'error'
},
{ mongodbLogPath: unsetOption as any }
);
const log: Log = { t: new Date(), c: 'command', s: 'emergency' };
const log: Log = { t: new Date(), c: 'command', s: 'error' };
options.logDestination.write(log);

expect(stderrStub.write).to.have.been.calledOnceWith(
Expand All @@ -451,11 +450,11 @@ describe('class MongoLogger', function () {
const options = MongoLogger.resolveOptions(
{
MONGODB_LOG_PATH: unsetEnvironmentOption,
MONGODB_LOG_COMMAND: 'emergency'
MONGODB_LOG_COMMAND: 'error'
},
{ mongodbLogPath: invalidOption as any }
);
const log: Log = { t: new Date(), c: 'command', s: 'emergency' };
const log: Log = { t: new Date(), c: 'command', s: 'error' };
options.logDestination.write(log);

expect(stderrStub.write).to.have.been.calledOnceWith(
Expand All @@ -473,12 +472,12 @@ describe('class MongoLogger', function () {
const options = MongoLogger.resolveOptions(
{
MONGODB_LOG_PATH: unsetEnvironmentOption,
MONGODB_LOG_COMMAND: 'emergency'
MONGODB_LOG_COMMAND: 'error'
},
{ mongodbLogPath: validOption as any }
);

const log: Log = { t: new Date(), c: 'command', s: 'emergency' };
const log: Log = { t: new Date(), c: 'command', s: 'error' };
options.logDestination.write(log);
const correctDestination = validOptions.get(validOption);
expect(correctDestination?.write).to.have.been.calledOnce;
Expand All @@ -498,11 +497,11 @@ describe('class MongoLogger', function () {
const options = MongoLogger.resolveOptions(
{
MONGODB_LOG_PATH: invalidEnvironmentOption,
MONGODB_LOG_COMMAND: 'emergency'
MONGODB_LOG_COMMAND: 'error'
},
{ mongodbLogPath: unsetClientOption as any }
);
const log: Log = { t: new Date(), c: 'command', s: 'emergency' };
const log: Log = { t: new Date(), c: 'command', s: 'error' };
options.logDestination.write(log);

expect(stderrStub.write).to.have.been.calledOnceWith(
Expand All @@ -522,11 +521,11 @@ describe('class MongoLogger', function () {
const options = MongoLogger.resolveOptions(
{
MONGODB_LOG_PATH: invalidEnvironmentOption,
MONGODB_LOG_COMMAND: 'emergency'
MONGODB_LOG_COMMAND: 'error'
},
{ mongodbLogPath: invalidOption as any }
);
const log: Log = { t: new Date(), c: 'command', s: 'emergency' };
const log: Log = { t: new Date(), c: 'command', s: 'error' };
options.logDestination.write(log);

expect(stderrStub.write).to.have.been.calledOnceWith(
Expand All @@ -545,12 +544,12 @@ describe('class MongoLogger', function () {
const options = MongoLogger.resolveOptions(
{
MONGODB_LOG_PATH: invalidEnvironmentOption,
MONGODB_LOG_COMMAND: 'emergency'
MONGODB_LOG_COMMAND: 'error'
},
{ mongodbLogPath: validOption as any }
);
const correctDestination = validOptions.get(validOption);
const log: Log = { t: new Date(), c: 'command', s: 'emergency' };
const log: Log = { t: new Date(), c: 'command', s: 'error' };
options.logDestination.write(log);
expect(correctDestination?.write).to.have.been.calledOnce;
});
Expand All @@ -568,12 +567,12 @@ describe('class MongoLogger', function () {
const options = MongoLogger.resolveOptions(
{
MONGODB_LOG_PATH: validEnvironmentOption,
MONGODB_LOG_COMMAND: 'emergency'
MONGODB_LOG_COMMAND: 'error'
},
{ mongodbLogPath: unsetOption as any }
);
const correctDestination = validOptions.get(validEnvironmentOption);
options.logDestination.write({ t: new Date(), c: 'command', s: 'emergency' });
options.logDestination.write({ t: new Date(), c: 'command', s: 'error' });

expect(correctDestination?.write).to.have.been.calledOnce;
});
Expand All @@ -590,13 +589,13 @@ describe('class MongoLogger', function () {
const options = MongoLogger.resolveOptions(
{
MONGODB_LOG_PATH: validEnvironmentOption,
MONGODB_LOG_COMMAND: 'emergency'
MONGODB_LOG_COMMAND: 'error'
},
{ mongodbLogPath: invalidValue as any }
);

const correctDestination = validOptions.get(validEnvironmentOption);
const log: Log = { t: new Date(), c: 'command', s: 'emergency' };
const log: Log = { t: new Date(), c: 'command', s: 'error' };
options.logDestination.write(log);

expect(correctDestination?.write).to.have.been.calledOnce;
Expand All @@ -617,12 +616,12 @@ describe('class MongoLogger', function () {
const options = MongoLogger.resolveOptions(
{
MONGODB_LOG_PATH: validEnvironmentOption,
MONGODB_LOG_COMMAND: 'emergency'
MONGODB_LOG_COMMAND: 'error'
},
{ mongodbLogPath: validValue as any }
);
const correctDestination = validOptions.get(validValue);
options.logDestination.write({ t: new Date(), c: 'command', s: 'emergency' });
options.logDestination.write({ t: new Date(), c: 'command', s: 'error' });
expect(correctDestination?.write).to.have.been.calledOnce;
});
}
Expand All @@ -633,9 +632,10 @@ describe('class MongoLogger', function () {
});

describe('severity helpers', function () {
// TODO(NODE-4814): Ensure we test on all valid severity levels
const severities = Object.values(SeverityLevel).filter(severity => severity === 'emergency');
for (const severityLevel of severities) {
const severities: SeverityLevel[] = Object.values(SeverityLevel).filter(severity =>
['error', 'warn', 'info', 'debug', 'trace'].includes(severity)
);
for (const [index, severityLevel] of severities.entries()) {
describe(`${severityLevel}()`, function () {
it('does not log when logging for the component is disabled', () => {
const stream = new BufferingStream();
Expand All @@ -650,8 +650,7 @@ describe('class MongoLogger', function () {
expect(stream.buffer).to.have.lengthOf(0);
});

// TODO(NODE-4814): Unskip this test
context.skip('when the log severity is greater than what was configured', function () {
context('when the log severity is greater than what was configured', function () {
it('does not write to logDestination', function () {
const stream = new BufferingStream();
const logger = new MongoLogger({
Expand All @@ -661,14 +660,9 @@ describe('class MongoLogger', function () {
logDestination: stream
} as any);

const TRACE = 8;
for (
let l = SEVERITY_LEVEL_MAP.getNumericSeverityLevel(severityLevel) + 1;
l <= TRACE;
l++
) {
const severity = SEVERITY_LEVEL_MAP.getSeverityLevelName(l);
logger[severity as SeverityLevel]('command', 'Hello');
for (let i = index + 1; i < severities.length; i++) {
const severity = severities[i];
logger[severity]('command', 'Hello');
}

expect(stream.buffer).to.have.lengthOf(0);
Expand All @@ -685,20 +679,13 @@ describe('class MongoLogger', function () {
logDestination: stream
} as any);

const EMERGENCY = 0;
// Calls all severity logging methods with a level less than or equal to what severityLevel
for (
let l = SEVERITY_LEVEL_MAP.getNumericSeverityLevel(severityLevel);
l >= EMERGENCY;
l--
) {
const severity = SEVERITY_LEVEL_MAP.getSeverityLevelName(l);
logger[severity as SeverityLevel]('command', 'Hello');
for (let i = index; i >= 0; i--) {
const severity = severities[i];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if we type severities as SeverityLevel[], we should be able to remove the cast in line 683

logger[severity]('command', 'Hello');
}

expect(stream.buffer).to.have.lengthOf(
SEVERITY_LEVEL_MAP.getNumericSeverityLevel(severityLevel) + 1
);
expect(stream.buffer).to.have.lengthOf(index + 1);
});
});

Expand Down