Ответ 1
попробуйте изменить параметр prettyPrint на
prettyPrint: function ( object ){
return JSON.stringify(object);
}
Я смотрел на верхние системы регистрации узлов: 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. Это способ сделать это, или есть какой-то другой способ?
попробуйте изменить параметр prettyPrint на
prettyPrint: function ( object ){
return JSON.stringify(object);
}
logger.log("info", "Starting up with config %j", config);
Winstons использует встроенную библиотеку utils.format. https://nodejs.org/dist/latest/docs/api/util.html#util_util_format_format_args
В 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
}
С помощью встроенной функции Node.js util.format
преобразуйте объекты в строки так же, как это делает console.log
.
Моя рекомендация - написать собственную абстракцию поверх winston, которая имеет удобный способ для печати ваших объектов для отладки.
Вы также можете посмотреть этот ответ, чтобы понять, как этот метод может быть разработан.
Как уже указывал Лео в своем ответе, Уинстон использует 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)
Вместо того, чтобы делать
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 '{}'
Попробуйте использовать 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,
} )}';
})
)
})
]