微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

node.js – 使用Mongoose Docs进行Winston记录

我最近刚切换到Winston进行日志记录,并注意到在exec之后记录mongoose文档时出现问题.

例:

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()进行记录之前必须如何被序列化.

我是否每次都必须手动调用.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 举报,一经查实,本站将立刻删除。

相关推荐