Log4j多執行緒實踐

2021-09-01 02:36:33 字數 2367 閱讀 6603

開發環境:

jdk:1.8

log4j:1.2.8

陷阱:上述思路是常規想法,沒有問題,但log4j中有個陷阱:單例模式。在log4j中,配置的每個logger,都只有乙個例項。即在不同執行緒中,取到的同名logger,全都是同乙個例項。那麼,之前的思路就行不通了。除非為每個執行緒配置乙個特定的logger,或者配置一定數量的logger,組成乙個logger池,各執行緒爭用logger池中的logger例項。但這兩種方法要麼不夠靈活,要麼邏輯複雜,並不是我想要的方案。

分析:既然問題出在單例模式上,那我們只要在建立子執行緒的時候,為執行緒建立乙個私有的logger例項,不就行了嗎。遺憾的是,log4j並沒有提供建立全新logger例項的介面給我們使用,logger物件只能通過logger.getlogger(*)方法獲取,而不能new乙個logger物件。怎麼辦?只能重寫logger類,或建立logger的子類了。

實踐:重寫logger類肯定是不合適的,所以我們要寫個自己的logger類mylogger,繼承log4j的logger類。通過反編譯log4j的logger類,發現logger也只是一層封裝,真正的業務邏輯在logger的父類category中,而logger和category中的大部分方法和成員變數,都是可繼承的,log4j已經知道了我們要這麼做並且願意讓我們繼承。我的mylogger類如下:

package org.huangguanhua.test.log;

import org.apache.log4j.level;

import org.apache.log4j.logger;

import org.apache.log4j.patternlayout;

public class mylogger extends logger

public mylogger(string name, string logid, level level) [%t %l] %m%n");

this.repository = logger.getrootlogger().getloggerrepository();

this.setlevel(level);

this.parent = logger.getrootlogger();

}}

if (aai == null)}

從上面的**不難看出,category中還有乙個成員變數repository似乎也是必不可少的,但它是protected修飾的,子類可以繼承。但它是如何初始化的呢?在category的**中,我們發現只有一處地方對repository進行了設定,如下:

final void sethierarchy(loggerrepository repository)
定義了mylogger後,就要看看能不能使用。我寫了mainclass和testthread兩個類,來檢驗mylogger。testthread繼承自thread,在run()方法中,建立了mylogger的例項logger,然後每隔一秒鐘用logger往日誌中輸出一句話;mainclass建立了20個testthread例項(即20個子執行緒),然後啟動它們。**如下:

testthread:

package org.huangguanhua.test.log;

import org.apache.log4j.level;

import org.apache.log4j.logger;

public class testthread extends thread catch (interruptedexception e)

} }}

mainclass:

package org.huangguanhua.test.log;

public class mainclass

}}

除了上述檔案,還需要乙個簡單的log4j配置檔案log4j.properties,檔案內容如下:

log4j.rootlogger=info, stdout, log
測試工程目錄結構如下圖:

工程執行後,會在d盤的log目錄下生成相應的日誌檔案,每個執行緒乙個檔案。注意,因為log4j不會自動建立不存在的目錄,所以在工程執行之前,需要確保日誌輸出目錄存在,否則報錯。工程執行結果如下:

log4j日誌系統 Log4j

1.1 log4j的三大核心元件 1.2 loggers 記錄器 1.4 layouts 布局 org.apache.log4j.htmllayout 以html 形式布局 org.apache.log4j.patternlayout 可以靈活地指定布局模式 org.apache.log4j.lay...

LOG4J配置及實踐

日誌級別 error varn info debug trace 日誌的級別越低,輸出的資訊越詳細,即只輸出不小於設定級別的資訊 使用 配置檔案 設定全域性日誌配置,輸入error級別,stdout輸出到控制台 log4j.rootlogger error,stdout 設定自定義的日誌級別 log...

Log4J學習 十六 Log4j的預設啟動流程一

既然要求我們自己來配置log4j,那麼又會出現相關的問題,不管我們採用哪種配置方式,log4j總會要求我們在應用啟動的最開始,完成log4j的配置,所以我們不得不在乙個靜態類的靜態 塊中完成相關的 配置。這對程式設計師和log4j框架本身的使用,都是乙個不友好的設計。考慮到這些因素,log4j提供了...