Файлы журнала Winston не всегда сохраняются при использовании process.exit () - node js

Я не могу понять эту концепцию ... при использовании process.exit () в программе, которая сохраняет файлы журнала в консоли и в фактический файл, все события журнала распечатываются в консоли, но только первый (или ни одного в все) сохраняются в файл. Вот краткая демонстрация проблемы:

В приведенном ниже коде создается регистратор Winston. Затем в функции numberScore для каждого числа в массиве я создаю журнал, и в конце я регистрирую все события параллельно - просто демонстрация!

var async = require('async')
var winston = require('winston')
var moment = require('moment')

var logger = new (winston.Logger)({
  transports: [
    new (winston.transports.Console)({
      timestamp: function () {
        return moment().format('D/MM/YYYY HH:mm:ss:SSS')
      },
      colorize: true
    }),
    new (require('winston-daily-rotate-file'))({
      filename: 'logs/-system.log',
      datePattern: 'dd-MM-yyyy',
      prepend: true,
      json: false,
      timestamp: function () {
        return moment().format('D/MM/YYYY HH:mm:ss:SSS')
      }
    })
  ]
})


var values = [1,2,3,4,5]

var numbersScore = function(done) {
var array = []
    array.push(function(callback) {
        logger.info('test1')
        callback()
      })

values.forEach(function(number){
    number += 1 
    console.log(number)


    array.push(function(callback) {
        logger.info('test2', number)
        callback()
      })
})

async.parallel(array, function(error, data){
    console.log('done')
    process.exit()
})
}
numbersScore()

Приведенный выше код при запуске выводит это на консоль, что означает, что все работает отлично, однако в файле журнала ничего не сохраняется.

2
3
4
5
6
28/09/2016 10:57:45:911 - info: test1
28/09/2016 11:01:22:677 - info: Numbers are 2
28/09/2016 11:01:22:678 - info: Numbers are 3
28/09/2016 11:01:22:678 - info: Numbers are 4
28/09/2016 11:01:22:678 - info: Numbers are 5
28/09/2016 11:01:22:678 - info: Numbers are 6
done

Как только вы закомментируете process.exit(), файл журнала будет правильно сохранен со всеми необходимыми данными. ОДНАКО .... в моем сценарии мне нужно иметь process.exit () - так каков же обходной путь?

Что я пробовал:

  1. Использование обратного вызова Winston - https://github.com/winstonjs/winston#events-and-callbacks-in-winston - не работает

  2. Добавление setTimeout - сбой (кажется, что process.exit не ждет setTimeout - он все равно выходит из программы)

  3. Как вы можете видеть в приведенном выше примере, используя async.parallel, но все равно не повезло

Какие-нибудь другие решения для этого?

Та же проблема открыта на github - https://github.com/winstonjs/winston/issues/228 - однако полностью работающего решения пока не найдено.


person Community    schedule 28.09.2016    source источник
comment
Проблема с github, с которой вы связались, имеет обходной путь, предложенный Кегсаем. Прослушивание внутреннего _stream и прослушивание события finish.   -  person DrakaSAN    schedule 28.09.2016


Ответы (2)


Из проблемы с github:

Примечание. Это копия соответствующего раздела проблемы, написанная пользователем Кегсай.

Как бы то ни было, вы можете обойтись без использования setTimeout, но вам нужно захватить лежащий в основе _stream:

// log then exit(1)
logger.error("The thing to log", function(err) {
  var numFlushes = 0;
  var numFlushed = 0;
  Object.keys(logger.transports).forEach(function(k) {
    if (logger.transports[k]._stream) {
      numFlushes += 1;
      logger.transports[k]._stream.once("finish", function() {
        numFlushed += 1;
        if (numFlushes === numFlushed) {
          process.exit(1);
        }
      });
      logger.transports[k]._stream.end();
    }
  });
  if (numFlushes === 0) {
    process.exit(1);
  }
});

Как упоминалось выше, использования одной только функции обратного вызова недостаточно для правильного сброса в файл. Мне это кажется ошибкой.

Обратите внимание, что я на самом деле слушаю событие завершения: https://nodejs.org/api/stream.html#stream_event_finish, а не использовать событие сброса или закрытия Winston, потому что этого тоже недостаточно для правильного ведения журнала: /

person DrakaSAN    schedule 28.09.2016
comment
Я видел это, однако я не уверен, как реализовать это в моем коде, имея в виду, что process.exit () не вызывается внутри журналов - есть другие функции, которые зависят от process.exit (). Так что это решение не работает для меня - person ; 28.09.2016
comment
Это не дает ответа на заданный вопрос ... Вы уже разместили это в комментарии - person deeveeABC; 28.09.2016

Попробуйте что-то вроде этого, у меня это сработало (на основе Winston):

logger.on('logging', function (transport, level, msg, meta) {
  if (msg == "equal your message" && transport.name == "file") {
    var id = setInterval(function () {
      //when it is done to write the file, it will enter the id condition
      if (transport._stream._writableState.bufferedRequestCount==0) {
        exitProcess(0);
      }
    },1000)
  }
});
person Arik    schedule 22.12.2016