130

I would like to put a button in my app, if you press it it will get the contents of everything that was written to the console and email it to me (for reporting bugs). I know I can keep a variable around and every time I do a console.log also append the message to that variable but I am trying to keep the memory consumption of the app low so it would be much more efficient just to grab it from the console.

Is there a way to retrieve the console messages from javascript?

phrogg
  • 888
  • 1
  • 13
  • 28
Mike
  • 1,403
  • 2
  • 10
  • 7
  • 1
    possible duplicate of [Google chrome extension : is it possible to get console output (js errors, console.log or etc)](http://stackoverflow.com/questions/13013535/google-chrome-extension-is-it-possible-to-get-console-output-js-errors-conso) – DontVoteMeDown Nov 07 '13 at 20:33
  • thanks, that is what I was thinking. I did some searching and didn't see this post, thanks for pointing it out – Mike Nov 07 '13 at 20:39
  • 1
    thanks, I used http://jsconsole.com/ before for remote debugging, next time I ned it I will give your library a look – Mike Nov 07 '13 at 21:06
  • @Mike Another fine tool is [weinre](http://debug.phonegap.com/). I used both weinre and jsconsole and I liked weinre most. – DontVoteMeDown Nov 08 '13 at 09:45

6 Answers6

141

You can't. What's in the console can't be read from JavaScript.

What you can do is hook the console.log function so that you store when it logs :

console.stdlog = console.log.bind(console);
console.logs = [];
console.log = function(){
    console.logs.push(Array.from(arguments));
    console.stdlog.apply(console, arguments);
}

console.logs contains all what was logged. You can clean it at any time by doing console.logs.length = 0;.

You can still do a standard, non storing, log by calling console.stdlog.

Denys Séguret
  • 372,613
  • 87
  • 782
  • 758
  • If you're the only one working on this project you could simply define a function `log` so you don't type as much. I would sync it with `console.log` as per this answer if you're working with other people (who may or may not be familiar with your method.) – sotrh Aug 19 '14 at 16:39
  • 9
    @dystroy: Hey, just curious is there any way to get the .js file name and the line number where original `console.log` was called from? – c00000fd Oct 12 '14 at 00:03
  • @c00000fd one thing I do is put some sort of unique identifier in the console output. I wouldn't go with the line number, since this can easily change after editing, but some unique string to identify that particular console.log. Then when you see it, it's easy to search for in a text editor. – Katharine Osborne Aug 14 '15 at 08:58
  • 2
    @c00000fd You could throw and catch an `Error` inside your function and then parse out the file name and line from the stack trace. – JLRishe Mar 01 '17 at 15:07
  • side note, you can override console.log like Denys said, or you can override console.error or console.exception to get specific types of messages. Works for my crash reporter, thanks! – MingMan Jan 19 '18 at 17:22
  • @KatharineOsborne what about uncaught errors? – Jiří Oct 05 '22 at 12:48
40

get all console data

how to read browser console error in js?

How to read from Chrome's console in JavaScript

https://www.quora.com/How-do-I-read-console-window-errors-from-Chrome-using-JavaScript

logs

console.defaultLog = console.log.bind(console);
console.logs = [];
console.log = function(){
    // default &  console.log()
    console.defaultLog.apply(console, arguments);
    // new & array data
    console.logs.push(Array.from(arguments));
}

error

console.defaultError = console.error.bind(console);
console.errors = [];
console.error = function(){
    // default &  console.error()
    console.defaultError.apply(console, arguments);
    // new & array data
    console.errors.push(Array.from(arguments));
}

warn

console.defaultWarn = console.warn.bind(console);
console.warns = [];
console.warn = function(){
    // default &  console.warn()
    console.defaultWarn.apply(console, arguments);
    // new & array data
    console.warns.push(Array.from(arguments));
}

debug

console.defaultDebug = console.debug.bind(console);
console.debugs = [];
console.debug = function(){
    // default &  console.debug()
    console.defaultDebug.apply(console, arguments);
    // new & array data
    console.debugs.push(Array.from(arguments));
}
20

I have used this code in the past to capture all console activity and store it with types and timestamps in console.everything for sending back to the server for diagnosing form data entry issues. I run this code as early as possible in the <head> element.

if (console.everything === undefined)
{
    console.everything = [];

    console.defaultLog = console.log.bind(console);
    console.log = function(){
        console.everything.push({"type":"log", "datetime":Date().toLocaleString(), "value":Array.from(arguments)});
        console.defaultLog.apply(console, arguments);
    }
    console.defaultError = console.error.bind(console);
    console.error = function(){
        console.everything.push({"type":"error", "datetime":Date().toLocaleString(), "value":Array.from(arguments)});
        console.defaultError.apply(console, arguments);
    }
    console.defaultWarn = console.warn.bind(console);
    console.warn = function(){
        console.everything.push({"type":"warn", "datetime":Date().toLocaleString(), "value":Array.from(arguments)});
        console.defaultWarn.apply(console, arguments);
    }
    console.defaultDebug = console.debug.bind(console);
    console.debug = function(){
        console.everything.push({"type":"debug", "datetime":Date().toLocaleString(), "value":Array.from(arguments)});
        console.defaultDebug.apply(console, arguments);
    }
}
QA Collective
  • 2,222
  • 21
  • 34
  • How to reset the console.everything to undefined again? I tried doing it and it gives me error in my react app. – Mohammed Ajmal Jul 19 '20 at 17:38
  • What am I doing wrong as it doesn't work? Only the `defaultLog` is catching the output in `console.everything`. Forcing this error _Uncaught ReferenceError: t is not defined_ with `let x = t.foo;` is not in `console.everything`. Any idea? – Peter VARGA May 14 '21 at 18:50
16

QA Collective's solution is very nice but has a lot of repeated code and doesn't capture errors that are not printed via the console.log, console.error, etc.

Here's the DRY and extended version of his solution that captures more error messages that show up in the console:

if (console.everything === undefined) {
  console.everything = [];
  function TS(){
    return (new Date).toLocaleString("sv", { timeZone: 'UTC' }) + "Z"
  }
  window.onerror = function (error, url, line) {
    console.everything.push({
      type: "exception",
      timeStamp: TS(),
      value: { error, url, line }
    })
    return false;
  }
  window.onunhandledrejection = function (e) {
    console.everything.push({
      type: "promiseRejection",
      timeStamp: TS(),
      value: e.reason
    })
  } 

  function hookLogType(logType) {
    const original= console[logType].bind(console)
    return function(){
      console.everything.push({ 
        type: logType, 
        timeStamp: TS(), 
        value: Array.from(arguments) 
      })
      original.apply(console, arguments)
    }
  }

  ['log', 'error', 'warn', 'debug'].forEach(logType=>{
    console[logType] = hookLogType(logType)
  })
}   

I also changed the timestamp format to use the ISO format in UTC timezone, to be able to compare time stamps in different time zones more easily.

BenVida
  • 1,796
  • 1
  • 16
  • 25
6

If you're working on vue.js, you can actually do this:

data () {
    return {
        data: []
    }
},
created () {
    let current_log = console.log;

    console.log = msg => {
        if (msg !== undefined) this.data.push(msg);
        current_log.apply(null, arguments);
    }
}

All logs from console will be captured and stored in data

Edsel Ayala
  • 209
  • 4
  • 7
4

If you just want to catch windows errors (Browser's developer tool), you just need to use the window.onerror listener. and the most important thing is to keep returning it false because If you return true in your callback, then the propagation of the error will stop and won't be log in the console anymore .

window.onerror = function myErrorHandler(err, url, line) {  
    //Do some  stuff 
    console.log(err) // Uncaught SyntaxError: Invalid or unexpected token at Line no:- 1
    return false;   // so you still log errors into console 
}
Sujeet Mishra
  • 199
  • 3
  • 2
  • Beware, this will always print out the one line using `log` isntaed of the line it has actually happened. – Jiří Oct 05 '22 at 12:40