Warning
I think the intended use of winston is to log string messages in first place and (if needed) additional meta information. Moreover, I do not quite get why you would like to log the whole collection returned from mongo and not - let say - just _id
s (assuming docs
may be pretty big).
Intro
I looked into winston
source and here are relevant parts:
winston/logger.js
Logger.prototype.log = function (level) {
var self = this,
args = Array.prototype.slice.call(arguments, 1);
...
var callback = typeof args[args.length - 1] === 'function' ? args.pop() : null,
meta = typeof args[args.length - 1] === 'object' ? args.pop() : {},
msg = util.format.apply(null, args);
...
}
Basically, single argument of type object
is interpreted as the meta.
Console transport layer (default) is mainly defined in winston/common.js and here is how meta is handled:
... if (Object.keys(meta).length > 0) {
output += ' ' + (
options.prettyPrint
? ('\n' + util.inspect(meta, false, null, options.colorize))
: exports.serialize(meta)
);
}
serialize method iterates (recursively) over all keys of an object to form the final string (instead of calling .toString
or similar).
Proposed Solutions
Both solutions force winston to interpret a single object argument not as meta but as the message string.
If you want to support different transport layers than they have to be modified.
Change winston source-code
Just fork the repo and make relevant changes to the source code. There is plenty of ways to accomplish it. One ugly could be:
meta = args.length === 1 ? {} :
(typeof args[args.length - 1] === 'object' ? args.pop() : {}),
But much better would be to add special case in the .serialize
method make special treatment if the object is mangoose model, very naive and incorrect:
else if ('_doc' in obj && 'save' in obj){
var result = [];
msg += '{'
for(var key in obj['_doc']){
result.push (key + ':' + obj['_doc'][key]);
}
msg += result.join(', ');
msg += '}';
}
(Unfortunately there is a problem with this approach, as winston makes copy of the meta and all methods defined higher in prototypical chain are lost -- otherwise it would as easy as calling obj.toJSON
and for sure it would be the most elegant and robust solution)
Override winston default behaviour
var original = winston.log;
winston.log = function(){
if(arguments.length === 2){
original.call(winston, arguments[0], arguments[1], {});
}
else {
original.apply(winston, arguments);
}
}
Explanation: arguments[0]
defines level so arguments[1]
is the actual object to be logged.