Configure Node.js to log to a file instead of the console
Asked Answered
L

28

262

Can I configure console.log so that the logs are written on a file instead of being printed in the console?

Liverpudlian answered 5/12, 2011 at 23:58 Comment(1)
could, but for long runtime production apps, it'd be hard to find logs for just a specific day, right? @racarKilroy
T
91

Update 2013 - This was written around Node v0.2 and v0.4; There are much better utilites now around logging. I highly recommend Winston

Update Late 2013 - We still use winston, but now with a logger library to wrap the functionality around logging of custom objects and formatting. Here is a sample of our logger.js https://gist.github.com/rtgibbons/7354879


Should be as simple as this.

var access = fs.createWriteStream(dir + '/node.access.log', { flags: 'a' })
      , error = fs.createWriteStream(dir + '/node.error.log', { flags: 'a' });

// redirect stdout / stderr
proc.stdout.pipe(access);
proc.stderr.pipe(error);
Timothytimour answered 6/12, 2011 at 0:28 Comment(13)
Nvm, it means process i think... How does this work? console.log(whatever); still goes to console, not file.Punchinello
Due to a recent change, you can't call stderr.pipe() anymore - it takes this now: process.__defineGetter__('stderr', function() { return fs.createWriteStream(__dirname + '/error.log', {flags:'a'}) })Levulose
Personally I'd steer well clear of Winston. We've used it for over a year now, and have finally decided to remove it completely as it was causing many issues in our production environment. The project seems to now be extremely poorly maintained. There's an issues list as long as your arm. Many of the issues have had pull requests submitted by other users, but the project maintainers are not even taking the time to merge these. For alternatives node-bunyan and caterpillar might be worth looking at.Snavely
It sucks that the maintainers aren't being responsive. I thought it was maintained by the Nodejitsu folks. We have used it on several sites pull over a million page views a day and haven't had any issues with logging. Maybe it has to do with what is being logged and the quantity of it.Timothytimour
It looks like as of April 2015 Winston is up to date and receiving a good deal of activity.Sunday
Yea, @MikeGrace Winston is still our platform of choice for logging. Though there is a camp investigating Bunyon - npmjs.com/package/bunyanTimothytimour
Had a lot of trouble getting Winston to work correctly on WindowsKaplan
We at @paytm used to use winston but have moved to npmlog (npmjs.com/package/npmlog ) now .. simple and powerfulMaori
@Levulose Your code creates a new stream every time the value of stderr is retrieved. It should be cached like how node/node.js does.Dependency
its about to be 2018 and I was in need of this again, however, it doesn't seems to be working though it used to work back in 2014s.Anton
@Anton try process.stdout and process.stdin instead of just proc?Timothytimour
after deploying app, how can i access this log file?Ingrain
winston has certain problems regarding buffers and flushing them. See my comment to above "answer".Rapturous
H
249

You could also just overload the default console.log function:

var fs = require('fs');
var util = require('util');
var log_file = fs.createWriteStream(__dirname + '/debug.log', {flags : 'w'});
var log_stdout = process.stdout;

console.log = function(d) { //
  log_file.write(util.format(d) + '\n');
  log_stdout.write(util.format(d) + '\n');
};

Above example will log to debug.log and stdout.

Edit: See multiparameter version by Clément also on this page.

Heidy answered 11/1, 2014 at 10:45 Comment(12)
i wouldn't bother overwriting console.log. Just create your own function that logs to a specific file.Consumerism
In addition this does not work for multiple parameters. E.g. console.log(p1, p2, p3)Sturgill
Great answer! Also, if you want to capture multiple console.log arguments, simply grab the 'Arguments' object in the place of 'd' - developer.mozilla.org/en/docs/Web/JavaScript/Reference/…Nap
@AlexMills Hi, maybe you could provide an example on how exactly that would be done?Ticon
@Ticon just create a function which uses the fs module to write to a file, you can use async or sync io to do it...for example nodejs.org/api/fs.html#fs_fs_writefilesync_file_data_optionsConsumerism
but i need to have this in every js file, is possible to make it global ?Aurea
after deploying app, i want to store log file in cloud storage how i can achieve this? i'm using app engine and after every deployment log files got replace with new empty ones i want to store the older oneIngrain
Works perfectly. See answer below for a tiny bit of expansion to this code.Expository
This solution not cover console.error() and other console methods: developer.mozilla.org/en-US/docs/Web/API/consoleSuggestion
This solution does not cover multiple arguments. It only logs the first argument, which means it's not backwards compatibleSuggestion
to log all the parameters you can do this way: sh console.log = function (...d) { log_file.write(util.format(...d) + '\n'); log_stdout.write(util.format(...d) + '\n'); }; Sponger
Shouldn't you close the stream after you're done? Or is this good to go?Dena
T
91

Update 2013 - This was written around Node v0.2 and v0.4; There are much better utilites now around logging. I highly recommend Winston

Update Late 2013 - We still use winston, but now with a logger library to wrap the functionality around logging of custom objects and formatting. Here is a sample of our logger.js https://gist.github.com/rtgibbons/7354879


Should be as simple as this.

var access = fs.createWriteStream(dir + '/node.access.log', { flags: 'a' })
      , error = fs.createWriteStream(dir + '/node.error.log', { flags: 'a' });

// redirect stdout / stderr
proc.stdout.pipe(access);
proc.stderr.pipe(error);
Timothytimour answered 6/12, 2011 at 0:28 Comment(13)
Nvm, it means process i think... How does this work? console.log(whatever); still goes to console, not file.Punchinello
Due to a recent change, you can't call stderr.pipe() anymore - it takes this now: process.__defineGetter__('stderr', function() { return fs.createWriteStream(__dirname + '/error.log', {flags:'a'}) })Levulose
Personally I'd steer well clear of Winston. We've used it for over a year now, and have finally decided to remove it completely as it was causing many issues in our production environment. The project seems to now be extremely poorly maintained. There's an issues list as long as your arm. Many of the issues have had pull requests submitted by other users, but the project maintainers are not even taking the time to merge these. For alternatives node-bunyan and caterpillar might be worth looking at.Snavely
It sucks that the maintainers aren't being responsive. I thought it was maintained by the Nodejitsu folks. We have used it on several sites pull over a million page views a day and haven't had any issues with logging. Maybe it has to do with what is being logged and the quantity of it.Timothytimour
It looks like as of April 2015 Winston is up to date and receiving a good deal of activity.Sunday
Yea, @MikeGrace Winston is still our platform of choice for logging. Though there is a camp investigating Bunyon - npmjs.com/package/bunyanTimothytimour
Had a lot of trouble getting Winston to work correctly on WindowsKaplan
We at @paytm used to use winston but have moved to npmlog (npmjs.com/package/npmlog ) now .. simple and powerfulMaori
@Levulose Your code creates a new stream every time the value of stderr is retrieved. It should be cached like how node/node.js does.Dependency
its about to be 2018 and I was in need of this again, however, it doesn't seems to be working though it used to work back in 2014s.Anton
@Anton try process.stdout and process.stdin instead of just proc?Timothytimour
after deploying app, how can i access this log file?Ingrain
winston has certain problems regarding buffers and flushing them. See my comment to above "answer".Rapturous
G
82

If you are looking for something in production winston is probably the best choice.

If you just want to do dev stuff quickly, output directly to a file (I think this works only for *nix systems):

nohup node simple-server.js > output.log &
Gazelle answered 6/12, 2011 at 8:56 Comment(8)
Using > to redirect STDOUT works on Windows as well. nohup doesn't.Sela
this works happily without nohup on *nix, i.e. node simple-server.js > output.log. Then if you'd like to follow the log as its written just tail -f output.logIsochor
This didn't work 2hen i had arguments passed to the processInference
What is the downside of doing this in production?Gooding
@Gooding well for one, that output.log file would get filled up for all eternity until you do-somethin-about-it. instead, you could have a method within your app that stores log files in a "logs folder" where the name of the file has a today's date appended to it.. that way at least you are creating a new log file each day, making it more manageable.Tichonn
btw depending on your OS, that "do-something-about-it" could simply be log rotation, which is a good solution imo - abdussamad.com/archives/541-Log-rotation-in-CentOS-Linux.htmlTichonn
What does the last "&" stand for?Betaine
@Betaine doesn't adding & to end make the command run in background? Or is there a different use case here? I see a different output on the console when I add ampersand to the endVerbenaceous
A
79

I often use many arguments to console.log() and console.error(), so my solution would be:

var fs = require('fs');
var util = require('util');
var logFile = fs.createWriteStream('log.txt', { flags: 'a' });
  // Or 'w' to truncate the file every time the process starts.
var logStdout = process.stdout;

console.log = function () {
  logFile.write(util.format.apply(null, arguments) + '\n');
  logStdout.write(util.format.apply(null, arguments) + '\n');
}
console.error = console.log;
Antipyrine answered 24/11, 2015 at 15:47 Comment(1)
This is great but util.format.apply(null, arguments) seems to output a massive amount of data on the program startup. It's like it outputs every required object. I can't figure out how to stop it but it doesn't occur with the single parameter approach above.Reductase
L
47

Winston is a very-popular npm-module used for logging.

Here is a how-to.
Install winston in your project as:

npm install winston --save

Here's a configuration ready to use out-of-box that I use frequently in my projects as logger.js under utils.

 /**
 * Configurations of logger.
 */
const winston = require('winston');
const winstonRotator = require('winston-daily-rotate-file');

const consoleConfig = [
  new winston.transports.Console({
    'colorize': true
  })
];

const createLogger = new winston.Logger({
  'transports': consoleConfig
});

const successLogger = createLogger;
successLogger.add(winstonRotator, {
  'name': 'access-file',
  'level': 'info',
  'filename': './logs/access.log',
  'json': false,
  'datePattern': 'yyyy-MM-dd-',
  'prepend': true
});

const errorLogger = createLogger;
errorLogger.add(winstonRotator, {
  'name': 'error-file',
  'level': 'error',
  'filename': './logs/error.log',
  'json': false,
  'datePattern': 'yyyy-MM-dd-',
  'prepend': true
});

module.exports = {
  'successlog': successLogger,
  'errorlog': errorLogger
};

And then simply import wherever required as this:

const errorLog = require('../util/logger').errorlog;
const successlog = require('../util/logger').successlog;

Then you can log the success as:

successlog.info(`Success Message and variables: ${variable}`);

and Errors as:

errorlog.error(`Error Message : ${error}`);

It also logs all the success-logs and error-logs in a file under logs directory date-wise as you can see here.
log direcotry

Lowelllowenstein answered 1/12, 2016 at 9:2 Comment(8)
The logs are visible in console. and no file is created immediately !! Am I missing something ?Gusto
Could you possibly share your configs ? Or did you use it as I suggested ? Check the imports (winston & winston-daily-rotate-file) once if configs are fine. They should be created inside a folder named logs in project's root directory. Pardon me for the delayed reply.Lowelllowenstein
@Gusto how did you fix this? I am facing the same issue.Enunciation
@Enunciation Take a look at my comment above Nigilan's comment. Let us know if you still can't get it done.Lowelllowenstein
Everything is same. What do you mean check the imports?Enunciation
Do not forget to add these on top of logger-util const winston = require('winston'); const winstonRotator = require('winston-daily-rotate-file'); And const errorLog = require('../util/logger').errorlog; const successlog = require('../util/logger').successlog; wherever you want to log something.Lowelllowenstein
gist.github.com/nigilan/f18cd70d967a8a55e90f7db442e8b4b9 This is working for me !Gusto
winston has a known complication delayed flushing of logs into the actual file. Hence, you won't see output during the debug or when you receive the errors. This is meant to be a feature (using buffers so that not to harm the performance of the main process), but since it doesn't seem have a flush function or automtically flushing them using a timer. IT keeps the logs in its buffer. This causes a known issue when program has to end using process.exit() - or when need to check the debug logs. Hence, it is not suitable for debugging. Even when the program errors/crashes, the logs are lost.Rapturous
A
16

For simple cases, we could redirect the Standard Out (STDOUT) and Standard Error (STDERR) streams directly to a file(say, test.log) using '>' and '2>&1'

Example:

// test.js
(function() {
    // Below outputs are sent to Standard Out (STDOUT) stream
    console.log("Hello Log");
    console.info("Hello Info");
    // Below outputs are sent to Standard Error (STDERR) stream
    console.error("Hello Error");
    console.warn("Hello Warning");
})();

node test.js > test.log 2>&1

As per the POSIX standard, 'input', 'output' and 'error' streams are identified by the positive integer file descriptors (0, 1, 2). i.e., stdin is 0, stdout is 1, and stderr is 2.

Step 1: '2>&1' will redirect from 2 (stderr) to 1 (stdout)

Step 2: '>' will redirect from 1 (stdout) to file (test.log)

Arceliaarceneaux answered 9/1, 2019 at 11:12 Comment(1)
This is great for simple cases when you just want to grab the application logs without having to deal with console breaking new lines etcAnatola
B
15
const fs = require("fs");
const {keys} = Object;
const {Console} = console;

/**
 * Redirect console to a file.  Call without path or with false-y
 * value to restore original behavior.
 * @param {string} [path]
 */
function file(path) {
    const con = path ? new Console(fs.createWriteStream(path)) : null;

    keys(Console.prototype).forEach(key => {
        if (path) {
            this[key] = (...args) => con[key](...args);
        } else {
            delete this[key];
        }
    });
};

// patch global console object and export
module.exports = console.file = file;

To use it, do something like:

require("./console-file");
console.file("/path/to.log");
console.log("write to file!");
console.error("also write to file!");
console.file();    // go back to writing to stdout
Betsybetta answered 9/2, 2017 at 18:34 Comment(4)
is possible just to save the erros ?Aurea
Instead of looping over Console.prototype keys, just explicitly set this.error only.Betsybetta
This breaks console.log?Clyve
It does not break console.log. It changes its behavior, though you can restore the old behavior by calling console.file().Betsybetta
I
13

If you're using linux, you can also use output redirection. Not sure about Windows.

node server.js >> file.log 2>> file.log

>> file.log to redirect stdout to the file

2>> file.log to redirect stderr to the file

others use the shorthand &>> for both stdout and stderr but it's not accepted by both my mac and ubuntu :(

extra: > overwrites, while >> appends.

By the way, regarding NodeJS loggers, I use pino + pino-pretty logger

Incubate answered 12/3, 2021 at 7:10 Comment(5)
This was the potential best answer for my use case. Unfortunately didn't work on Mac.Cicatrize
What error message were you getting? Or the file just doesn't appear where it should be?Incubate
It has been a while since I tried. I suspect my difficulties laid with using Docker. I tried it now with just Node.js and it worked, thanks.Cicatrize
This works well with Git Bash (VS Code) in windowsOddment
It does not work for me. Windows, node task run from scheduler, no log file is being created, nor text added to existing file; ideas?Valli
Q
11

If this is for an application, you're probably better off using a logging module. It'll give you more flexibility. Some suggestions.

Quarta answered 6/12, 2011 at 7:19 Comment(2)
Your log4js link is broken now. How about this? github.com/nomiddlename/log4js-nodeCarbonize
Yeah I guess the project switched hands. Thanks.Quarta
B
9

Straight from nodejs's API docs on Console

const output = fs.createWriteStream('./stdout.log');
const errorOutput = fs.createWriteStream('./stderr.log');
// custom simple logger
const logger = new Console(output, errorOutput);
// use it like console
const count = 5;
logger.log('count: %d', count);
// in stdout.log: count 5
Bilbe answered 25/7, 2017 at 0:16 Comment(2)
Your example worked for me, but you should write the const logger = new console.Console(output, errorOutput);Corrianne
when does one close the writeStreams? How do you close them at the end of your program?Freedom
C
6

Another solution not mentioned yet is by hooking the Writable streams in process.stdout and process.stderr. This way you don't need to override all the console functions that output to stdout and stderr. This implementation redirects both stdout and stderr to a log file:

var log_file = require('fs').createWriteStream(__dirname + '/log.txt', {flags : 'w'})

function hook_stream(stream, callback) {
    var old_write = stream.write

    stream.write = (function(write) {
        return function(string, encoding, fd) {
            write.apply(stream, arguments)  // comments this line if you don't want output in the console
            callback(string, encoding, fd)
        }
    })(stream.write)

    return function() {
        stream.write = old_write
    }
}

console.log('a')
console.error('b')

var unhook_stdout = hook_stream(process.stdout, function(string, encoding, fd) {
    log_file.write(string, encoding)
})

var unhook_stderr = hook_stream(process.stderr, function(string, encoding, fd) {
    log_file.write(string, encoding)
})

console.log('c')
console.error('d')

unhook_stdout()
unhook_stderr()

console.log('e')
console.error('f')

It should print in the console

a
b
c
d
e
f

and in the log file:

c
d

For more info, check this gist.

Ceroplastics answered 14/12, 2016 at 5:28 Comment(1)
Correct answer.Normannormand
C
5

Overwriting console.log is the way to go. But for it to work in required modules, you also need to export it.

module.exports = console;

To save yourself the trouble of writing log files, rotating and stuff, you might consider using a simple logger module like winston:

// Include the logger module
var winston = require('winston');
// Set up log file. (you can also define size, rotation etc.)
winston.add(winston.transports.File, { filename: 'somefile.log' });
// Overwrite some of the build-in console functions
console.error = winston.error;
console.log = winston.info;
console.info = winston.info;
console.debug = winston.debug;
console.warn = winston.warn;
module.exports = console;
Coppinger answered 12/1, 2016 at 22:33 Comment(3)
Yep. Sorry. My badPetal
you can overwrite console properties on the global object. why do module.exports?Daggna
Line 3 should be winston.add(new winston.transports.File, { filename: 'somefile.log' });Anadromous
P
4

Most logger is overkill and does not support the build in console.log correctly. Hence I create console-log-to-file:

import { consoleLogToFile } from "console-log-to-file";
// or `const { consoleLogToFile } = require("console-log-to-file/dist/index.cjs.js")`

consoleLogToFile({
  logFilePath: "/log/default.log",
});

// all of your console.log/warn/error/info will work as it does and save to file now.
Pentose answered 4/4, 2021 at 10:7 Comment(0)
M
4

You can use the nodejs Console constructor

const mylog = new console.Console(
  fs.createWriteStream("log/logger.log"),
  fs.createWriteStream("log/error.log")
);

And then you can use it just like the normal console class, eg:

mylog.log("Ok!"); // Will be written into 'log/logger.log'
mylog.error("Bad!"); // Will be written into 'log/error.log'
Merge answered 29/1, 2023 at 15:20 Comment(1)
Will this have any performance impact?Exposed
K
3

METHOD STDOUT AND STDERR

This approach can help you (I use something similar in my projects) and works for all methods including console.log, console.warn, console.error, console.info

This method write the bytes written in stdout and stderr to file. Is better than changing console.log, console.warn, console.error, console.info methods, because output will be exact the same as this methods output


var fs= require("fs")
var os= require("os")
var HOME= os.homedir()
var stdout_r = fs.createWriteStream(HOME + '/node.stdout.log', { flags: 'a' })
var stderr_r = fs.createWriteStream(HOME + '/node.stderr.log', { flags: 'a' })

var attachToLog= function(std, std_new){

    var originalwrite= std.write
    std.write= function(data,enc){
        try{
            var d= data
            if(!Buffer.isBuffer(d))
                d= Buffer.from(data, (typeof enc === 'string') ? enc : "utf8")
            std_new.write.apply(std_new, d)
        }catch(e){}
        return originalwrite.apply(std, arguments)
    }


}
attachToLog(process.stdout, stdout_r)
attachToLog(process.stderr, stderr_r)

// recommended catch error on stdout_r and stderr_r
// stdout_r.on("error", yourfunction)
// stderr_r.on("error", yourfunction)
Kanazawa answered 20/1, 2019 at 1:5 Comment(1)
i'm going to use this in my npm module and attribute this code to you. is that cool?Daggna
E
3

Adding to the answer above, a lit bit of an expansion to the short and efficient code overriding console.log. Minor additions: set filename with date, wrapper function, also do the original console.logging to keep the console active with the info.

Usage: in the beginning of your code, run setConsoleLogToFile([FILENAME]).

const fs = require("fs"),
    util = require('util');


const getPrettyDate = ()=> new Date().toString().replace(":","-").replace(/00\s\(.*\)/, "").replace(` ${new Date().getFullYear()}`, ",").replace(/:\d\d\s/, " ");

module.exports.getPrettyDate = getPrettyDate;

module.exports.setConsoleLogToFile = (filename) => {
    const log_file = fs.createWriteStream(`${__dirname}/${filename} -  ${getPrettyDate()}.log`, { flags: 'w' }),
        log_stdout = process.stdout;

    const origConsole = console.log;
    console.log = (d) => { 
        origConsole(d);
        log_file.write(util.format(d) + '\n');
        log_stdout.write(util.format(d) + '\n');
    };
}
Expository answered 27/3, 2021 at 10:19 Comment(0)
J
3

If you are looking for a solution without modifying any code, here is a simple solution.

It requires pm2, just add it to your node modules and start you app with

pm2 start server.js

And you are done, console.logs are now automatically registered under home/.pm2/logs/server-out.log.

Jackqueline answered 28/10, 2021 at 19:32 Comment(0)
E
2

Improve on Andres Riofrio , to handle any number of arguments

var fs = require('fs');
var util = require('util');

var log_file = fs.createWriteStream(__dirname + '/debug.log', {flags : 'w'});
var log_stdout = process.stdout;

console.log = function(...args) {
    var output = args.join(' ');
    log_file.write(util.format(output) + '\r\n');
    log_stdout.write(util.format(output) + '\r\n');
};
Embalm answered 4/7, 2018 at 4:42 Comment(0)
F
1

You can now use Caterpillar which is a streams based logging system, allowing you to log to it, then pipe the output off to different transforms and locations.

Outputting to a file is as easy as:

var logger = new (require('./').Logger)();
logger.pipe(require('fs').createWriteStream('./debug.log'));
logger.log('your log message');

Complete example on the Caterpillar Website

Freidafreight answered 8/5, 2013 at 1:9 Comment(0)
O
1

You can also have a look at this npm module: https://www.npmjs.com/package/noogger

noogger

simple and straight forward...

Oshiro answered 11/5, 2016 at 4:8 Comment(1)
Great module recommendation but perhaps could put in some effort to giving some more detail/code usage.Interbrain
R
1

For future users. @keshavDulal answer doesn't work for latest version. And I couldn't find a proper fix for the issues that are reporting in the latest version 3.3.3.

Anyway I finally fixed it after researching a bit. Here is the solution for winston version 3.3.3

Install winston and winston-daily-rotate-file

npm install winston 
npm install winston-daily-rotate-file

Create a new file utils/logger.js

const winston = require('winston');
const winstonRotator = require('winston-daily-rotate-file');

var logger = new winston.createLogger({
  transports: [
    new (winston.transports.DailyRotateFile)({
      name: 'access-file',
      level: 'info',
      filename: './logs/access.log',
      json: false,
      datePattern: 'yyyy-MM-DD',
      prepend: true,
      maxFiles: 10
    }),
    new (winston.transports.DailyRotateFile)({
      name: 'error-file',
      level: 'error',
      filename: './logs/error.log',
      json: false,
      datePattern: 'yyyy-MM-DD',
      prepend: true,
      maxFiles: 10
    })
  ]
});


module.exports = {
  logger
};

Then in any file where you want to use logging import the module like

const logger = require('./utils/logger').logger;

Use logger like the following:

logger.info('Info service started');
logger.error('Service crashed');
Riff answered 2/8, 2020 at 16:52 Comment(0)
S
1

if you are using forever to keep your node app running, then typing forever list will show you the path to the log file that console.log is writing too

enter image description here

Sprinkle answered 4/5, 2021 at 8:36 Comment(0)
I
1

Create a utils/logger.js file with:

var fs = require('fs');
var util = require('util');
var log_file = fs.createWriteStream(__dirname + '/../logs/server.log', { flags: 'w' });
var log_stdout = process.stdout;

console.log = function () { //
    [...arguments].forEach(element => {
        log_file.write(util.format(element) + '\n');
        log_stdout.write(util.format(element) + '\n');
    });
};

module.exports = {
    console
}

Include the logger.js file from any file where you want to console.log like:

const console = require('./utils/logger').console;

Create a logs folder and create an empty server.log file in it and run your app :)

Intercessor answered 7/11, 2021 at 14:27 Comment(0)
S
0

I took on the idea of swapping the output stream to a my stream.

const LogLater                = require ('./loglater.js');
var logfile=new LogLater( 'log'+( new Date().toISOString().replace(/[^a-zA-Z0-9]/g,'-') )+'.txt' );


var PassThrough = require('stream').PassThrough;

var myout= new PassThrough();
var wasout=console._stdout;
myout.on('data',(data)=>{logfile.dateline("\r\n"+data);wasout.write(data);});
console._stdout=myout;

var myerr= new PassThrough();
var waserr=console._stderr;
myerr.on('data',(data)=>{logfile.dateline("\r\n"+data);waserr.write(data);});
console._stderr=myerr;

loglater.js:

const fs = require('fs');

function LogLater(filename, noduplicates, interval) {
    this.filename = filename || "loglater.txt";
    this.arr = [];
    this.timeout = false;
    this.interval = interval || 1000;
    this.noduplicates = noduplicates || true;
    this.onsavetimeout_bind = this.onsavetimeout.bind(this);
    this.lasttext = "";
    process.on('exit',()=>{ if(this.timeout)clearTimeout(this.timeout);this.timeout=false; this.save(); })
}

LogLater.prototype = {
    _log: function _log(text) {
        this.arr.push(text);
        if (!this.timeout) this.timeout = setTimeout(this.onsavetimeout_bind, this.interval);
    },
    text: function log(text, loglastline) {
        if (this.noduplicates) {
            if (this.lasttext === text) return;
            this.lastline = text;
        }
        this._log(text);
    },
    line: function log(text, loglastline) {
        if (this.noduplicates) {
            if (this.lasttext === text) return;
            this.lastline = text;
        }
        this._log(text + '\r\n');
    },
    dateline: function dateline(text) {
        if (this.noduplicates) {
            if (this.lasttext === text) return;
            this.lastline = text;
        }
        this._log(((new Date()).toISOString()) + '\t' + text + '\r\n');
    },
    onsavetimeout: function onsavetimeout() {
        this.timeout = false;
        this.save();
    },
    save: function save() { fs.appendFile(this.filename, this.arr.splice(0, this.arr.length).join(''), function(err) { if (err) console.log(err.stack) }); }
}

module.exports = LogLater;
Sappington answered 7/5, 2018 at 23:19 Comment(0)
C
0

I just build a pack to do this, hope you like it ;) https://www.npmjs.com/package/writelog

Cryoscopy answered 11/7, 2018 at 20:41 Comment(0)
O
0

I for myself simply took the example from winston and added the log(...) method (because winston names it info(..):

Console.js:

"use strict"

// Include the logger module
const winston = require('winston');

const logger = winston.createLogger({
    level: 'info',
    format: winston.format.json(),
    transports: [
        //
        // - Write to all logs with level `info` and below to `combined.log`
        // - Write all logs error (and below) to `error.log`.
        //
        new winston.transports.File({ filename: 'error.log', level: 'error' }),
        new winston.transports.File({ filename: 'combined.log' })
    ]
});

//
// If we're not in production then log to the `console` with the format:
// `${info.level}: ${info.message} JSON.stringify({ ...rest }) `
//
if (process.env.NODE_ENV !== 'production') {
    logger.add(new winston.transports.Console({
        format: winston.format.simple()
    }));
}

// Add log command
logger.log=logger.info;

module.exports = logger;

Then simply use in your code:

const console = require('Console')

Now you can simply use the normal log functions in your file and it will create a file AND log it to your console (while debugging/developing). Because of if (process.env.NODE_ENV !== 'production') { (in case you want it also in production)...

Olfactory answered 5/10, 2018 at 16:11 Comment(2)
Doesn't winston add a bunch of garbage like "message" and the log level?Clyve
@Clyve What do you mean? winston is very flexible, you can configure it... are you looking for... github.com/winstonjs/winston#formats ?Olfactory
C
0

Based on multiparameter version by Clément, just without color codes for the text file

var fs = require('fs');
var util = require('util');
var logFile = fs.createWriteStream('log.txt', { flags: 'a' });
  // Or 'w' to truncate the file every time the process starts.
var logStdout = process.stdout;

console.log = function () {
  // Storing without color codes
  logFile.write(util.format.apply(null,arguments).replace(/\033\[[0-9;]*m/g,"") + '\n');
  // Display normally, with colors to Stdout
  logStdout.write(util.format.apply(null, arguments) + '\n');
}

Note: Answering since I couldn't comment

Colleencollege answered 30/12, 2021 at 12:33 Comment(1)
Seems you meant to use var logFile = fs.createWriteStream('log.txt', { flags: 'a' }); to append the new content.Adorn
U
0

Rudy Huynh's solution worked really well for me. I added a little bit to have it spit out files with today's date and time.

var dateNow = new Date();
var timeNow = dateNow.getHours() + '-' + dateNow.getMinutes();
var logPath = "log/" + dateNow.toDateString() + ' -' + ' Start Time - ' + timeNow + ".log"

consoleLogToFile({
logFilePath: logPath
});

It's not very elegant but this way it'll save different, easy to read, log files instead of just updating the same "default.log" file.

Unstrap answered 19/4, 2022 at 0:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.