`

log4j 获取行号

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

Java代码  收藏代码

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


而且可以 根据异常堆栈可以找到方法的调用链。
顺便研究一下 log4j 的源码(1.2.16),也是同样的方法实现的:
new Throwable() 然后根据该 Throwable 获取堆栈信息
Java代码  收藏代码

    public LocationInfo getLocationInformation() { 
      if(locationInfo == null) { 
        locationInfo = new LocationInfo(new Throwable(), fqnOfCategoryClass); 
       //org.apache.log4j.spi.LoggingEvent  253 行 
      } 
      return locationInfo; 
    } 



Java代码  收藏代码

    //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 发现其实可以从当前线程里面拿到堆栈信息的
Java代码  收藏代码

    StackTraceElement[] stes = Thread.currentThread().getStackTrace(); 


另外还有一个关于线程信息的类 【 java.lang.management.ThreadInfo 】
Java代码  收藏代码

    ThreadInfo ThreadMXBean.getThreadInfo(long); 
    //获取不带堆栈信息的 ThreadInfo 
    ThreadInfo[] ThreadMXBean.dumpAllThreads(boolean, boolean); 
    //获取所有线程的 ThreadInfo 并带有堆栈信息 



转载请保留地址:http://lchshu001.iteye.com/blog/1472583
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics