差異處

這裏顯示兩個版本的差異處。

連向這個比對檢視

下次修改
前次修改
java:log4j:bridge [2013/04/29 13:41]
tony 建立
java:log4j:bridge [2023/06/25 09:48] (目前版本)
行 1: 行 1:
 {{tag>​java log4j}} {{tag>​java log4j}}
 ====== Bridge JUL to SLF4j ====== ====== 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? ===== ===== How to use? =====
 +==== Config ====
 +直接看我的cofng。首先我將JUL的所有Log level打開。假如你沒這麼做,JUL預設Level為Info,你只有在Info Level以上的才有辦法將內容導向SLF4J;再來就是針對你要的Package做設定。我選用[[https://​code.google.com/​p/​expect4j/​|Expect4j]]做範例
 +<​code>​
 +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
 +</​code>​
 +這是JUL與Log4j之對應,可以根據這個設定你的config。(參考[[http://​www.slf4j.org/​api/​org/​slf4j/​bridge/​SLF4JBridgeHandler.html|Javadoc for SLF4JBridgeHandler]])
 +<​code>​
 +FINEST ​ -> TRACE
 +FINER   -> DEBUG
 +FINE    -> DEBUG
 +INFO    -> INFO
 +WARNING -> WARN
 +SEVERE ​ -> ERROR
 +</​code>​
 +==== Load Config ====
 +除了用檔案設定,當然你也可以透過寫Code的方式去設定,但我比較偏好透過檔案。提供給你兩種方法:​ 1. 從Classpath讀取設定;2. 從File path讀取設定。我將檔案放在source folder **test**目錄下。
 +=== Load from ClassPath ===
 +<code java>
 +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);​
 + }
 +}
 +</​code>​
 +註: Cleaner是自製類別,負責關閉串流。
 +=== Load from FilePath ===
 +這是透過java.util.logging.config.file的設定,你也可以藉由傳入-Djava.util.logging.config.file參數。
 +<code java>
 +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);​
 + }
 +}
 +</​code>​
 +==== Bridging ====
 +先閱讀一下範例程式:​
 +<code java>
 +@Test
 +public void test() throws Exception {
 + readLog4jConfigFromClasspath();​
 + //​readLog4jConfigFromFilePath();​
 +
 + SLF4JBridgeHandler.removeHandlersForRootLogger();​
 + SLF4JBridgeHandler.install();​
 +
 + Expect4j.log.finest("​test1"​);​
 + Expect4j.log.info("​test2"​);​
 + Expect4j.log.fine("​test3"​);​
 +}
 +</​code>​
 +最重要的兩個method是removeHandlersForRootLogger與install。以下圖結果來說,假如你沒呼叫removeHandlersForRootLogger,原本JUL的訊息也會被Log,如圖片中紅色的字。install就是安裝bridge的功能,當然也有uninstall去移除拉!另外紅色的有三筆,黑色的只有兩筆,原因是finest為TRACE Level,設定為Debug並不會顯示。\\
 +{{:​java:​log4j:​log4j_slf4j_jul_bridge.png|}}\\
 +\\
 +友藏內心獨白:​ 趁著修改測試程式,順便學習新招。
 ===== Reference ===== ===== Reference =====
   * [[http://​www.slf4j.org/​api/​org/​slf4j/​bridge/​SLF4JBridgeHandler.html|Javadoc for SLF4JBridgeHandler]]   * [[http://​www.slf4j.org/​api/​org/​slf4j/​bridge/​SLF4JBridgeHandler.html|Javadoc for SLF4JBridgeHandler]]
行 10: 行 90:
   * [[https://​code.google.com/​p/​expect4j/​|Expect4j]]   * [[https://​code.google.com/​p/​expect4j/​|Expect4j]]
   * [[http://​logback.qos.ch/​manual/​configuration.html#​LevelChangePropagator|Level Change Propagator]]   * [[http://​logback.qos.ch/​manual/​configuration.html#​LevelChangePropagator|Level Change Propagator]]
 +  * [[http://​stackoverflow.com/​questions/​805701/​load-java-util-logging-config-file-for-default-initialization|Stack over flow for "Load java.util.logging.config.file for default initialization"​ - classpath]]
 +  * [[http://​bitingcode.blogspot.tw/​2012/​01/​jul-configuration.html|JUL Configuration]]
 +=====    =====
 +----
 +\\
 +~~DISQUS~~