log4j 获取行号

今天看log4j的日志,突然注意到log4j 可以打印行号.
行号之类的信息一般调试的时候会用到,java API 猜测应该不会封装调试器API出来(不清楚调试器的实现)
后来想到了异常堆栈的时候是可以打印行号的,所以是不是可以通过异常获取行号呢?
查看API 

StackTraceElement[] java.lang.Throwable.getStackTrace() //堆栈元素
int java.lang.StackTraceElement.getLineNumber() //行号
String java.lang.StackTraceElement.getMethodName() //方法名

而且可以 根据异常堆栈可以找到方法的调用链。
顺便研究一下 log4j 的源码(1.2.16),也是同样的方法实现的:
new Throwable() 然后根据该 Throwable 获取堆栈信息
  public LocationInfo getLocationInformation() {
    if(locationInfo == null) {
      locationInfo = new LocationInfo(new Throwable(), fqnOfCategoryClass);
     //org.apache.log4j.spi.LoggingEvent  253 行
    }
    return locationInfo;
  }


//org.apache.log4j.spi.LocationInfo 138 行
public LocationInfo(Throwable t, String fqnOfCallingClass) {
Object[] noArgs = null;
Object[] elements =  (Object[]) getStackTraceMethod.invoke(t, noArgs);
String prevClass = NA;
for(int i = elements.length - 1; i >= 0; i--) {
  String thisClass = (String) getClassNameMethod.invoke(elements[i], noArgs);
  if(fqnOfCallingClass.equals(thisClass)) {
    int caller = i + 1;
    if (caller < elements.length) {
      className = prevClass;
      methodName = (String) getMethodNameMethod.invoke(elements[caller], noArgs);
      fileName = (String) getFileNameMethod.invoke(elements[caller], noArgs);
      if (fileName == null) {
        fileName = NA;
      }
      int line = ((Integer) getLineNumberMethod.invoke(elements[caller], noArgs)).intValue();
      if (line < 0) {
        lineNumber = NA;
      } else {
        lineNumber = String.valueOf(line);
      }
      StringBuffer buf = new StringBuffer();
      buf.append(className);
      buf.append(".");
      buf.append(methodName);
      buf.append("(");
      buf.append(fileName);
      buf.append(":");
      buf.append(lineNumber);
      buf.append(")");
      this.fullInfo = buf.toString();
    }
    return;
  }
  prevClass = thisClass;
}
return;
//其他代码

不清楚调试器是怎么实现的.

重新看了一下JDK 发现其实可以从当前线程里面拿到堆栈信息的
StackTraceElement[] stes = Thread.currentThread().getStackTrace();

另外还有一个关于线程信息的类 【 java.lang.management.ThreadInfo 】
ThreadInfo ThreadMXBean.getThreadInfo(long);
//获取不带堆栈信息的 ThreadInfo
ThreadInfo[] ThreadMXBean.dumpAllThreads(boolean, boolean);
//获取所有线程的 ThreadInfo 并带有堆栈信息


转载请保留地址:http://lchshu001.iteye.com/blog/1472583

你可能感兴趣的:(java,log4j)