Intellij idea中使用SLF4J+log4j做日誌記錄

轉:https://blog.csdn.net/huwei2003/article/details/76071451

Intellij idea中使用SLF4J+log4j做日誌記錄

一、 簡介

SLF4J (Simple Logging Facade for Java) 不是具體的日誌解決方案,它只服務於各種各樣的日誌系統。按照官方的說法,SLF4J是一個用於日誌系統的簡單Facade,允許最終用戶在部署其應用時使用其所希望的日誌系統。
實際上,SLF4J所提供的核心API是一些接口以及一個LoggerFactory的工廠類。從某種程度上,SLF4J有點類似JDBC,不過比JDBC更簡單,在JDBC中,你需要指定驅動程序,而在使用SLF4J的時候,不需要在代碼中或配置文件中指定你打算使用那個具體的日誌系統。如同使用JDBC基本不用考慮具體數據庫一樣,SLF4J提供了統一的記錄日誌的接口,只要按照其提供的方法記錄即可,最終日誌的格式、記錄級別、輸出方式等通過具體日誌系統的配置來實現,因此可以在應用中靈活切換日誌系統。
二 應用程序中使用方法及配置
3 添加相應的包,在pom.xml中添加相應的依賴,然後點擊右下角的import changes 即可自動導入相應的包

pom.xml添加的內容如下:

[html] view plain copy
<dependencies>  
    <!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api -->  
    <dependency>  
        <groupId>org.slf4j</groupId>  
        <artifactId>slf4j-api</artifactId>  
        <version>1.7.2</version>  
    </dependency>  

    <!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-log4j12 -->  
    <dependency>  
        <groupId>org.slf4j</groupId>  
        <artifactId>slf4j-log4j12</artifactId>  
        <version>1.7.2</version>  
    </dependency>  
</dependencies>  

4 在src>main>resources下添加 log4j.properties文件,內容如下:

[plain] view plain copy
### 設置###  
log4j.rootLogger = debug,stdout,D,E,I  

### 輸出信息到控制擡 ###  
log4j.appender.stdout = org.apache.log4j.ConsoleAppender  
log4j.appender.stdout.Target = System.out  
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout  
log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n  

### 輸出DEBUG 級別以上的日誌到=E://logs/error.log ###  
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender  
log4j.appender.D.File = E://logs/log.log  
log4j.appender.D.Append = true  
log4j.appender.D.Threshold = DEBUG  
log4j.appender.D.layout = org.apache.log4j.PatternLayout  
log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n  

### 輸出ERROR 級別以上的日誌到=E://logs/error.log ###  
log4j.appender.E = org.apache.log4j.DailyRollingFileAppender  
log4j.appender.E.File =E://logs/error.log  
log4j.appender.E.Append = true  
log4j.appender.E.Threshold = ERROR  
log4j.appender.E.layout = org.apache.log4j.PatternLayout  
log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n  

### 輸出INFO 級別以上的日誌到=E://logs/error.log ###  
log4j.appender.I = org.apache.log4j.DailyRollingFileAppender  
log4j.appender.I.File =E://logs/info.log  
log4j.appender.I.Append = true  
log4j.appender.I.Threshold = INFO  
log4j.appender.I.layout = org.apache.log4j.PatternLayout  
log4j.appender.I.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n  

其中路徑部分可更改,
5 啓動程序看是否能輸出日誌,啓動時程序會彈出讓配置啓動類,設爲testDemo即可,程序正常啓動,且在相應的目錄可以看到產生了日誌文件。

三 spring+mvc web項目使用及配置方法

1 新建好一個 spring mvc web項目,過程略,可參見另一篇 去看看

2 在pom.xml中添加相應的依賴,然後點擊右下角的import changes導入相應的包,加的內容如下:

“` python
[html] view plain copy

org.slf4j
slf4j-api
1.7.2

<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-log4j12 -->  
<dependency>  
  <groupId>org.slf4j</groupId>  
  <artifactId>slf4j-log4j12</artifactId>  
  <version>1.7.2</version>  
</dependency>  

“`
3 在web.xml中加入如下內容:

python
[html] view plain copy
<context-param>
<param-name>log4jConfigLocation</param-name>
<!--<param-value>classpath:/log4j/log4j.xml</param-value>-->
<param-value>/WEB-INF/config/log4j.properties</param-value>
</context-param>
<!-- 加載log4j配置文件 -->
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>

如上內容中有一個註釋了的,原來是按這麼寫的,發現不行,改成 /WEB-INF/config/log4j.properties 這樣即可
4 在web-inf下建config文件夾,再在config下添加log4j.properties文件,內容如下:

[plain] view plain copy
### 設置###  
log4j.rootLogger = debug,stdout,D,E,I  

### 輸出信息到控制擡 ###  
log4j.appender.stdout = org.apache.log4j.ConsoleAppender  
log4j.appender.stdout.Target = System.out  
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout  
log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n  

### 輸出DEBUG 級別以上的日誌到=E://logs/error.log ###  
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender  
log4j.appender.D.File = E://logs/log.log  
log4j.appender.D.Append = true  
log4j.appender.D.Threshold = DEBUG  
log4j.appender.D.layout = org.apache.log4j.PatternLayout  
log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n  

### 輸出ERROR 級別以上的日誌到=E://logs/error.log ###  
log4j.appender.E = org.apache.log4j.DailyRollingFileAppender  
log4j.appender.E.File =E://logs/error.log  
log4j.appender.E.Append = true  
log4j.appender.E.Threshold = ERROR  
log4j.appender.E.layout = org.apache.log4j.PatternLayout  
log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n  

### 輸出INFO 級別以上的日誌到=E://logs/error.log ###  
log4j.appender.I = org.apache.log4j.DailyRollingFileAppender  
log4j.appender.I.File =E://logs/info.log  
log4j.appender.I.Append = true  
log4j.appender.I.Threshold = INFO  
log4j.appender.I.layout = org.apache.log4j.PatternLayout  
log4j.appender.I.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n  

5 至引配置完成,啓動tomcat,運行程序,發現日誌如期輸出。

上面兩個demo都能正常運行,idea版本爲IntelliJ IDEA 2017.1.4 x64。本篇只是測試日誌能否正常記錄,代碼及配置可以再優化,後續再修改。

四 SLF4J對比Log4J,logback和java.util.Logging的優勢

正如我之前說的,在你的代碼中使用SLF4J寫日誌語句的主要出發點是使得你的程序獨立於任意特定的日誌類庫,依賴於特定類可能需要不同與你已有的配置,並且導致更多維護的麻煩。但除此之外,還要一個SLF4J API的特性使得我堅持使用SLF4J而拋棄我長期間鍾愛的Lof4j的理由,是被稱爲佔位符(place holder),在代碼中表示爲“{}”的特性。佔位符是一個非常類似於在String的format()方法中的%s,因爲它會在運行時被某個提供的實際字符串所替換。這不僅降低了你代碼中字符串連接次數,而且還節省了新建的String對象。即使你可能沒需要那些對象,但這個依舊成立,取決於你的生產環境的日誌級別,例如在DEBUG或者INFO級別的字符串連接。因爲String對象是不可修改的並且它們建立在一個String池中,它們消耗堆內存( heap memory)而且大多數時間他們是不被需要的,例如當你的應用程序在生產環境以ERROR級別運行時候,一個String使用在DEBUG語句就是不被需要的。通過使用SLF4J,你可以在運行時延遲字符串的建立,這意味着只有需要的String對象才被建立。而如果你已經使用log4j,那麼你已經對於在if條件中使用debug語句這種變通方案十分熟悉了,但SLF4J的佔位符就比這個好用得多。

這是你在Log4j中使用的方案,但肯定這一點都不有趣並且降低了代碼可讀性因爲增加了不必要的繁瑣重複代碼(boiler-plate code):

[java] view plain copy
if (logger.isDebugEnabled()) {  
    logger.debug("Processing trade with id: " + id + " symbol: " + symbol);  
}  

另一方面,如果你使用SLF4J的話,你可以得到在極簡潔的格式的結果,就像以下展示的一樣:

[java] view plain copy
logger.debug("Processing trade with id: {} and symbol : {} ", id, symbol);  

在SLF4J,我們不需要字符串連接而且不會導致暫時不需要的字符串消耗。取而代之的,我們在一個以佔位符和以參數傳遞實際值的模板格式下寫日誌信息。你可能會在想萬一我有很個參數怎麼辦?嗯,那麼你可以選擇使用變量參數版本的日誌方法或者用以Object數組傳遞。這是一個相當的方便和高效方法的打日誌方法。記住,在生產最終日誌信息的字符串之前,這個方法會檢查一個特定的日誌級別是不是打開了,這不僅降低了內存消耗而且預先降低了CPU去處理字符串連接命令的時間。這裏是使用SLF4J日誌方法的代碼,來自於slf4j-log4j12-1.6.1.jar中的Log4j的適配器類Log4jLoggerAdapter。

[java] view plain copy
public void debug(String format, Object arg1, Object arg2) {  
    if (logger.isDebugEnabled()) {  
        FormattingTuple ft = MessageFormatter.format(format, arg1, arg2);  
        logger.log(FQCN, Level.DEBUG, ft.getMessage(), ft.getThrowable());  
    }  
}  

同時,我們也很值得知道打日誌是對應用程序的性能有着很大影響的,在生產環節上只進行必要的日誌記錄是我們所建議的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章