模擬log4j獲取日志對象調用所在的類名、方法名及行號


    當我們在記錄日志時,每個類中會定義一個日志對象,然后利用這個對象去寫日志,那么我們在處理日志時,如何能才能記錄日志對象所在的類、方法和行號呢?log4j中已經實現了該功能,那么它是怎么實現的呢?

    其實我們可以這樣,在要寫日志的代碼時獲得當前的線程信息,這樣我們就可以獲得上個線程的信息了(即對象寫日志所在類的信息)。

    先看以下列子。

新建Location類和Test類:

      Location:

public class Location {
	public void getInfo(){
		String location="";
		StackTraceElement[] stacks = Thread.currentThread().getStackTrace(); 
		location = "類名:"+stacks[2].getClassName() + "\n函數名:" + stacks[2].getMethodName()
		+ "\n文件名:" + stacks[2].getFileName() + "\n行號:"
		+ stacks[2].getLineNumber() + "";
		System.out.println(location);
	}
}

 

Test:

public class Test {

	public static void main(String[] args) {
		Location l = new Location();
		l.getInfo();
	}

}


執行Test中的main函數,得到以下結果:

類名:thread.Test
函數名:main
文件名:Test.java
行號:10


是不是輸出了Test類中調用的信息呢?那么有很多人就問了,為什么location類中調用的是stacts[2]而不是stacts[0]或其他的呢?

針對這個問題,我們可以將stacts數組里面的東西遍歷輸出一下就知道了:

StackTraceElement[] stacks = Thread.currentThread().getStackTrace(); 
		for(int i=0;i<stacks.length;i++){
			location = i+"  at "+stacks[i].getClassName() + "." + stacks[i].getMethodName()
			+ "(" + stacks[i].getFileName() + ":"
			+ stacks[i].getLineNumber() + ")";
			System.out.println(location);
		}


 

再次執行,輸出結果如下:

0  at java.lang.Thread.getStackTrace(Thread.java:1436)
1  at thread.Location.getInfo(Location.java:6)
2  at thread.Test.main(Test.java:7)


 

那么這就好理解了,線程是以棧形式存放的,

分析一下StackTraceElement[] stacks = Thread.currentThread().getStackTrace();

此代碼中會創建2個線程,調用Thread.currentThread().getStackTrace()時底層會創建一個線程,我們調用它也會創建一個線程,然后test調用getInfo函數時會創建一個線程,這樣總共就三個線程了,程序執行順序是先test類中調用getInfo方法,然后getInfo方法中調用StackTraceElement[] stacks = Thread.currentThread().getStackTrace();調用StackTraceElement[] stacks = Thread.currentThread().getStackTrace();時底層還會創建一個線程,根據棧的原理先進后出規則,他們的排隊順序就是上面輸出的結果了。


 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM