如何像 console.log 那样在 winston 中记录 JavaScript 对象和数组?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/33158974/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 14:43:05  来源:igfitidea点击:

How to log JavaScript objects and arrays in winston as console.log does?

javascriptarraysnode.jsloggingwinston

提问by Tommz

I was looking at top Node logging systems: npmlog, log4js, bunyanand winstonand decided to use winstonfor having the most npmmonthly downloads.

我一直在寻找顶级节点记录系统:npmloglog4jsbunyanwinston,决定使用winston具有最npm每月下载。

What I want to set up is custom logger which I will be able to use on development environment with logger.debug(...)which won't log anything on production environment. This will help me so when I'm on development environment, I won't need to write anything since I'll see all the outputs.

我想要设置的是自定义记录器,我将能够在开发环境中使用logger.debug(...)它,而不会在生产环境中记录任何内容。这对我有帮助,所以当我在开发环境中时,我不需要写任何东西,因为我会看到所有的输出。

This is what I have now:

这就是我现在所拥有的:

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

Problem occurs when I'm trying to log JavaScript Objector Javascript Array. With Object, I need to do toJSON(), and for ArrayI need first JSON.stringify()and then JSON.parse().

当我尝试记录 JavaScriptObject或 Javascript时出现问题Array。有了Object,我需要做的toJSON(),对于Array我需要的JSON.stringify(),然后JSON.parse()

It's not nice to write all the time this methods, just to log something that I want. Furthermore, it's not even resource-friendly, because those formatting methods need to be executed before logger.debug()realises that it's on production and that it shouldn't log it in the first place (basically, it's evaluating arguments before function call). I just like how old-fashined console.log()logs JavaScript objects and arrays.

一直写这种方法并不好,只是为了记录我想要的东西。此外,它甚至不是资源友好的,因为这些格式化方法需要在logger.debug()意识到它正在生产并且首先不应该记录它之前执行(基本上,它是在函数调用之前评估参数)。我只是喜欢旧式的console.log()记录 JavaScript 对象和数组的方式。

Now, as I'm writing this question, I found that there is a way of describing custom formatfor every winston transportsobject. Is that the way of doing it, or is there some other way?

现在,当我写这个问题时,我发现有一种方法可以描述每个 winston对象的自定义格式transports。这是这样做的方式,还是有其他方式?

采纳答案by Bharat Kul Ratan

try changing prettyPrint parameter to

尝试将prettyPrint参数更改为

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

回答by Leo

logger.log("info", "Starting up with config %j", config);

Winstons uses the built-in utils.format library. https://nodejs.org/dist/latest/docs/api/util.html#util_util_format_format_args

Winstons 使用内置的 utils.format 库。 https://nodejs.org/dist/latest/docs/api/util.html#util_util_format_format_args

回答by smith64fx

In Winston > 3 you can use

在温斯顿 > 3 你可以使用

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

Anyway... Couldn't accept that I have to use %o always and made this simple solution:

无论如何......无法接受我必须始终使用 %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({})
  ],
})

So this logger....

所以这个记录器......

  logger.info({ hi: 123 })

...transforms to this in the console

...在控制台中转换为

info: {
    "hi": 123
}

回答by Radon Rosborough

Use the built-in Node.js function util.formatto convert your objects to strings in the same way that console.logdoes.

使用内置的 Node.js 函数util.format以相同的方式将您的对象转换为字符串console.log

回答by ambrons

My recommendation is to write your own abstraction on top of winston that has a convenience method for printing your objects for debugging.

我的建议是在 winston 之上编写自己的抽象,它具有打印对象以进行调试的便捷方法。

You may also look at this response for a hint of how the method could be developed.

您还可以查看此回复以获取有关如何开发该方法的提示。

https://stackoverflow.com/a/12620543/2211743

https://stackoverflow.com/a/12620543/2211743

回答by K435

As Leo already pointed out in his answer, Winston makes use of String Interpolationprovided by util.format:

正如 Leo 在他的回答中已经指出的那样,Winston 使用了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);                                                                                                                                                                                                                                  

When calling logger.log, you can define placeholders which will be appropriately replaced. %jwill be replaced by the equivalent of JSON.stringify(nestedObj)

调用时logger.log,您可以定义将被适当替换的占位符。%j将被替换为相当于JSON.stringify(nestedObj)

回答by Atishay Jain

Instead of doing

而不是做

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

it's better go with utils-deep-clonepackage

最好使用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)
}

if you'll go with JSON.stringifyyou won't be able to print error

如果你去,JSON.stringify你将无法打印错误

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

回答by logeekal

Try using util.inspect for objects. It handles circular references correctly as well. @radon-rosborough has already given this answer but I thought of adding an example. Please see below

尝试对对象使用 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,
                } )}`;
            })
        )
    })
]