Как сделать так, чтобы библиотека журналов winston работала как `console.log`? - PullRequest
1 голос
/ 28 марта 2019

Библиотека 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().

Ответы [ 2 ]

0 голосов
/ 02 июля 2019

Отвечая на мой собственный вопрос.Проблема с format.splat - pure 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} "
0 голосов
/ 03 июня 2019

Для всех, кто придет к этому вопросу в будущем, смущенный документацией, единственный способ, которым я смог достичь этого, был путем добавления Console транспорта, объединяющего splat() and simple () formats. i also added colorized`, когда я нахожу Цветовое кодирование особенно полезно. этот пример показан в документах, но документы повсюду и сбивают с толку. надеюсь, это поможет.

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);
})

использование:

_log(someObject) //should log the object same as console.log does
_log('app running on port %d',3000) //should printf like console.log does
...