Skip to content
Merged
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ simplest way to do this is using `winston.createLogger`:
const logger = winston.createLogger({
level: 'info',
format: winston.format.json(),
defaultMeta: {service: 'user-service'},
transports: [
//
// - Write to all logs with level `info` and below to `combined.log`
Expand Down Expand Up @@ -191,6 +192,20 @@ logger.configure({
});
```

### Creating child loggers

You can create child loggers from existing loggers to pass metadata overrides:

``` js
const logger = winston.createLogger({
transports: [
new winston.transports.Console(),
]
});

const childLogger = logger.child({ req_id: '451' });
```

### Streams, `objectMode`, and `info` objects

In `winston`, both `Logger` and `Transport` instances are treated as
Expand Down
1 change: 1 addition & 0 deletions lib/winston/create-logger.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ class DerivedLogger extends Logger {
const [msg] = args;
const info = msg && msg.message && msg || { message: msg };
info.level = info[LEVEL] = level;
this._addDefaultMeta(info);
this.write(info);
return this;
}
Expand Down
47 changes: 41 additions & 6 deletions lib/winston/logger.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,40 @@ const config = require('./config');
*/
class Logger extends Transform {
/**
* Constructor function for the Logger object responsible for persisting log
* messages and metadata to one or more transports.
* @param {!Object} options - foo
*/
* Constructor function for the Logger object responsible for persisting log
* messages and metadata to one or more transports.
* @param {!Object} options - foo
*/
constructor(options) {
super({
objectMode: true
});
this.configure(options);
}

child(defaultRequestMetadata) {
const logger = this;
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
if (info instanceof Error) {
infoClone.stack = info.stack;
infoClone.message = info.message;
}

logger.write(infoClone);
}
}
});
}

/**
* This will wholesale reconfigure this instance by:
* 1. Resetting all transports. Older transports will be removed implicitly.
Expand All @@ -46,6 +69,7 @@ class Logger extends Transform {
configure({
silent,
format,
defaultMeta,
levels,
level = 'info',
exitOnError = true,
Expand All @@ -66,6 +90,7 @@ class Logger extends Transform {
this.silent = silent;
this.format = format || this.format || require('logform/json')();

this.defaultMeta = defaultMeta || null;
// Hoist other options onto this instance.
this.levels = levels || this.levels || config.npm.levels;
this.level = level;
Expand Down Expand Up @@ -153,6 +178,7 @@ class Logger extends Transform {
// In this context the LHS `level` here is actually the `info` so read
// this as: info[LEVEL] = info.level;
level[LEVEL] = level.level;
this._addDefaultMeta(level);
this.write(level);
return this;
}
Expand All @@ -161,6 +187,7 @@ class Logger extends Transform {
if (arguments.length === 2) {
if (msg && typeof msg === 'object') {
msg[LEVEL] = msg.level = level;
this._addDefaultMeta(msg);
this.write(msg);
return this;
}
Expand All @@ -176,14 +203,16 @@ class Logger extends Transform {
[SPLAT]: splat.slice(1),
level,
message: msg
}));
},
this.defaultMeta));
} else {
this.write(Object.assign({}, {
[LEVEL]: level,
[SPLAT]: splat,
level,
message: msg
}));
},
this.defaultMeta));
}

return this;
Expand Down Expand Up @@ -535,6 +564,12 @@ class Logger extends Transform {
transport.on(event, transport['__winston' + event]);
}
}

_addDefaultMeta(msg) {
if (this.defaultMeta) {
Object.assign(msg, this.defaultMeta);
}
}
}

function getLevelValue(levels, level) {
Expand Down
28 changes: 21 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 4 additions & 8 deletions test/helpers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@
*
*/

var assume = require('assume'),
const assume = require('assume'),
fs = require('fs'),
path = require('path'),
through = require('through2'),
spawn = require('child_process').spawn,
stream = require('stream'),
util = require('util'),
winston = require('../../lib/winston');
winston = require('../../lib/winston'),
mockTransport = require('./mocks/mock-transport');

var helpers = exports;

Expand All @@ -25,15 +26,10 @@ var helpers = exports;
* @returns {Logger} A winston.Logger instance
*/
helpers.createLogger = function (write, format) {
var writeable = new stream.Writable({
objectMode: true,
write: write
});

return winston.createLogger({
format,
transports: [
new winston.transports.Stream({ stream: writeable })
mockTransport.createMockTransport(write)
]
});
};
Expand Down
22 changes: 22 additions & 0 deletions test/helpers/mocks/mock-transport.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
const stream = require('stream')
const winston = require('../../../lib/winston');

/**
* Returns a new Winston transport instance which will invoke
* the `write` method on each call to `.log`
*
* @param {function} write Write function for the specified stream
* @returns {StreamTransportInstance} A transport instance
*/
function createMockTransport(write) {
const writeable = new stream.Writable({
objectMode: true,
write: write
});

return new winston.transports.Stream({stream: writeable})
}

module.exports = {
createMockTransport
};
Loading