Winston: Alto uso da CPU ao habilitar "prettyPrint"

Criado em 4 set. 2018  ·  3Comentários  ·  Fonte: winstonjs/winston

Conte-nos sobre o seu ambiente:

Qual é o problema?

Ao ter registro intenso usando várias estruturas JSON e opção prettyPrint habilitada, o winston aumentaria a CPU para 90% +

Usando o seguinte transporte configurado para reproduzir o problema:

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

Pode estar relacionado a https://github.com/winstonjs/winston/issues/613

O que você espera que aconteça em vez disso?

Nenhum pico de CPU usando Winston e prettyPrint habilitado

Outra informação

Ao desabilitar o prettyPrint ou usar versões stringificadas das estruturas JSON antes do registro, os picos de CPU desaparecem completamente.

Configuração de transporte modificada para resolver os picos de 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;
            })
          )
        })
docs

Comentários muito úteis

Vou deixar isso aberto porque devemos adicionar alguns documentos ao winston ou logform.

Dos documentos do Node.js em util.inspect (https://nodejs.org/api/util.html#util_util_inspect_object_options):

Observe que util.inspect () é um método síncrono cujo objetivo principal é ser uma ferramenta de depuração. Alguns valores de entrada podem ter uma sobrecarga de desempenho significativa que pode bloquear o loop de eventos. Use esta função com cuidado e nunca em um caminho de código ativo.

Portanto, o Node recomenda não usar isso no código de produção, portanto, provavelmente devemos mencionar em algum lugar que os usuários não devem usar prettyPrint no código de produção. Dito isso, aposto que se expuséssemos um parâmetro de profundidade para prettyPrint, isso poderia ajudar no desempenho.

Obrigado por trazer isso à tona, acho que é uma observação importante!

Todos 3 comentários

Quão profundos / complicados são seus objetos JSON? util.inspect, que é o que usamos para impressão bonita, pode se tornar muito lento para objetos suficientemente complicados (talvez até mesmo loop infinito se houver estruturas cíclicas). Você precisa registrar todo o seu objeto ou ficaria feliz apenas com as primeiras camadas dele (parâmetro de profundidade)?

No momento, as estruturas JSON que estou registrando são essencialmente uma matriz de objetos; os objetos são classes instanciadas, seu número vai de 10 a 100 itens e sua complexidade nunca atinge um nível de profundidade de 3 (sem estruturas cíclicas).

No entanto, eu os registro com muita frequência: atingindo a frequência máxima de um registro a cada 200/500 ms.

O registro de estruturas complexas só é útil no ambiente de desenvolvimento ao usar verbosidade "tola".
Já que a verbosidade "boba" deve ser "boba" o suficiente (^^), eu resolvi desabilitar a impressão bonita e obter todos os dados complexos sem qualquer limite de profundidade, atraso ou uso pesado da CPU.

Eu não sabia que "util.inspect" podia ser tão lento em comparação com um JSON.stringify; provavelmente um parâmetro de profundidade pode ser suficiente para remover o pico (eu poderia testá-lo no meu tempo livre se você precisar de mais dados para entender melhor a situação)

Vou deixar isso aberto porque devemos adicionar alguns documentos ao winston ou logform.

Dos documentos do Node.js em util.inspect (https://nodejs.org/api/util.html#util_util_inspect_object_options):

Observe que util.inspect () é um método síncrono cujo objetivo principal é ser uma ferramenta de depuração. Alguns valores de entrada podem ter uma sobrecarga de desempenho significativa que pode bloquear o loop de eventos. Use esta função com cuidado e nunca em um caminho de código ativo.

Portanto, o Node recomenda não usar isso no código de produção, portanto, provavelmente devemos mencionar em algum lugar que os usuários não devem usar prettyPrint no código de produção. Dito isso, aposto que se expuséssemos um parâmetro de profundidade para prettyPrint, isso poderia ajudar no desempenho.

Obrigado por trazer isso à tona, acho que é uma observação importante!

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

greenhat616 picture greenhat616  ·  3Comentários

bertolo1988 picture bertolo1988  ·  3Comentários

pocesar picture pocesar  ·  3Comentários

kjin picture kjin  ·  3Comentários

Buzut picture Buzut  ·  3Comentários