跳到主要內容

Bridge JUL to SLF4j

Problem

許多third-party api都是使用Java Util Logging(JUL)來Log資訊,但你可能會遇到幾點問題:

  • Log格式與Log4j或Slf4j不相同,看了礙眼。
  • 我平常不需要JUL的訊息,但發生問題時就需要了。怎樣可以方便設定?
  • 不要讓我學兩份Config的方式。好嗎?

也許還有種種原因,我只是希望能有一個統一輸出界面。還好有好心人士做了Bridge,目前看到有Log4j的JULBridgeLogManager與SLF4J的SLF4JBridgeHandler。這篇文章中挑SLF4JBridgeHandler做介紹。

How to use?

Config

直接看我的cofng。首先我將JUL的所有Log level打開。假如你沒這麼做,JUL預設Level為Info,你只有在Info Level以上的才有辦法將內容導向SLF4J;再來就是針對你要的Package做設定。我選用Expect4j做範例

log4j.rootCategory=WARN, CONSOLE

.level= ALL
handlers= java.util.logging.ConsoleHandler
java.util.logging.ConsoleHandler.level= ALL

log4j.additivity.expect4j=false
log4j.logger.expect4j=TRACE, CONSOLE

# CONSOLE is set to be a ConsoleAppender using a PatternLayout.
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.Threshold=TRACE
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{dd/MM HH:mm:ss} %5p[%t] %X{usedheap}(%F:%M:%L) - %m%n

這是JUL與Log4j之對應,可以根據這個設定你的config。(參考Javadoc for SLF4JBridgeHandler)

FINEST  -> TRACE
FINER   -> DEBUG
FINE    -> DEBUG
INFO    -> INFO
WARNING -> WARN
SEVERE  -> ERROR

Load Config

除了用檔案設定,當然你也可以透過寫Code的方式去設定,但我比較偏好透過檔案。提供給你兩種方法: 1. 從Classpath讀取設定;2. 從File path讀取設定。我將檔案放在source folder test目錄下。

Load from ClassPath

private void readLog4jConfigFromClasspath(){
	InputStream is = this.getClass().getResourceAsStream("/log4j.properties");
	try { 
		LogManager.getLogManager().readConfiguration(is); 
	} catch(Exception e) {
		throw new RuntimeException(e);
	} finally {
		Cleaner.close(is);
	}
}

註: Cleaner是自製類別,負責關閉串流。

Load from FilePath

這是透過java.util.logging.config.file的設定,你也可以藉由傳入-Djava.util.logging.config.file參數。

private void readLog4jConfigFromFilePath(){
	Properties prop = System.getProperties();
	prop.setProperty("java.util.logging.config.file", "test/log4j.properties"); 
	try { 
		LogManager.getLogManager().readConfiguration(); 
	} catch(Exception e) {
		throw new RuntimeException(e);
	}
}

Bridging

先閱讀一下範例程式:

@Test
public void test() throws Exception {
	readLog4jConfigFromClasspath();
	//readLog4jConfigFromFilePath();
 
	SLF4JBridgeHandler.removeHandlersForRootLogger();
	SLF4JBridgeHandler.install();
 
	Expect4j.log.finest("test1");
	Expect4j.log.info("test2");
	Expect4j.log.fine("test3");
}

最重要的兩個method是removeHandlersForRootLogger與install。以下圖結果來說,假如你沒呼叫removeHandlersForRootLogger,原本JUL的訊息也會被Log,如圖片中紅色的字。install就是安裝bridge的功能,當然也有uninstall去移除拉!另外紅色的有三筆,黑色的只有兩筆,原因是finest為TRACE Level,設定為Debug並不會顯示。

友藏內心獨白: 趁著修改測試程式,順便學習新招。

Reference

留言

這個網誌中的熱門文章

PostgreSQL - Unattended installation on windows

Introduction 要將別人軟體包裝到自己軟體中,不可或缺的東西就是Unattended installation。以Unattended installation來說,我們可以選擇透過Installer的silent mode安裝,也可以透過把目標軟體做成portable的版本。本篇文章分享這兩種方法,教導大家如何將PostgreSQL透過Unattended installation方式安裝到目標系統成為service。 Note. 本篇以PostgreSQL 10.7為例。 Install with installer Tips 安裝程式或反安裝程式的參數,除了可以直接上官網搜尋Installation User Guide以外,也可以直接使用help參數查詢: postgresql- 10.7 - 2 -windows-x64.exe --help Windows安裝程式主要有EnterpriseDB與BigSQL兩種。BigSQL版本安裝元件是透過網路下載且支援參數不如EnterpriseDB版本多,以我們需求來說,我們傾向於使用EnterpriseDB版本。接下來分享給大家安裝與反安裝方法。 Installation @ echo off set INSTALL_DIR =C:\postgres10 set INSTALLER =postgresql- 10.7 - 2 -windows-x64.exe   rem options for installation set SSMDB_SERVICE =postgresql- 10 set MODE =--unattendedmodeui none --mode unattended   set DB_PASSWD =--superpassword postgres set DB_PORT =--serverport 5432   set SERVICE_NAME =--servicename % SSMDB_SERVICE %   set PREFIX =--prefix "%INSTALL_DIR%" set DATA_DIR =--datadir "%INSTALL_DIR%\data"   set OPTIONS =

How to install RIDE on Windows?

Introduction 多年沒在Windows上開發RobotFramework,趁著這次整理一下RIDE安裝方法。 目前RIDE最新版本與Python對應版本如下: (3.6 < python <= 3.11) Install current released version (2.0.8.1) with: pip install -U robotframework-ride 安裝Python 直接到Python官網找尋最新的3.11版本,我使用3.11.9: link 。安裝就是一直下一步而已。 安裝wxPython 每次安裝RIDE最困難的都是wxPython。看了一下 官網 描述,我就姑且相信一下: 接著進入下 載頁面 就有安裝教學。基本上就是到Python目錄下的Scripts直接執行以下command: pip install -U wxPython 安裝RIDE 接著就如RIDE官網所說,執行以下command: pip install -U robotframework-ride 啟動RIDE 直接在相同目錄下執行ride就可以啟動了,你也可以直接在桌面建ride連結,加快下次啟動時間。 沒想到這次這麼順利就安裝完成了。因為我是使用java去啟動robot framework,就不特別講要怎麼使用pip安裝robot framework了。

Hello World!

即將要搬家,因此舊網頁內容將慢慢轉移至Blogger。 如果要存取舊網頁,可以使用以下連結: https://wiki.tonylin.idv.tw/dokuwiki/doku.php