Skip to content

Commit 3aa990c

Browse files
committed
[refactor api] Added Logger.prototype.configure which now contains all logic previously in the winston.Logger constructor function.
[api] `winston.Logger` constructor function and `Logger.prototype.configure` set filters in addition to rewriters.
1 parent 8cb7048 commit 3aa990c

File tree

3 files changed

+104
-34
lines changed

3 files changed

+104
-34
lines changed

README.md

+38-2
Original file line numberDiff line numberDiff line change
@@ -95,10 +95,35 @@ You can work with this logger in the same way that you work with the default log
9595
// Adding / Removing Transports
9696
// (Yes It's chainable)
9797
//
98-
logger.add(winston.transports.File)
99-
.remove(winston.transports.Console);
98+
logger
99+
.add(winston.transports.File)
100+
.remove(winston.transports.Console);
100101
```
101102

103+
You can also wholesale reconfigure a `winston.Logger` instance using the `configure` method:
104+
105+
``` js
106+
var logger = new winston.Logger({
107+
level: 'info',
108+
transports: [
109+
new (winston.transports.Console)(),
110+
new (winston.transports.File)({ filename: 'somefile.log' })
111+
]
112+
});
113+
114+
//
115+
// Replaces the previous transports with those in the
116+
// new configuration wholesale.
117+
//
118+
logger.configure({
119+
level: 'verbose',
120+
transports: [
121+
new require('winston-daily-rotate-file')(opts)
122+
]
123+
});
124+
```
125+
126+
102127
### Logging with Metadata
103128
In addition to logging string messages, winston will also optionally log additional JSON metadata objects. Adding metadata is simple:
104129

@@ -641,6 +666,17 @@ Configuring output for this style is easy, just use the `.cli()` method on `wins
641666
### Filters and Rewriters
642667
Filters allow modifying the contents of **log messages**, and Rewriters allow modifying the contents of **log meta** e.g. to mask data that should not appear in logs.
643668

669+
Both filters and rewriters are simple Arrays of functions which can be provided when creating a `new winston.Logger(options)`. e.g.:
670+
671+
``` js
672+
var logger = new winston.Logger({
673+
rewriters: [function (level, msg, meta) { /* etc etc */ }]
674+
filters: [function (msg, meta, level) { /* etc etc */ }]
675+
})
676+
```
677+
678+
Like any Array they can also be modified at runtime with no adverse side-effects to the `winston` internals.
679+
644680
``` js
645681
logger.filters.push(function(msg, meta, level) {
646682
return meta.production

lib/winston/logger.js

+44-32
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,41 @@ var events = require('events'),
2222
//
2323
var Logger = exports.Logger = function (options) {
2424
events.EventEmitter.call(this);
25+
this.configure(options);
26+
};
27+
28+
//
29+
// Inherit from `events.EventEmitter`.
30+
//
31+
util.inherits(Logger, events.EventEmitter);
32+
33+
//
34+
// ### function configure (options)
35+
// This will wholesale reconfigure this instance by:
36+
// 1. Resetting all transports. Older transports will be removed implicitly.
37+
// 2. Set all other options including levels, colors, rewriters, filters,
38+
// exceptionHandlers, etc.
39+
//
40+
Logger.prototype.configure = function (options) {
41+
var self = this;
42+
43+
//
44+
// If we have already been setup with transports
45+
// then remove them before proceeding.
46+
//
47+
if (Array.isArray(this._names) && this._names.length) {
48+
this.clear();
49+
}
50+
2551
options = options || {};
52+
this.transports = {};
53+
this._names = [];
2654

27-
var self = this,
28-
handleExceptions = false;
55+
if (options.transports) {
56+
options.transports.forEach(function (transport) {
57+
self.add(transport, null, true);
58+
});
59+
}
2960

3061
//
3162
// Set Levels and default logging level
@@ -47,40 +78,23 @@ var Logger = exports.Logger = function (options) {
4778
: true;
4879

4980
//
50-
// Setup other intelligent default settings.
81+
// Setup internal state as empty Objects even though it is
82+
// defined lazily later to ensure a strong existential API contract.
5183
//
52-
this.transports = {};
53-
this.rewriters = [];
54-
this.filters = [];
5584
this.exceptionHandlers = {};
5685
this.profilers = {};
57-
this._names = [];
58-
this._hnames = [];
59-
60-
if (options.transports) {
61-
options.transports.forEach(function (transport) {
62-
self.add(transport, null, true);
63-
64-
if (transport.handleExceptions) {
65-
handleExceptions = true;
66-
}
67-
});
68-
}
6986

70-
if (Array.isArray(options.rewriters)) {
71-
this.rewriters = options.rewriters;
72-
}
87+
['rewriters', 'filters'].forEach(function (kind) {
88+
self[kind] = Array.isArray(options[kind])
89+
? options[kind]
90+
: [];
91+
});
7392

7493
if (options.exceptionHandlers) {
7594
this.handleExceptions(options.exceptionHandlers);
7695
}
7796
};
7897

79-
//
80-
// Inherit from `events.EventEmitter`.
81-
//
82-
util.inherits(Logger, events.EventEmitter);
83-
8498
//
8599
// ### function log (level, msg, [meta], callback)
86100
// #### @level {string} Level at which to log the message.
@@ -106,7 +120,7 @@ Logger.prototype.log = function (level) {
106120
msg = new Array(this.levelLength - level.length + 1).join(' ') + msg;
107121
}
108122

109-
function onError (err) {
123+
function onError(err) {
110124
if (callback) {
111125
callback(err);
112126
}
@@ -115,7 +129,6 @@ Logger.prototype.log = function (level) {
115129
}
116130
}
117131

118-
119132
if (Object.keys(this.transports).length === 0) {
120133
return onError(new Error('Cannot log with no transports.'));
121134
}
@@ -185,7 +198,6 @@ Logger.prototype.log = function (level) {
185198
}
186199

187200
async.forEach(this._names, emit, cb);
188-
189201
return this;
190202
};
191203

@@ -230,7 +242,7 @@ Logger.prototype.query = function (options, callback) {
230242
// Helper function to accumulate the results from
231243
// `queryTransport` into the `results`.
232244
//
233-
function addResults (transport, next) {
245+
function addResults(transport, next) {
234246
queryTransport(transport, function (err, result) {
235247
//
236248
// queryTransport could potentially invoke the callback
@@ -456,9 +468,9 @@ Logger.prototype.add = function (transport, options, created) {
456468
// Remove all transports from this instance
457469
//
458470
Logger.prototype.clear = function () {
459-
for (var name in this.transports) {
471+
Object.keys(this.transports).forEach(function (name) {
460472
this.remove({ name: name });
461-
}
473+
}, this);
462474
};
463475

464476
//

test/logger-test.js

+22
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,29 @@ vows.describe('winton/logger').addBatch({
6565
assert.equal(level, 'info');
6666
assert.equal(msg, 'test message');
6767
}
68+
}
69+
}
70+
}
71+
}).addBatch({
72+
"An instance of winston.Logger": {
73+
topic: new (winston.Logger)({ transports: [new (winston.transports.Console)({ level: 'info' })] }),
74+
"the configure() method": {
75+
"with no options": function (logger) {
76+
assert.equal(Object.keys(logger.transports).length, 1);
77+
assert.deepEqual(logger._names, ['console']);
78+
logger.configure();
79+
assert.equal(Object.keys(logger.transports).length, 0);
80+
assert.deepEqual(logger._names, []);
6881
},
82+
"with options { transports }": function (logger) {
83+
assert.equal(Object.keys(logger.transports).length, 0);
84+
assert.deepEqual(logger._names, []);
85+
logger.configure({
86+
transports: [new winston.transports.Console({ level: 'verbose' })]
87+
});
88+
assert.equal(Object.keys(logger.transports).length, 1);
89+
assert.deepEqual(logger._names, ['console']);
90+
}
6991
}
7092
}
7193
}).addBatch({

0 commit comments

Comments
 (0)