如何使“ winston”日志记录库像“ console.log”一样工作?

时间:2019-03-27 22:58:27

标签: javascript node.js logging winston

winston库非常适合传输和灵活性。我想使用它来配置级别并重定向到文件,但想重现console.log的行为以进行格式化,并遇到麻烦。

这是我到目前为止所拥有的:

const log = winston.createLogger({
  level: 'debug',
  format: format.combine(
    format.timestamp({format: 'YYYY-MM-DD HH:mm:ss.SSS'}),
    format.splat(),
    format.colorize(),
    format.printf(({level, message, label, timestamp}) => `${timestamp} ${label || '-'} ${level}: ${message}`),
  ),
  transports: [
    new winston.transports.Stream({
      stream: process.stderr,
      level: 'debug',
    })
  ],
});

log.info("Hello, %s", "Bob");   // Works: outputs "Hello, Bob"

但这不起作用:

log.info("Hello", "Bob");
log.info("Hello", 123, {someObj: 1});

我希望将splat()占用的所有多余对象添加到上面,并用空格分隔并最好使用util.inspect()转换为字符串。

3 个答案:

答案 0 :(得分:0)

对于将来对文档感到困惑的任何人,我能够实现这一目标的唯一方法是添加结合了Console simple()splat() and的{​​{1}}传输因为我发现颜色编码特别有帮助。此示例显示在文档中,但文档无处不在且令人困惑。希望对您有帮助。

formats. i also added

编辑:为了尽可能将输出匹配到const winston = require('winston'); const format = winston.format; logger.add(new winston.transports.Console({ format: format.combine( format.splat(), format.simple(), format.colorize(), ) })); ,我想出了这一点

console.log

我还使用了一个小型便利包装,如下所示:

logger.add(new winston.transports.Console({
    format: format.combine(
        format.errors({ stack: true }),
        format.splat(),
        format.colorize(),
        format.timestamp(),
        format.printf(({level,message,timestamp,...restProps})=>{
            var retval = `${timestamp} ${level}: `;
            if(message) {
                retval += message;
            }else{
                retval += "\r\n"+util.inspect(JSON.parse(restProps[Symbol.for('message')]));
            }
            return retval;
        })
    )
}));

用法:

function _log(...rest) {
    logger.log('info',...rest);
}

['emerg','alert','crit','error','warning','notice','info','debug'].forEach(fn=>{
    _log[fn] = (...rest) => logger.log(fn,...rest);
})

答案 1 :(得分:0)

回答我自己的问题。问题出在format.splat上-纯util.format提供了更简单,更预期的行为。将format.splat替换为utilFormatter可解决该问题:

const util = require('util');

function transform(info, opts) {
  const args = info[Symbol.for('splat')];
  if (args) { info.message = util.format(info.message, ...args); }
  return info;
}

function utilFormatter() { return {transform}; }

然后我的问题示例如下:

const log = winston.createLogger({
  level: 'debug',
  format: format.combine(
    format.timestamp({format: 'YYYY-MM-DD HH:mm:ss.SSS'}),
    utilFormatter(),     // <-- this is what changed
    format.colorize(),
    format.printf(({level, message, label, timestamp}) => `${timestamp} ${label || '-'} ${level}: ${message}`),
  ),
  transports: [
    new winston.transports.Stream({
      stream: process.stderr,
      level: 'debug',
    })
  ],
});

log.info("Hello, %s", "Bob");          // Works: outputs "Hello, Bob"
log.info("Hello", "Bob");              // Works: outputs "Hello Bob"
log.info("Hello", 123, {someObj: 1});  // Works: outputs "Hello 123 { someObj: 1} "

答案 2 :(得分:-1)

我做了这种解决方法,但是我最终没有使用winston:

const wrapper = (original: any) => {
    return (...args: any[]): any => original(args.map((a) => `${a}`).join(' '))
}

logger.error = wrapper(logger.error)
logger.warn = wrapper(logger.warn)
logger.info = wrapper(logger.info)

顺便说一句,loggerwinston.Logger的实例