nodejs winston - 使用多个参数进行记录

时间:2013-02-12 16:49:49

标签: node.js winston

我试图使用winston进行日志记录,但我看到如果我想用2个arg获取数据,那么我得到了日志,但如果我想得到3个参数,那么我没有得到数据,

例如:

logger = new (winston.Logger)({
transports: [
   new (winston.transports.Console)({colorize : true, timestamp:true}),
 ]
});

现在尝试获取如下日志:

 1. logger.info("We got the data %s, %d", data, port);
 O/P: We got the data %s, %d  => No data and port value
 2. logger.info("We got the data, port", data, port);
 O/P: We got the data, port   => No data and port value
 3. logger.info("We got the data", data);
 ===> Getting the data correctly.

你能不能让我知道我在1,2中丢失了什么,或者winston没有记录案例1和1中的数据。 2真的吗?

4 个答案:

答案 0 :(得分:3)

您假设有一个varargs样式API,但没有。完整的API是level, msg, meta, callback,但是当您使用其中一种方法时,它只是msg, meta, callback。您需要构造一个meta对象并传递它。

https://github.com/flatiron/winston/blob/master/lib/winston/logger.js#L115

//
// ### function log (level, msg, [meta], callback)
// #### @level {string} Level at which to log the message.
// #### @msg {string} Message to log
// #### @meta {Object} **Optional** Additional metadata to attach
// #### @callback {function} Continuation to respond to when complete.
// Core logging method exposed to Winston. Metadata is optional.
//

https://github.com/flatiron/winston#logging-with-metadata

答案 1 :(得分:1)

我通过包装winston函数和使用包装器解决了这个问题。我希望现在有更好的解决方案。

var logger = new (winston.Logger)({
        transports:[new (winston.transports.Console)({ json : false, timestamp : true, level : 0, colorize : true}),
                    new (winston.transports.File)({ filename: filepath, json : false, timestamp : true, level : 0, colorize: true })]
    });

// pass in function arguments object and returns string with whitespaces
function argumentsToString(v){
    // convert arguments object to real array
    var args = Array.prototype.slice.call(v);
    for(var k in args){
        if (typeof args[k] === "object"){
            // args[k] = JSON.stringify(args[k]);
            args[k] = util.inspect(args[k], false, null, true);
        }
    }
    var str = args.join(" ");
    return str;
}


    // wrapping the winston function to allow for multiple arguments
    var wrap = {};
    wrap.info = function () {
        logger.log.apply(logger, ["info", argumentsToString(arguments)]);
    };

    wrap.error = function () {
        logger.log.apply(logger, ["error", argumentsToString(arguments)]);
    };

    wrap.warn = function () {
        logger.log.apply(logger, ["warn", argumentsToString(arguments)]);
    };

    wrap.debug = function () {
        logger.log.apply(logger, ["debug", argumentsToString(arguments)]);
    };

///然后返回换行,因为它是你的记录器。 ///并使用像log.info(1,2,3,4,“foo”,“bar”);

答案 2 :(得分:0)

由于Winston API不能像console.log那样工作,因此一种解决方法是创建一个包装器函数,该函数可以通过以下方式利用util.format

const util = require('util')   

...

function log(...msg) {
  logger.info(util.format(...msg))
}

然后您可以像这样调用日志:    log('my log entry', 'foo, 'bar')

将这样记录:{"message":"my log entry foo bar","level":"info"}

答案 3 :(得分:0)

这对我和Winston 3.2.x都有效:

const { format, createLogger, transports } = require('winston');
const jsonStringify = require('fast-safe-stringify');

const logLikeFormat = {
  transform(info) {
    const { timestamp, label, message } = info;
    const level = info[Symbol.for('level')];
    const args = info[Symbol.for('splat')];
    const strArgs = args.map(jsonStringify).join(' ');
    info[Symbol.for('message')] = `${timestamp} [${label}] ${level}: ${message} ${strArgs}`;
    return info;
  }
};

const debugFormat = {
  transform(info) {
    console.log(info);
    return info;
  }
};

const logger = createLogger({
  format: format.combine(
    // debugFormat, // uncomment to see the internal log structure
    format.timestamp(),
    format.label({ label: 'myLabel' }),
    logLikeFormat,
    // debugFormat, // uncomment to see the internal log structure
  ),
  transports: [
    new transports.Console()
  ]
});


logger.info('foo', 'bar', 1, [2, 3], true, { name: 'John' });

其结果是:2019-07-04T21:30:08.455Z [myLabel] info: foo "bar" 1 [2,3] true {"name":"John"}

基本上format.combine设置info对象的管道。对于每个格式函数,将调用transform,最后的日志消息应写入info[Symbol.for('message')] 希望对您有帮助