Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

console.log wrapper that keeps line numbers and supports most methods? [closed]

How can i write a console log wrapper that:

  • Keeping the recorded line number and file name of the log statement intact
  • Provides access to all log severity methods (error, log, debug, ...) and shows them in the console as they where logged
  • does provide some fallback (for example calls the log method when the browser does not support error)
  • can be switched off in a central location, so I can switch off logging for production
  • does handle the case that no console exists, and does not throw errors

Since logging in Java Script is so inconsistent, there must be some solution. Implementing it myself is a little bit tedious, but there seems to be no good library.

I currently found this logger that provides all the features, but it does mess up the line numbers. http://benalman.com/projects/javascript-debug-console-log/

like image 600
Paul Weber Avatar asked Jul 03 '12 09:07

Paul Weber


People also ask

How do you wrap a console log?

Type it and press Ctrl+Alt+W + W . Another way to console. log your variables is to simply place your mouse cursor on them and then wrap them on the line below with Ctrl+Alt+W + Down or the line above with Ctrl+Alt+W + Up .

What is console log method?

The console. log() method outputs a message to the web console. The message may be a single string (with optional substitution values), or it may be any one or more JavaScript objects. Note: This feature is available in Web Workers.

What is the difference between console log and console warn?

log method, and its friends console. warn and console. error , lets you dump objects in the console. The only difference between these functions is their “type” classification, which looks slightly different and can be filtered when viewing the console output.


2 Answers

There is my own log4javascript, which has its own logging console but also provides a wrapper around console.log. It fulfils all your criteria except keeping line numbers intact, which is impossible to achieve if you're wrapping calls to console.log() etc. in another function.

var log = log4javascript.getLogger("main"); var appender = new log4javascript.BrowserConsoleAppender(); log.addAppender(appender); log.debug("Hello world"); 
like image 176
Tim Down Avatar answered Oct 05 '22 08:10

Tim Down


I would also recommend log4javascript and explain how you can still keep the information about the printed filename and line, at least in Chrome.

I am not talking about changing the filename and line printed by Chrome but you can get to the information you are interested in and append it to the log statement. My solution has been a quick hack but I think with a little more work you can get nicely formatted log statements. It probably has also a heavy performance-impact, but since you won't leave your logs activated in production this shouldn't be too much of a problem.

The Concept

In Chrome you can create an Error object which provides a stack property that shows you your current stack location and somewhere in the stack string you find the file and line number of your calling script.

  > new Error().stack   "Error     at eval at <anonymous> (eval at evaluate (unknown source))     at eval at evaluate (unknown source)     at FrameMirror.evaluate (native)     at Object.evaluate (unknown source)     at Object._evaluateOn (unknown source)     at Object._evaluateAndWrap (unknown source)     at Object.evaluateOnCallFrame (unknown source)     at meinAjaxAufruf (http://localhost:8080/numberajax.js:21:9)     at HTMLInputElement.onkeyup (http://localhost:8080/numberajax.html:15:188)" 

For a log4javascript call the stack trace might look something like this:

"Error     at Object.append (http://localhost:8080/log4javascript_uncompressed.js:1921:17)     at Object.doAppend (http://localhost:8080/log4javascript_uncompressed.js:1047:9)     at Object.callAppenders (http://localhost:8080/log4javascript_uncompressed.js:647:27)     at Object.log (http://localhost:8080/log4javascript_uncompressed.js:640:10)     at Object.debug (http://localhost:8080/log4javascript_uncompressed.js:748:9)     at meinAjaxAufruf (http://localhost:8080/numberajax.js:36:16)     at HTMLInputElement.onkeyup (http://localhost:8080/numberajax.html:16:188)" 

And the file and line that made the log4javascript call and that i am interested in is

at meinAjaxAufruf (http://localhost:8080/numberajax.js:36:16) 

The Solution

I am guessing that the stack depth from the script your interested in to where the actual console call happens is always the same. So now you simply have to find out where the BrowserConsoleAppender makes its window.console access and add the line you are interested in to the formatted string. I did the following changes to log4javascript_uncompressed.js (version 1.4.2 line 1913):

} else if (window.console && window.console.log) { // Safari and Firebug         var formattedMesage = getFormattedMessage();          //---my additions         var isChrome = navigator.userAgent.indexOf("Chrome") !== -1;         if(isChrome){             var stack = new Error().stack;             var lineAccessingLogger = stack.split("\n")[6];             formattedMesage += "\n" + lineAccessingLogger;         }         //---          // Log to Firebug using its logging methods or revert to the console.log         // method in Safari         if (window.console.debug && Level.DEBUG.isGreaterOrEqual(loggingEvent.level)) {             window.console.debug(formattedMesage);         } else if (window.console.info && Level.INFO.equals(loggingEvent.level)) {         ... 

Now instead of

17:53:22,872 DEBUG - sending /NumberServlet?zahl=1&text=                                                  log4javascript.js:154 

I get

17:55:53,008 DEBUG - sending /NumberServlet?zahl=1&text=      at meinAjaxAufruf (http://localhost:8080/numberajax.js:36:16) log4javascript_uncompressed.js:1930 

It sure isn't a nice solution :), but I get what I need.

With a little more knowledge of the framework I suppose one could change the PatternLayout in a way that you can define how to print the file name/location and line number.

edit Instead of my prior solution I made some modifications to the PatternLayout.prototype.format function, so now I can use the additional option %l to define where and how I want to output the calling file and its line. I published my changes and a usage example as a Gist.

like image 27
LeoR Avatar answered Oct 05 '22 07:10

LeoR