Skip to content

Commit

Permalink
[refactor] Make some performance optimizations for `Logger.prototype.…
Browse files Browse the repository at this point in the history
…log`.
  • Loading branch information
indexzero committed Oct 29, 2015
1 parent 0d955d3 commit 3747ccf
Showing 1 changed file with 61 additions and 38 deletions.
99 changes: 61 additions & 38 deletions lib/winston/logger.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,22 +104,27 @@ Logger.prototype.configure = function (options) {
// Core logging method exposed to Winston. Metadata is optional.
//
Logger.prototype.log = function (level) {
var self = this,
args = Array.prototype.slice.call(arguments, 1);
var args = Array.prototype.slice.call(arguments, 1),
self = this,
transports;

while(args[args.length - 1] === null) {
while (args[args.length - 1] === null) {
args.pop();
}

//
// Determining what is `meta` and what are arguments for string interpolation
// turns out to be VERY tricky. e.g. in the cases like this:
//
// logger.info('No interpolation symbols', 'ok', 'why', { meta: 'is-this' });
//
var callback = typeof args[args.length - 1] === 'function' ? args.pop() : null,
meta = typeof args[args.length - 1] === 'object' && Object.prototype.toString.call(args[args.length - 1]) !== '[object RegExp]' ? args.pop() : {},
msg = util.format.apply(null, args);

// If we should pad for levels, do so
if (this.padLevels) {
msg = new Array(this.levelLength - level.length + 1).join(' ') + msg;
}

//
// Handle errors appropriately.
//
function onError(err) {
if (callback) {
callback(err);
Expand All @@ -129,13 +134,49 @@ Logger.prototype.log = function (level) {
}
}

if (Object.keys(this.transports).length === 0) {
if (this._names.length === 0) {
return onError(new Error('Cannot log with no transports.'));
}
else if (typeof self.levels[level] === 'undefined') {
return onError(new Error('Unknown log level: ' + level));
}

//
// If there are no transports that match the level
// then be eager and return. This could potentially be calculated
// during `setLevels` for more performance gains.
//
var targets = this._names.filter(function (name) {
var transport = self.transports[name];
return (transport.level && self.levels[transport.level] >= self.levels[level])
|| (!transport.level && self.levels[self.level] >= self.levels[level]);
});

if (!targets.length) {
if (callback) { callback(); }
return;
}

//
// Respond to the callback.
//
function finish(err) {
if (callback) {
if (err) return callback(err);
callback(null, level, msg, meta);
}

callback = null;
if (!err) {
self.emit('logged', level, msg, meta);
}
}

// If we should pad for levels, do so
if (this.padLevels) {
msg = new Array(this.levelLength - level.length + 1).join(' ') + msg;
}

this.rewriters.forEach(function (rewriter) {
meta = rewriter(level, msg, meta, self);
});
Expand Down Expand Up @@ -165,39 +206,21 @@ Logger.prototype.log = function (level) {
//
// Log for each transport and emit 'logging' event
//
function emit(name, next) {
function transportLog(name, next) {
var transport = self.transports[name];
if ((transport.level && self.levels[transport.level] >= self.levels[level])
|| (!transport.level && self.levels[self.level] >= self.levels[level])) {
transport.log(level, msg, meta, function (err) {
if (err) {
err.transport = transport;
cb(err);
return next();
}
self.emit('logging', transport, level, msg, meta);
next();
});
} else {
next();
}
}
transport.log(level, msg, meta, function (err) {
if (err) {
err.transport = transport;
finish(err);
return next();
}

//
// Respond to the callback
//
function cb(err) {
if (callback) {
if (err) return callback(err);
callback(null, level, msg, meta);
}
callback = null;
if (!err) {
self.emit('logged', level, msg, meta);
}
self.emit('logging', transport, level, msg, meta);
next();
});
}

async.forEach(this._names, emit, cb);
async.forEach(targets, transportLog, finish);
return this;
};

Expand Down

0 comments on commit 3747ccf

Please sign in to comment.