Как записывать объекты JavaScript и массивы в winston в качестве console.log?

Я смотрел на верхние системы регистрации узлов: npmlog, log4js, bunyan и winston и решил использовать winston для получения максимальной загрузки в bunyan npm.

То, что я хочу настроить, - это настраиваемый регистратор, который я смогу использовать в среде разработки с помощью logger.debug(...) которая не будет регистрировать ничего в рабочей среде. Это поможет мне, когда я нахожусь в среде разработки, мне не нужно ничего писать, так как я увижу все результаты.

Это то, что у меня есть сейчас:

var level = 'debug';
if (process.env.NODE_ENV !== 'development'){
  level = 'production'; // this will never be logged!
}

var logger = new winston.Logger({
  transports: [
    // some other loggings
    new winston.transports.Console({
      name: 'debug-console',
      level: level,
      prettyPrint: true,
      handleExceptions: true,
      json: false,
      colorize: true
    })

  ],
  exitOnError: false // don't crush no error
});

Проблема возникает, когда я пытаюсь зарегистрировать JavaScript Object или Javascript Array. С Object, мне нужно сделать toJSON(), а для Array мне нужно сначала JSON.stringify() а затем JSON.parse().

Нехорошо писать все это время, просто записывать то, что я хочу. Более того, это не даже дружественно к ресурсам, потому что эти методы форматирования должны быть выполнены до того, как logger.debug() поймет, что он работает, и что он не должен регистрировать его в первую очередь (в основном, он вычисляет аргументы перед вызовом функции), Мне просто нравится, как old-fashined console.log() регистрирует объекты JavaScript и массивы.

Теперь, когда я пишу этот вопрос, я обнаружил, что существует способ описания пользовательского формата для каждого объекта transports winston. Это способ сделать это, или есть какой-то другой способ?

Ответы

Ответ 1

попробуйте изменить параметр prettyPrint на

prettyPrint: function ( object ){
    return JSON.stringify(object);
}

Ответ 3

В Winston> 3 вы можете использовать

logger.log('%o', { lol: 123 }')

Во всяком случае... Не могу согласиться с тем, что я всегда должен использовать% o, и сделал это простое решение:

const prettyJson = format.printf(info => {
  if (info.message.constructor === Object) {
    info.message = JSON.stringify(info.message, null, 4)
  }
  return '${info.level}: ${info.message}'
})

const logger = createLogger({
  level: 'info',
  format: format.combine(
    format.colorize(),
    format.prettyPrint(),
    format.splat(),
    format.simple(),
    prettyJson,
  ),
  transports: [
    new transports.Console({})
  ],
})

Так что этот регистратор....

  logger.info({ hi: 123 })

... превращается в консоль

info: {
    "hi": 123
}

Ответ 4

С помощью встроенной функции Node.js util.format преобразуйте объекты в строки так же, как это делает console.log.

Ответ 5

Моя рекомендация - написать собственную абстракцию поверх winston, которая имеет удобный способ для печати ваших объектов для отладки.

Вы также можете посмотреть этот ответ, чтобы понять, как этот метод может быть разработан.

fooobar.com/questions/1436580/...

Ответ 6

Как уже указывал Лео в своем ответе, Уинстон использует String Interpolation, предоставляемый util.format:

const winston = require("winston");                                                                                                                                                                                                    
const logger = new winston.Logger({                                                                                                                                                                                                    
  transports: [                                                                                                                                                                                                                        
    // some other loggings                                                                                                                                                                                                             
    new winston.transports.Console({                                                                                                                                                                                                   
      name: "debug-console",                                                                                                                                                                                                           
      level: process.env.LOGLEVEL || "info",                                                                                                                                                                                           
      prettyPrint: true,                                                                                                                                                                                                               
      handleExceptions: true,                                                                                                                                                                                                          
      json: false,                                                                                                                                                                                                                     
      colorize: true                                                                                                                                                                                                                   
    })                                                                                                                                                                                                                                 
  ],                                                                                                                                                                                                                                   
  exitOnError: false // don't crush no error                                                                                                                                                                                           
});                                                                                                                                                                                                                                    

const nestedObj = {                                                                                                                                                                                                                    
  foo: {                                                                                                                                                                                                                               
    bar: {                                                                                                                                                                                                                             
      baz: "example"                                                                                                                                                                                                                   
    }                                                                                                                                                                                                                                  
  }                                                                                                                                                                                                                                    
};                                                                                                                                                                                                                                     

const myString = "foo";                                                                                                                                                                                                                

logger.log("info", "my nested object: %j. My string: %s", nestedObj, myString);                                                                                                                                                                                                                                  

При вызове logger.log вы можете определить заполнители, которые будут соответствующим образом заменены. %j будет заменен эквивалентом JSON.stringify(nestedObj)

Ответ 7

Вместо того, чтобы делать

prettyPrint: function ( object ){
    return JSON.stringify(object)
}

лучше использовать пакет utils-deep-clone package

// initialize package on the top
const { toJSON } = require('utils-deep-clone')


// and now in your 'prettyPrint' parameter do this
prettyPrint: function ( object ){
    return toJSON(object)
}

если вы воспользуетесь JSON.stringify, вы не сможете распечатать ошибку

console.log(JSON.stringify(new Error('some error')))
// output will '{}'

Ответ 8

Попробуйте использовать util.inspect для объектов. Также корректно обрабатывает циклические ссылки. @radon-rosborough уже дал этот ответ, но я подумал добавить пример. Пожалуйста, смотрите ниже

const customTransports = [
    new winston.transports.Console({
        format: combine(
            timestamp({
                format: 'DD-MMM-YYYY HH:MM:SS'
            }),
            label({
                label: file
            }),
            prettyPrint(),
            format.splat(),
            simple(),
            printf( (msg)=> {
                let message = msg.message;

                return colorize().colorize(msg.level, '${ msg.level } :  ${msg.timestamp} :  ${ msg.label } : \n') + '${ util.inspect(message,{
                    depth: 2,
                    compact:true,
                    colors: true,
                } )}';
            })
        )
    })
]