【log4j】log4j中获取调用日志对象的类名称

在使用log4j过程中,很好奇log4j是如何获取到调用类以及调用方法的信息的,如

Logger.getLogger("").info("info");
Logger.getLogger("").warn("warn");
Logger.getLogger("").error("error");

通过查资料想到在java中,可以使用

 Thread.currentThread().getStackTrace();

获取堆栈信息,例如

public class Log4jTest {
    public static void main(String[] args) {
        StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
        for (int i = 0; i < stackTraceElements.length; i++) {
            System.out.println(stackTraceElements[i]);
        }
    }
}

运行程序,可以看到结果为

堆栈信息的规则为先进后出,最上方的为堆栈顶,最下面为堆栈底,因此可以知道,这次调用共产生了两个线程,在main调用的时候先产生了一个线程,而后在调用Thread.currentThread().getStackTrace();的时候又产生了一个线程

分析完毕,自己写一个小例子,看看能否实现

class MLog {

    public static void info() {
        StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
        System.out.println(stackTraceElements[2].getClassName());
    }
}

class B {
    public void bbb() {
        MLog.info();
    }
}

public class Test {

    public static void main(String[] args) {
        new B().bbb();
        MLog.info();
    }
}

运行结果为

可以看到结果正确,那么为什么stackTraceElements指定的下标为2呢,根据之前的分析,程序先调用main生成第一个线程,然后创建对象B调用bbb()方法,生成第二个线程,再然后调用MLog的info()方法生成第三个线程,最后调用Thread.currentThread().getStackTrace()生成第四个线程,由于实际调用MLog.info()方法的为对象B的bbb()方法,因此下标指定为2,同理,在main()中直接调用MLog.info()也是一样,main生成第一个线程,调用MLog的info()方法生成第二个线程,最后调用Thread.currentThread().getStackTrace()生成第三个线程,由于实际调用MLog.info()方法的位置是在main()中,所以下标同样应指定为2。注意点:堆栈为先进后出,所以在stackTraceElements中下标越大的调用顺序越靠前,也就是越靠近堆栈底

====================================================================

小白文章,如有错误希望能够给予指正

你可能感兴趣的:(【log4j】log4j中获取调用日志对象的类名称)