3

How can I hijack calls to the browsers console.log and send them to my own log function while still letting them make there normal console.log entry.

Sites like JSBin and CodePen allow you to view there version of a console log in the page DOM while still making the console.log entry as well.

So every time I call console.log('my log msg'); it should behave like normal but also pipe/send the console log data to my own JavaScript logger.log('log entry') function.

How can this be done?


UPDATE

Desired custom logger output of an object:

Logging this object:

var data = {
  date: new Date(),
  prop2: 'sfgsdgsd',
  arrayProp: ['key1', 'key2', 'key3'],
  arrayOfObjectsProp: [
  {
      date: new Date(),
      date2: new Date()
  },{
      date: new Date(),
      date2: new Date()
  },{
      date: new Date(),
      date2: new Date()
  }]      
};
setInterval(function() {
  console.log(data);
}, 10000);

In the Logger will show as:

{
  "date": "2017-01-01T03:19:46.944Z",
  "prop2": "sfgsdgsd",
  "arrayProp": [
    "key1",
    "key2",
    "key3"
  ],
  "arrayOfObjectsProp": [
    {
      "date": "2017-01-01T03:19:46.944Z",
      "date2": "2017-01-01T03:19:46.944Z"
    },
    {
      "date": "2017-01-01T03:19:46.944Z",
      "date2": "2017-01-01T03:19:46.944Z"
    },
    {
      "date": "2017-01-01T03:19:46.944Z",
      "date2": "2017-01-01T03:19:46.944Z"
    }
  ]
}
Community
  • 1
  • 1
JasonDavis
  • 48,204
  • 100
  • 318
  • 537

2 Answers2

8

You could assign old console.log to a variable called, for instance, oldlog, and then assign to console.log your own function, which would do all the necessary things, and then call oldlog in the very end, passing given text as a parameter

var oldlog = console.log
console.log = function(...args) {
  // do something fancy with text passed
  oldlog(...args);
}

EDIT As mentioned by KevBot, console.log can take unlimited number of arguments, so, to cover all the cases, your function should allow this behavior. This can be done using ES6 feature called rest parameters or, without relying on ES6, using arguments array-like object, as described in num8er's answer

Also, as mentioned by Oriol, some browsers wont allow oldlog to be called not on console. This can be fixed by changing the line

oldlog(...args)

in your custom console.log to

oldlog.call(console, ...args)
msaw328
  • 1,459
  • 10
  • 18
  • 2
    Don't forget that `console.log()` can receive `n` number of arguments. – KevBot Dec 31 '16 at 02:40
  • 1
    Some browsers won't allow `oldlog` not to be called on a `console` object. You should use `call` or `apply`. – Oriol Dec 31 '16 at 02:48
  • 2
    and in mozilla dev network website tells You that no need to wait for ES6 (: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/arguments – num8er Dec 31 '16 at 02:54
3

First of all You must understand that console.log takes dynamic amount of arguments.

So You should not end Your job with: console.log = function(text) {}

You've to get magic variable arguments and then call original log function inside of custom function.

So see this example:

console.log2 = console.log; // keeping original function under new name

console.log = function() {
  // converting arguments object to array
  var args = Array.prototype.splice.call(arguments, 0); 
   
  // calling original log function with args
  console.log2.apply(this, args); 

  // doing something else...      
  document.getElementById('debug-bar').innerHTML = 'Debug: '+ args.join(' ');
};

setInterval(function() {
  console.log(new Date());
}, 1000);
<div id="debug-bar"></div>

P.S. if it's nodejs app so You can use winston package that is very flexible for customizations.

num8er
  • 18,604
  • 3
  • 43
  • 57
  • The console log DIV that the StackOverflow editor shows in your demo is actually what I am trying to achieve. I want to make a really light weight drop in JS lib that adds a console logger DIV to the DOM that will pipe console.log calls to itand format and show objects and arrays and stuff like the console does. Looking at the console in your demo from StackOverflow it handles objects and arrays and nested items just as I need. I updated my question to show what I mean. DO you know how to do a logger like that? – JasonDavis Jan 01 '17 at 03:34
  • 1
    I just found there JS file http://stacksnippets.net/scripts/snippet-javascript-console.min.js?v=1 driopping it in as page makes it work anywhere! – JasonDavis Jan 01 '17 at 03:37