I. Introduction of the problem
When we use the log function (JDK log or log4j) in Java programs, we find that the log system will automatically print out rich information for us in the following format:
[Run time] [Current class name] [Method Name]
Info: [user Info]
Specific examples such as Tomcat startup information:
June 9, 11:22:41 AM org.apache.coyote.http11.Http11Protocol start
Info:starting Coyote http/1.1 on port 8080
Looks like there's nothing magical about it, does it just print a message? But if curiosity is a little bit more, and pursuing the principles behind it, you'll find it really magical.
The log information above [the current class name] [method name] part is not added by the user, but the log system is automatically added. This means that the log system can automatically determine which method of which class the current execution statement is. How is this done?
We went through the java.lang.reflection package, fantasizing about finding a statement statement level reflection class that gets method from this statement object, And then get declared Class with this method. Does this not get the corresponding class and method information? This is a good idea, but it can only be an idea; because there is no such statement object.
Think again. By the right, does Java have a thread class? Thread.CurrentThread () method gets the current thread, can we get the currently running methods and class from this current thread? Unfortunately, if you are still using JDK1.4 or the following version, then you can not find such a method. (JDK1.5 's case will be followed)
Think again. Yes, we all have a deep impression that when the system throws a exception, it always prints out a string of messages telling us where the exception occurs, and a layer of call relationship. We can also call exception's Printstacktrace () method to print this information ourselves. This is not the current line Cheng broker's storehouses information? Found it, that's it.
Exception's Printstacktrace () method inherits from Throwable, let's take a look at how the JDK's Throwable printstacktrace () method is implemented.
Let's take a look at JDK1.3 's source code and find out that the Throwable.printstacktrace () method calls a native PrintStackTrace0 () method. We can't find any clues that can be used in our own Java code.
Then what? Does the output string of Throwable.printstacktrace () contain all the information for the current line Cheng broker's storehouses? We can extract the information we need from this string. JDK1.3 of the Times, can only do so.
Ii. related implementation of LOG4J 1.2
LOG4J 1.2 is the work of the JDK1.3 era. Let's look at the relevant source code.
[code]
/**
Instantiate location information based on a Throwable. We
expect the Throwable t, to be in the format
java.lang.Throwable
...
at org.apache.log4j.PatternLayout.format(PatternLayout.java:413)
at org.apache.log4j.FileAppender.doAppend(FileAppender.java:183)
at org.apache.log4j.Category.callAppenders(Category.java:131)
at org.apache.log4j.Category.log(Category.java:512)
at callers.fully.qualified.className.methodName(FileName.java:74)
...
*/
public LocationInfo(Throwable t, String fqnOfCallingClass) {
String s;
…
t.printStackTrace(pw);
s = sw.toString();
sw.getBuffer().setLength(0);
…. // 这里的代码省略
}
[/code]