Winston: 启用“prettyPrint”时 CPU 使用率高

创建于 2018-09-04  ·  3评论  ·  资料来源: winstonjs/winston

请告诉我们您的环境:

问题是什么?

当使用多个JSON 结构并启用了PrettyPrint选项进行密集日志记录时,winston 会使CPU 飙升至 90% 以上

使用以下配置的传输来重现问题:

new (winston.transports.Console)({
          level: 'silly',
          silent: false,
          colorize: true,
          prettyPrint: true,
          timestamp: true,
          humanReadableUnhandledException: true,
          format: format.combine(
            format.splat(),
            format.colorize(),
            format.label({ label: 'Foo' }),
            format.timestamp(),
            format.prettyPrint(),
            format.printf( log => {
              return '[ ' + log.timestamp + ' ][ ' + log.level + ' ][ ' + log.label + ' ] ' + log.message;
            })
          )
        })

可能与https://github.com/winstonjs/winston/issues/613有关

你期望发生什么?

使用 Winston 和 PrettyPrint 没有 CPU 峰值

其他信息

通过在记录之前禁用 PrettyPrint 或使用字符串化版本的 JSON 结构,CPU 峰值完全消失。

修改传输配置以解决 CPU 峰值:

new (winston.transports.Console)({
          level: 'silly',
          silent: false,
          colorize: true,
          prettyPrint: false, // Forced disabled pretty print
          timestamp: true,
          humanReadableUnhandledException: true,
          format: format.combine(
            format.splat(),
            format.colorize(),
            format.label({ label: 'Foo' }),
            format.timestamp(),
            //format.prettyPrint(), // Removed prettyPrint from format
            format.printf( log => {
              return '[ ' + log.timestamp + ' ][ ' + log.level + ' ][ ' + log.label + ' ] ' + log.message;
            })
          )
        })

最有用的评论

我将保持开放状态,因为我们应该向 winston 或 logform 添加一些文档。

来自 util.inspect (https://nodejs.org/api/util.html#util_util_inspect_object_options) 上的 Node.js 文档:

请注意 util.inspect() 是一种同步方法,主要用作调试工具。 某些输入值可能会产生显着的性能开销,从而阻塞事件循环。 小心使用此函数,切勿在热代码路径中使用。

所以 Node 建议不要在生产代码中使用它,因此我们可能应该在某处提到用户不应该在生产代码中使用prettyPrint。 也就是说,我敢打赌,如果我们为 prettyPrint 公开一个深度参数,它将有助于提高性能。

感谢您提出这个问题,我认为这是一个重要的说明!

所有3条评论

你的 JSON 对象有多深/有多复杂? util.inspect,这是我们用于漂亮打印的,对于足够复杂的对象可能会变得非常慢(如果有循环结构,甚至可能是无限循环)。 您需要记录整个对象,还是只对它的前几层(深度参数)感到满意?

现在我记录的 JSON 结构本质上是一个对象数组; 对象是实例化的类,它们的数量从 10 到 100 个项目,它们的复杂性永远不会达到 3 的深度级别(没有循环结构)。

但是我经常记录它们:每 200/500 毫秒达到一个日志的最大频率。

复杂结构的日志记录仅在使用“愚蠢”冗长的开发环境中才有用。
由于“愚蠢”的冗长应该足够“愚蠢”(^^),我只是通过禁用漂亮打印来解决并获取所有复杂数据,而没有任何深度限制、延迟或大量 CPU 使用。

与 JSON.stringify 相比,我不知道“util.inspect”会这么慢; 可能深度参数足以消除尖峰(如果您需要更多数据以更好地了解情况,我可以在业余时间对其进行测试)

我将保持开放状态,因为我们应该向 winston 或 logform 添加一些文档。

来自 util.inspect (https://nodejs.org/api/util.html#util_util_inspect_object_options) 上的 Node.js 文档:

请注意 util.inspect() 是一种同步方法,主要用作调试工具。 某些输入值可能会产生显着的性能开销,从而阻塞事件循环。 小心使用此函数,切勿在热代码路径中使用。

所以 Node 建议不要在生产代码中使用它,因此我们可能应该在某处提到用户不应该在生产代码中使用prettyPrint。 也就是说,我敢打赌,如果我们为 prettyPrint 公开一个深度参数,它将有助于提高性能。

感谢您提出这个问题,我认为这是一个重要的说明!

此页面是否有帮助?
0 / 5 - 0 等级