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.