1. 程式人生 > >Java高階--Java執行緒執行棧資訊的獲取

Java高階--Java執行緒執行棧資訊的獲取

*/

public LocationInfo(Throwable t, String fqnOfCallingClass) {

String s;



t.printStackTrace(pw);

s = sw.toString();

sw.getBuffer().setLength(0);

…. // 這裡的程式碼省略

}

[/code]



這裡我們可以看到整體的實現思路。

首先,t.printStackTrace(pw); 獲得stack trace字串。這個t是 new Throwable()的結果。使用者程式呼叫Log4J方法之後,Log4J自己又進行了4次呼叫,然後才獲得了 t = new 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)

那麼,往下走4行,就可以回到使用者程式本身的呼叫資訊:

at callers.fully.qualified.className.methodName(FileName.java:74)

這一行裡面,類名、方法名、檔名、行號等資訊全有了。解析這一行,就可以獲得需要的所有資訊。

三、JDK1.4 Log的相關實現
Log4J大獲成功,Sun決定在JDK1.4中引入這個Log功能。

為了免去解析StackTrace字串的麻煩,JDK1.4引入了一個新的類,StackTraceElement。



public final class StackTraceElement implements java.io.Serializable {

// Normally initialized by VM (public constructor added in 1.5)

private String declaringClass;

private String methodName;

private String fileName;

private int lineNumber;



可以看到,恰好包括類名、方法名、檔名、行號等資訊。

我們來看JDK1.4 Log的相關實現。

LocationInfo.java 的infoCaller方法(推算呼叫者)



// Private method to infer the callers class and method names

private void inferCaller() {



// Get the stack trace.

StackTraceElement stack[] = (new Throwable()).getStackTrace();

// First, search back to a method in the Logger class.

…. // 這裡的程式碼省略

// Now search for the first frame before the "Logger" class.

while (ix < stack.length) {

StackTraceElement frame = stack[ix];

String cname = frame.getClassName();

if (!cname.equals("java.util.logging.Logger"))

// Weve found the relevant frame.

… // 這裡的程式碼省略

}

// We haven found a suitable frame, so just punt. This is

// OK as we are only committed to making a "best effort" here.

}



從註釋中就可以看出實現思路。過程和Log4J異曲同工。只是免去了解析字串的麻煩。

四、Log4J 1.3 alpha的相關實現
既然JDK1.4中引入了StackTraceElement類,Log4J也要與時俱進。LocationInfo類也有了相應的變化。



/**

Instantiate location information based on a Throwable. We

expect the Throwable t
, to be in the format