37

I have another question (last question). At the moment i am working on a Node.js project and in this I have many console.log() functions. This has worked okay so far but I also want everything that's written to the console to also be written in a log-file. Can someone please help me?

For example:

Console.log('The value of array position [5] is '+ array[5]);

In my real code its a bit more but this should give you an idea.

Thank you hopefully.

Community
  • 1
  • 1
Limatuz
  • 666
  • 2
  • 6
  • 12

7 Answers7

75

Just run the script in your terminal like this...

node script-file.js > log-file.txt

This tells the shell to write the standard output of the command node script-file.js to your log file instead of the default, which is printing it to the console.

This is called redirection and its very powerful. Say you wanted to write all errors to a separate file...

node script-file.js >log-file.txt 2>error-file.txt

Now all console.log are written to log-file.txt and all console.error are written to error-file.txt

Charlie Martin
  • 8,208
  • 3
  • 35
  • 41
  • 5
    Note: two greater than signs redirect and appends the output to a file whilst a single greater than sign empties / overwrites the file upon a restart of your script. Example: `2>>error-file.txt`. I use two greater than signs to prevent a loss of output when restarting my scripts. – Skoempie May 03 '18 at 13:32
  • how to navigate it back to console? – Angelzzz Oct 12 '18 at 12:42
  • 1
    @Angelzzz `node script-file.js 2>&1 | tee log-file.txt` – Charlie Martin Jan 29 '19 at 16:20
  • how can I insert line break in the txt file using this way? – Mark Nov 05 '19 at 08:38
28

I would use a library instead of re-inventing the wheel. I looked for a log4j-type library on npm, and it came up with https://github.com/nomiddlename/log4js-node

if you want to log to the console and to a file:

var log4js = require('log4js');
log4js.configure({
  appenders: [
    { type: 'console' },
    { type: 'file', filename: 'logs/cheese.log', category: 'cheese' }
  ]
});

now your code can create a new logger with

var logger = log4js.getLogger('cheese'); 

and use the logger in your code

logger.warn('Cheese is quite smelly.');
logger.info('Cheese is Gouda.');
logger.debug('Cheese is not a food.');
activedecay
  • 10,129
  • 5
  • 47
  • 71
  • will this log all the console logs without any need to add a custom console log for your particular module? – John Dec 20 '16 at 03:13
  • Didn't test this yet when i did i will tell you. – Limatuz Dec 20 '16 at 06:25
  • 2
    @Juan no, you need to get `var logger = log4js.getLogger('cheese');` and then you can do `logger.warn('Cheese is quite smelly.');`, `logger.info('Cheese is Gouda.'); `, etc. – Antonio Val Dec 20 '16 at 08:33
18
const fs = require('fs');
const myConsole = new console.Console(fs.createWriteStream('./output.txt'));
myConsole.log('hello world');

This will create an output file with all the output which can been triggered through console.log('hello world') inside the console.

This is the easiest way to convert the console.log() output into a text file.`

  • it logs undefined for a JSON. I tried `JSON.stringify()` but still got undefined – Sarneet Kaur Jun 19 '20 at 00:11
  • Hi Sarneet , `const fs = require("fs"); const out = { name: "test", id: 456 }; const myConsole = new console.Console(fs.createWriteStream("./output.json")); myConsole.log(out); ` the above code has worked for me without any issue . it was able to output json on a output file. – Avinash Chandravansi Jun 23 '20 at 14:36
  • I am not able to change my vote. This did work for me when I tried it with a different CSV. – Sarneet Kaur Jul 01 '20 at 19:57
12

You could try overriding the built in console.log to do something different.

var originalLog = console.log;

console.log = function(str){
  originalLog(str);
  // Your extra code
}

However, this places the originalLog into the main scope, so you should try wrapping it in a function. This is called a closure, and you can read more about them here.

(function(){
   var originalLog = console.log;

  console.log = function(str){
  originalLog(str);
  // Your extra code
})();

To write files, see this stackoverflow question, and to override console.log even better than the way I showed, see this. Combining these two answers will get you the best possible solution.

Community
  • 1
  • 1
Max
  • 1,325
  • 9
  • 20
6

Just write your own log function:

function log(message) {
   console.log(message);
   fs.writeFileSync(...);
}

Then replace all your existing calls to console.log() with log().

Charlie Martin
  • 8,208
  • 3
  • 35
  • 41
Steve Bennett
  • 114,604
  • 39
  • 168
  • 219
  • What a brilliant idea, no stuffing around with winston or other over-engineered bloat; I'd probably use no args, and try to retrieve them inside the log function. – joedotnot Jan 17 '21 at 22:33
6

@activedecay's answer seems the way to go. However, as of april 30th 2018, I have had trouble with that specific model (node crashed due to the structure of the object passed on to .configure, which seems not to work in the latest version). In spite of that, I've managed to work around an updated solution thanks to nodejs debugging messages...

const myLoggers = require('log4js');

myLoggers.configure({
    appenders: { mylogger: { type:"file", filename: "path_to_file/filename" } },
    categories: { default: { appenders:["mylogger"], level:"ALL" } }
});
const logger = myLoggers.getLogger("default");

Now if you want to log to said file, you can do it just like activedecay showed you:

logger.warn('Cheese is quite smelly.');
logger.info('Cheese is Gouda.');
logger.debug('Cheese is not a food.');

This however, will not log anything to the console, and since I haven't figured out how to implement multiple appenders in one logger, you can still implement the good old console.log();

PD: I know that this is a somewhat old thread, and that OP's particular problem was already solved, but since I came here for the same purpose, I may as well leave my experience so as to help anyone visiting this thread in the future

J3STER
  • 1,027
  • 2
  • 11
  • 28
0

Here is simple solution for file logging @grdon/logger

const logger = require('@grdon/logger')({
  defaultLogDirectory : __dirname + "/logs",
})
// ...
logger(someParams, 'logfile.txt')
logger(anotherParams, 'anotherLogFile.log')
Kandrat
  • 464
  • 7
  • 16