How can i write a console log wrapper that:
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/
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 .
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.
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.
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");
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.
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)
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With