Log4j从异常堆栈中获取类、方法、行数演示
好奇Log4j格式化日志时,上述信息获取方式。 跟踪代码,发现了其利用异常实现的,下面是简单例子:
package com.billstudy.test;
import java.lang.reflect.Method;
/**
* Test exception stack infomation analysis
* @author LiBiao - Bill
* @since V1.0 2016年4月15日 - 下午5:48:35
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public class StackDemo {
private static Method getStackTraceMethod;
private static Method getClassNameMethod;
private static Method getMethodNameMethod;
private static Method getFileNameMethod;
private static Method getLineNumberMethod;
static {
Class[] noArgs = null;
try {
getStackTraceMethod = Throwable.class.getMethod("getStackTrace", noArgs);
Class stackTraceElementClass = Class.forName("java.lang.StackTraceElement");
getClassNameMethod = stackTraceElementClass.getMethod("getClassName", noArgs);
getMethodNameMethod = stackTraceElementClass.getMethod("getMethodName", noArgs);
getFileNameMethod = stackTraceElementClass.getMethod("getFileName", noArgs);
getLineNumberMethod = stackTraceElementClass.getMethod("getLineNumber", noArgs);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Obtain relevant information from the exception stack
* @author LiBiao - Bill
* @since V1.0 2016年4月15日 - 下午6:14:33
* @param e
* @param className
*/
private static void analysisException(Exception e, String className) {
Object[] noArgs = null;
try {
Object[] elements = (Object[]) getStackTraceMethod.invoke(e,noArgs);
for (int i = 0; i < elements.length; i++) {
Object element = elements[i];
String clazz = (String) getClassNameMethod.invoke(element, noArgs);
// find
if (className.equals(clazz)) {
String method = (String) getMethodNameMethod.invoke(element, noArgs);
int line = (Integer) getLineNumberMethod.invoke(element, noArgs);
String fileName = (String) getFileNameMethod.invoke(element, noArgs);
String result = String.format(
"class:%s \r\n "
+ "method:%s \r\n "
+ "line:%s \r\n "
+ "fileName:%s \r\n errorMsg:%s", clazz,method,line,fileName,e.getMessage());
System.out.println(result);
break;
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
public static void main(String[] args) {
String findClassName = "com.billstudy.test.StackDemo$B";
try {
A a = new A();
a.test();
} catch (Exception e) {
//e.printStackTrace();
analysisException(e, findClassName);
}
// a.nullException();
}
public static class A {
private B b = new B();
public void test() {
b.test();
}
public void nullException() {
String target = null;
target.intern();
}
}
public static class B {
private C c = new C();
public void test() {
c.test();
}
}
public static class C {
public void test() {
throw new RuntimeException("别问我为啥,就是想抛个异常 ~");
}
}
}
输出:
class:com.billstudy.test.StackDemo$B
method:test
line:97
fileName:StackDemo.java
errorMsg:别问我为啥,就是想抛个异常 ~