How can I write caller location information (Java source file and line), in a log file using Java and log4j, but without hurting performance? log4j allow yo开发者_JS百科u to write such information in the log file, but it uses the stack trace to get that it information, every time a log statement is issued, what causes performance degradation. I'm looking for a performance friendly alternative, like getting the location information at compile time instead at runtime. It is possible to use annotations to accomplish that? Or maybe some other technique?
How about making it part of the build process to replace certain placeholders, like $filename$
and $linenumber$
in this snippet.
logger.info("The original message... $filename$ $linenumber$");
To replace the filename, it may suffice to have keyword substitution with your revision control system. Disclaimer: this is just from the top of my head, I never tried it myself.
I agree with Rob that it is generally unnecessary. Usually there's some distinct string in a log message, searching for it will get to the source. With a good IDE this is really fast.
Now, given the question as is, this is a possible solution:
Class Foo
void bar()
new Logger(){} . warn("blah");
for each log action at runtime, a new object is created - that's not a problem.
for each line of source containing such log statement, a new class is created. that can be too many.
here's how the magic works:
abstract public class Logger
static Map<Class, String> sourceInfo = new ...
public Logger()
Class thisClass = this.getClass();
String info = sourceInfo.get(thisClass);
if(info==null)
info = ... // init from stack trace
sourceInfo.put(thisClass,info)
this.info = info
public void warn(msg)
log(WARN, this.info,msg)
精彩评论