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

issue/2029 #2284

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"extends": "@dabh/eslint-config-populist",
"rules": {
"one-var": ["error", { "var": "never", "let": "never", "const": "never" }],
"semi": "error",
"strict": 0
},
"parserOptions": {
Expand Down
2 changes: 1 addition & 1 deletion .nycrc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ reporter:
check-coverage: true
branches: 61.51
lines: 70.85
functions: 73.21
functions: 73.08
statements: 70.54
37 changes: 13 additions & 24 deletions lib/winston/logger.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,15 @@

const { Stream, Transform } = require('readable-stream');
const asyncForEach = require('async/forEach');
const { LEVEL, SPLAT } = require('triple-beam');
const { LEVEL, SPLAT, MESSAGE } = require('triple-beam');
const isStream = require('is-stream');
const ExceptionHandler = require('./exception-handler');
const RejectionHandler = require('./rejection-handler');
const LegacyTransportStream = require('winston-transport/legacy');
const Profiler = require('./profiler');
const { warn } = require('./common');
const config = require('./config');
const jsonStringify = require('safe-stable-stringify');

/**
* Captures the number of format (i.e. %s strings) in a given string.
Expand All @@ -42,30 +43,12 @@ class Logger extends Transform {
this.configure(options);
}

child(defaultRequestMetadata) {
child(childMetadata) {
const logger = this;
const clonedParentMetadata = JSON.parse(jsonStringify(this.defaultMeta));
return Object.create(logger, {
write: {
value: function (info) {
const infoClone = Object.assign(
{},
defaultRequestMetadata,
info
);

// Object.assign doesn't copy inherited Error
// properties so we have to do that explicitly
//
// Remark (indexzero): we should remove this
// since the errors format will handle this case.
//
if (info instanceof Error) {
infoClone.stack = info.stack;
infoClone.message = info.message;
}

logger.write(infoClone);
}
defaultMeta: {
value: Object.assign({}, clonedParentMetadata, childMetadata)
}
});
}
Expand Down Expand Up @@ -288,6 +271,10 @@ class Logger extends Transform {
info[LEVEL] = info.level;
}

if (!info[MESSAGE]) {
info[MESSAGE] = info.message;
}

// Remark: really not sure what to do here, but this has been reported as
// very confusing by pre [email protected] users as quite confusing when using
// custom levels.
Expand Down Expand Up @@ -647,7 +634,9 @@ class Logger extends Transform {

_addDefaultMeta(msg) {
if (this.defaultMeta) {
Object.assign(msg, this.defaultMeta);
// The msg must be cloned as it is being mutated, but any metadata provided with the msg takes precedence over default
const msgClone = JSON.parse(jsonStringify(msg));
Object.assign(msg, this.defaultMeta, msgClone);
}
}
}
Expand Down
7 changes: 5 additions & 2 deletions lib/winston/profiler.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ module.exports = class Profiler {
* @private
*/
constructor(logger) {
// TODO there is no restriction on what the Profiler considers a Logger. As such there is no guarantees it adheres
// to the proper interface. This needs to hardened.
if (!logger) {
throw new Error('Logger is required for profiling.');
}
Expand All @@ -32,7 +34,8 @@ module.exports = class Profiler {
/**
* Ends the current timer (i.e. Profiler) instance and logs the `msg` along
* with the duration since creation.
* @returns {mixed} - TODO: add return description.
* @returns {boolean} - `false` if the logger stream wishes for the calling code to wait for the 'drain' event to be
* emitted before continuing to write additional data; otherwise `true`
* @private
*/
done(...args) {
Expand All @@ -45,7 +48,7 @@ module.exports = class Profiler {
const info = typeof args[args.length - 1] === 'object' ? args.pop() : {};
info.level = info.level || 'info';
info.durationMs = (Date.now()) - this.start;

if (this.logger._addDefaultMeta) this.logger._addDefaultMeta(info);
return this.logger.write(info);
}
};
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "winston",
"description": "A logger for just about everything.",
"version": "3.8.2",
"version": "3.9.2-RC.0",
"author": "Charlie Robbins <[email protected]>",
"maintainers": [
"David Hyde <[email protected]>"
Expand Down
22 changes: 20 additions & 2 deletions test/helpers/mocks/mock-transport.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
const stream = require('stream')
const winston = require('../../../lib/winston');
const {Writable} = require("stream");

/**
* Returns a new Winston transport instance which will invoke
* the `write` method on each call to `.log`
* the `write` method on each call to `.log`
*
* @param {function} write Write function for the specified stream
* @returns {StreamTransportInstance} A transport instance
Expand All @@ -17,6 +18,23 @@ function createMockTransport(write) {
return new winston.transports.Stream({ stream: writeable })
}

/**
* Returns a valid Winston transport that writes to the passed array object
* @param array Array to be used to store the "written" chunks
* @returns {winston.transports.Stream}
*/
function inMemory(array, options = {}) {
const memoryStream = new Writable({
objectMode: true,
write: (chunk, encoding, next) => {
array.push(chunk);
next()
}
});
return new winston.transports.Stream({stream: memoryStream, ...options})
}

module.exports = {
createMockTransport
createMockTransport,
inMemory
};
Loading