I'm building a debugging tool for my web app and I need to show console errors in a div. I know I can use my own made console like object and use it, but for future use I need to send all console errors to window. Actually I want to catch console events.
- Here's what I found helpful ultimately: stackoverflow.com/a/37081135/470749Ryan– Ryan2018-04-05 02:51:24 +00:00Commented Apr 5, 2018 at 2:51
- stackoverflow.com/a/43725214/470749 down below is pretty cool.Ryan– Ryan2018-04-05 03:11:18 +00:00Commented Apr 5, 2018 at 3:11
- 1github.com/bahmutov/console-log-div - is quite useful and comprehensivelifebalance– lifebalance2018-12-31 07:45:38 +00:00Commented Dec 31, 2018 at 7:45
8 Answers
To keep the console working:
if (typeof console != "undefined") if (typeof console.log != 'undefined') console.olog = console.log; else console.olog = function() {}; console.log = function(message) { console.olog(message); $('#debugDiv').append('<p>' + message + '</p>'); }; console.error = console.debug = console.info = console.log 3 Comments
!= "undefined" is only partially complete, later on we are assigning to console.log anyway...$('#debugDiv') ? Try using something like this instead: document.getElementById('debugDiv').innerHTML += ('<p>' + message + '</p>');Here's a way using closure, containing the old console log function in the scope of the new one.
console.log = (function (old_function, div_log) { return function (text) { old_function(text); div_log.value += text; }; } (console.log.bind(console), document.getElementById("error-log"))); 5 Comments
div_log.textContent += text;console.error = console.log = (function... made mine work for errors. This could work for other console.[whatever] as well. Also @srgsanky's change was required for it to work on mine.console.error or console.log function. I don't think that can be done if you set multiple attrs with one function - will need multiple functions.if (typeof console !== 'undefined') { if (typeof console.log !== 'undefined') { console.log = (function (old_function) { return function (text) { old_function(text); const newMessage = text.replace('%c', ''); setMessage([...message, newMessage]); }; })(console.log.bind(console)); }None of the answers here consider console messages that get passed multiple parameters. E.g. console.log("Error:", "error details")).
The function that replaces the default log function better regards all function arguments (e.g. by using the arguments object). Here is an example:
console.log = function() { log.textContent += Array.prototype.slice.call(arguments).join(' '); } (The Array.prototype.slice.call(...) simply converts the arguments object to an array, so it can be concatenated easily with join().)
When the original log should be kept working as well:
console.log = (function (old_log, log) { return function () { log.textContent += Array.prototype.slice.call(arguments).join(' '); old_log.apply(console, arguments); }; } (console.log.bind(console), document.querySelector('#log'))); A complete solution:
var log = document.querySelector('#log'); ['log','debug','info','warn','error'].forEach(function (verb) { console[verb] = (function (method, verb, log) { return function () { method.apply(console, arguments); var msg = document.createElement('div'); msg.classList.add(verb); msg.textContent = verb + ': ' + Array.prototype.slice.call(arguments).join(' '); log.appendChild(msg); }; })(console[verb], verb, log); }); (An example of a framework that emits messages with multiple parameters is Video.js. But there is certainly many others.)
Edit: Another use of multiple parameters is the formatting capabilities of the console (e.g. console.log("Status code: %d", code).
About errors that are not shown
(Update Dec. 2021)
If any code crashes with an uncaught error, in might not show up in the div. One solution could be, if possible, to wrap all code in a try block to catch such errors and log them manually to the div.
try { // Code that might throw errors... } catch(err) { // Pass the error to the overridden error log handler console.error(err); } 5 Comments
JSON.stringify() result for each of the arguments, since often they will be objects. Currently it's just outputting [object Object], and I haven't yet figured out where to use JSON.stringify() in your code. Thanks for the start, though.$(document).ready(function () { ... });msg.textContent = verb + ' ' + JSON.stringify(Array.prototype.slice.call(arguments)); works.Else, if you were concerned at keeping log, warn and error separate from one another, you could do something like this (adapted from MST's answer):
var log = document.querySelector('#log'); ['log','warn','error'].forEach(function (verb) { console[verb] = (function (method, verb, log) { return function (text) { method(text); // handle distinguishing between methods any way you'd like var msg = document.createElement('code'); msg.classList.add(verb); msg.textContent = verb + ': ' + text; log.appendChild(msg); }; })(console[verb].bind(console), verb, log); }); where #log is your HTML element. The variable verb is one of 'log', 'warn', or 'error'. You can then use CSS to style the text in a distinguishable way. Note that a lot of this code isn't compatible with old versions of IE.
3 Comments
How about something as simple as:
console.log = function(message) {$('#debugDiv').append('<p>' + message + '</p>');}; console.error = console.debug = console.info = console.log 5 Comments
<!DOCTYPE html> <html> <head> <title>Page Title</title> </head> <body> <div id="logger" class="web_console"></div> <script type="text/javascript"> // Overriding console object var console = {}; // Getting div to insert logs var logger = document.getElementById("logger"); // Adding log method from our console object console.log = function(text) { var element = document.createElement("div"); var txt = document.createTextNode(text); element.appendChild(txt); logger.appendChild(element); } // testing console.log("Hello World..."); console.log("WOW"); /** console.log prints the message in the page instead browser console, useful to programming and debugging JS using a Android phone */ </script> </body> </html> Comments
I created a zero-dependency npm module for this case: console-events (surely if you're okay to use nodejs :P)
You can add event listener like that:
const { console } = require('console-events'); console.addEventListener('log', (e) => { e.preventDefault(); //if you need to prevent normal behaviour e.g. output to devtools console $('#debugDiv').append('<p>' + message + '</p>'); }) 2 Comments
webpack or gulp to bundle it to your javascript, so require will automatically put a module code into your output JSabout console.log
✔️ variable number of arguments
console_log = console.log console.log = (...a)=> { outDiv.innerHTML += a.join(' ') + '<br>' } ❌ handle object representation
I thinks this is complex
JSON.stringify() can't handle all object.
❌ handle other behavior
'%s' '%c' things..
not impossible, but cumbersome
some related project
https://jsconsole.com/
https://github.com/remy/jsconsole/blob/9bad5db/src/core/components/Console.jshttps://console.re/
https://github.com/kurdin/console-remotehttps://npmjs.com/package/weinre
https://people.apache.org/~pmuellr/weinre/docs/latest/Home.htmlhttps://eruda.liriliri.io/
https://github.com/liriliri/eruda