Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to force nodejs winston log to file before process exit

I am using winston 3 to log my data. But sometimes it didn't log the error before process exit.

The following process will exit, without log to the logfile.log:

const winston = require('winston');

winston.add(new winston.transports.File({
    filename: 'logfile.log'
}));

winston.info('please log me in');
process.exit(1);

One of attempted solution is used callback:

const winston = require('winston');

const logger = new winston.createLogger({
    new winston.transports.File({
    filename: 'logfile.log'
}));

winston.info('please log me in', () => {
    process.exit(1);
});

setTimeout(() => {}, 100000000000); // pause the process until process.exit is call

But Winston 3.x have callback issue, so the above code won't work, the process will not exit.

I am looking for a workable solution? Any help will be greatly appreciated. My OS is Ubuntu 16.04, Node 10.17.

Edit 1: I also have try Prabhjot Singh Kainth's suggestion use finish event to trigger process exit:

const winston = require('winston');

const logger = winston.createLogger({
    transports: [
        new winston.transports.File({
            filename: 'logfile.log'
        })
    ]
});

logger.info('please log me in');

logger.on('finish', () => {
    process.exit();
});
logger.end();

setTimeout(() => {}, 100000000000); // pause the process until process.exit is call

In the above case, the process will exit, but no log file will be created.

like image 893
Wan Chap Avatar asked Nov 19 '19 12:11

Wan Chap


People also ask

Why doesn't Winston create the log file when I exit?

When you have winston configured to log to a file and you call process.exit (0) in your code, winston never ends up creating the log file and appending the log messages to the file.

How do I log with Winston in Linux?

Install the Winston package using the command npm install winston. Logging with Winston is simple, with just four steps, as shown in the example below, and you have your log recorded. Add the Winston module with a require () function. Creating Winston configuration object.

How do I send and save logs with Winston?

With Winston, you can send and save logs in different ways, such as files, databases, emails, and console. Log formats. Winston provides you with several log formats. For example, when saving a log to a Mongo database, the log format needs to be in JSON format.

What are the transport options available in Winston by default?

The following transport options are available in Winston by default: Console : output logs to the Node.js console. File : store log messages to one or more files. HTTP : stream logs to an HTTP endpoint. Stream : output logs to any Node.js stream.


2 Answers

Finally, I find a workable solution. Instead of listening to logger finish event, it should listen to file._dest finish event. But file._dest is only created after file open event. So it need to wait for file open event in initialization process.

const winston = require('winston');

const file = new winston.transports.File({
  filename: 'logfile.log'
});

const logger = winston.createLogger({
    transports: [file]
});

file.on('open', () => {  // wait until file._dest is ready
  logger.info('please log me in');
  logger.error('logging error message');
  logger.warn('logging warning message');

  file._dest.on('finish', () => {
    process.exit();
  });
  logger.end();
});

setTimeout(() => {}, 100000000000); // pause the process until process.exit is call
like image 120
Wan Chap Avatar answered Sep 18 '22 20:09

Wan Chap


How about this one?

logger.info('First message...')
logger.info('Last message', () => process.exit(1))
like image 22
fmagno Avatar answered Sep 22 '22 20:09

fmagno