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);// findif (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$Bmethod:testline:97fileName:StackDemo.javaerrorMsg:别问我为啥,就是想抛个异常 ~