差異處
這裏顯示兩個版本的差異處。
下次修改 | 前次修改 | ||
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~~ |