如何像 console.log 一样在 winston 中记录 JavaScript 对象和数组?
Posted
技术标签:
【中文标题】如何像 console.log 一样在 winston 中记录 JavaScript 对象和数组?【英文标题】:How to log JavaScript objects and arrays in winston as console.log does? 【发布时间】:2016-01-14 12:39:35 【问题描述】:我正在查看***节点日志记录系统:npmlog
、log4js
、bunyan
和 winston
,并决定使用 winston
来获得最多的 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()
意识到它在生产中并且它不应该首先记录它之前执行(基本上,它是在函数调用之前评估参数)。我只是喜欢老式的 console.log()
记录 JavaScript 对象和数组。
现在,当我写这个问题时,我发现有一种方法可以为每个winston transports
对象描述custom format。是这样做的方式,还是有其他的方式?
【问题讨论】:
【参考方案1】:尝试对对象使用 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,
)`;
)
)
)
]
【讨论】:
【参考方案2】:在 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 )
...在控制台中转换为 this
info:
"hi": 123
【讨论】:
很遗憾,您的答案不适用于:log.silly(`Ok: $ lol: 123 `);
:(
@K-ToxicityinSOisgrowth。你找到解决办法了吗?
@FabZbi 我创建了自己的日志库:github.com/langurama/log【参考方案3】:
而不是做
prettyPrint: function ( object )
return JSON.stringify(object)
最好使用utils-deep-clone 包
// 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 ''
【讨论】:
【参考方案4】:正如 Leo 在他的 answer 中已经指出的那样,Winston 使用了 util.format 提供的 String Interpolation:
const winston = require("winston"); 常量记录器=新的winston.Logger( 运输:[ // 其他一些日志 新的winston.transsports.Console( 名称:“调试控制台”, 级别:process.env.LOGLEVEL || “信息”, 漂亮打印:是的, 处理异常:真, json: 假的, 着色:真 ) ], exitOnError: false // 不粉碎没有错误 ); 常量嵌套对象 = 富: 酒吧: baz:“示例” ; const myString = "foo"; logger.log("info", "我的嵌套对象:%j。我的字符串:%s", nestedObj, myString);
当调用logger.log
时,您可以定义将被适当替换的占位符。 %j
将替换为 JSON.stringify(nestedObj)
的等效项
【讨论】:
【参考方案5】: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
【讨论】:
提供一些解释来解释为什么它会这样工作或 OP 做错了什么。只是这样的代码粘贴会被标记。 我在这里看到的最佳解决方案。使用现有的记录器 api 并漂亮地打印所有内容。 提醒一下,您需要启用 format.splat()。否则它不起作用。【参考方案6】:使用内置的 Node.js 函数 util.format
将对象转换为字符串,方法与 console.log
相同。
【讨论】:
【参考方案7】:尝试将 prettyPrint 参数更改为
prettyPrint: function ( object )
return JSON.stringify(object);
【讨论】:
有趣的事实,你也可以这样做prettyPrint: JSON.stringify
如果object
有循环引用会不会失败?
是的,它绝对会在循环 JSON 中失败。我添加了一个答案,通过使用 util.format 函数解决了问题。【参考方案8】:
我的建议是在 winston 之上编写您自己的抽象,该抽象具有打印对象以进行调试的便捷方法。
您也可以查看此回复以了解如何开发该方法。
https://***.com/a/12620543/2211743
【讨论】:
以上是关于如何像 console.log 一样在 winston 中记录 JavaScript 对象和数组?的主要内容,如果未能解决你的问题,请参考以下文章
在 svelte 中,如何在变量更改时使用 `console.log('yes')`?