例:
Model.find().exec(function (err,docs) { console.log(docs) // Prints the collection fine winston.info(docs) // Prints a ton on mongoose stuff,related to the query });
那么基本上我如何让winston日志记录以与从console.log获得的方式相同的方式进行打印?我猜它在通过调用toJSON()进行记录之前必须如何被序列化.
解决方法
我认为winston的预期用途是首先记录字符串消息,并(如果需要)记录其他元信息.此外,我不明白为什么你想记录从mongo返回的整个集合而不是 – 比方说 – 只是_ids(假设文档可能相当大).
介绍
我查看了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); ... }
基本上,类型对象的单个参数被解释为元.
控制台传输层(默认)主要在winston / common.js中定义,以下是元的处理方式:
... if (Object.keys(Meta).length > 0) { output += ' ' + ( options.prettyPrint ? ('\n' + util.inspect(Meta,false,null,options.colorize)) : exports.serialize(Meta) ); }
serialize方法迭代(递归地)对象的所有键以形成最终字符串(而不是调用.toString或类似的).
提出的解决方案
两种解决方案都强制winston将单个对象参数解释为Meta而不是消息字符串.
更改winston源代码
只需对repo进行分叉并对源代码进行相关更改.有很多方法可以实现它.一个丑陋的可能是:
Meta = args.length === 1 ? {} : (typeof args[args.length - 1] === 'object' ? args.pop() : {}),
但更好的是在.serialize方法中添加特殊情况如果对象是mangoose模型则进行特殊处理,非常天真且不正确:
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 += '}'; }
(不幸的是,这种方法存在问题,因为winston制作了Meta的副本,并且在原型链中定义得更高的所有方法都丢失了 – 否则它就像调用obj.toJSON一样容易,并且肯定会是最优雅和最健壮的解)
覆盖winston默认行为
var original = winston.log; winston.log = function(){ if(arguments.length === 2){ original.call(winston,arguments[0],arguments[1],{}); } else { original.apply(winston,arguments); } }
说明:arguments [0]定义级别,因此arguments [1]是要记录的实际对象.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。