slf4j爲spring boot 的日誌功能定義了一套統一的接口,方便各類日誌框架去實現。html
SLF4J——Simple Logging Facade For Java,它是一個針對於各種Java日誌框架的統一Facade抽象。Java日誌框架衆多——經常使用的有java.util.logging, log4j, logback,commons-logging, Spring框架使用的是Jakarta Commons Logging API (JCL)。而SLF4J定義了統一的日誌抽象接口,而真正的日誌實現則是在運行時決定的——它提供了各種日誌框架的binding。java
spring boot默認使用的日誌框架是logback,它的maven jar包名稱叫程序員
spring-boot-starter-loggingspring
這裏咱們談談spring boot 整合log4j2日誌框架。apache
固然,logback,log4j和log4j2,確定都是實現了slf4j接口的日誌框架。json
這裏要注意,以前看其餘文章,有人說過spring boot 版本超過1.4,就再也不支持log4j了,須要使用log4j2框架。springboot
本文解決如下問題:
- 爲什麼使用log4j2
- springboot下log4j2日誌的使用
- 控制檯日誌顯示的級別和文件保存的日誌不一樣
- idea控制檯顏色日誌的輸出服務器
目前有關服務器日誌輸出的框架有不少,如log4j、sl4j和log4j2,爲何我選擇使用log4j2呢,看完下面兩篇性能的對比,相信你也會選擇log4j2
http://www.jianshu.com/p/483a9cf61c36
https://blog.souche.com/logback-log4j-log4j2shi-ce/?utm_source=tuicool&utm_medium=referralmybatis
大意就是從不一樣角度看,log4j2的性能提高比較大。app
須要將springboot內置的日誌剃掉,而後引入log4j2,pom以下
<!-- 支持log4j2日誌框架 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-log4j2</artifactId> </dependency>
而後須要在resource下面添加log4j2.xml配置文件,固然了若是你不添加,springboo會提示你沒有對應文件,並使用默認的配置文件,這個時候級別能夠在application.properties中配置
logging.level.root=error
控制檯打印結果
SLF4J: Class path contains multiple SLF4J bindings. SLF4J: Found binding in [jar:file:/E:/ide/maven-jar/ch/qos/logback/logback-classic/1.1.11/logback-classic-1.1.11.jar!/org/slf4j/impl/StaticLoggerBinder.class] SLF4J: Found binding in [jar:file:/E:/ide/maven-jar/org/apache/logging/log4j/log4j-slf4j-impl/2.7/log4j-slf4j-impl-2.7.jar!/org/slf4j/impl/StaticLoggerBinder.class] SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation. SLF4J: Actual binding is of type [ch.qos.logback.classic.util.ContextSelectorStaticBinder] . ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v1.5.18.RELEASE) 2019-01-11 16:56:04.582 INFO 7640 --- [ main] com.example.demo.Demo1Application : Starting Demo1Application on 16101281-6 with PID 7640 (E:\ide\workspace\demo-1\target\classes started by Administrator in E:\ide\workspace\demo-1) 2019-01-11 16:56:04.586 INFO 7640 --- [ main] com.example.demo.Demo1Application : No active profile set, falling back to default profiles: default 2019-01-11 16:56:05.038 INFO 7640 --- [ main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@1dd02175: startup date [Fri Jan 11 16:56:05 CST 2019]; root of context hierarchy 2019-01-11 16:56:06.844 INFO 7640 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration' of type [org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration$$EnhancerBySpringCGLIB$$76665e5c] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2019-01-11 16:56:07.654 INFO 7640 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 82 (http) 2019-01-11 16:56:07.697 INFO 7640 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat] 2019-01-11 16:56:07.698 INFO 7640 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.5.35
注意最上面的幾行日誌,有警告,緣由是項目中同時存在logback和log4j2的依賴包,它們都實現了slf4j接口,因此衝突了。
而logback框架是依賴於spring-boot-starter-logging這個jar包的。這個jar包,你會發現咱們pom裏面沒有主動引入它。可是有jar包依賴了它,maven就會把logging下載到依賴它的jar包中。
咱們經過下面的操做,把依賴logging的jar包,找出來,解除它對logging的依賴,同時項目又加入了log4j2的jar包。那麼在輸出日誌的時候,就不會衝突了。
這裏我分享一個eclipse的小技巧,如何查看pom.xml裏面jar包的關聯關係。
打開pom.xml文件,打開Dependency Hierarchy選項卡,將logging這個jar包,輸入filter中,就能夠看到pom裏面誰依賴了它。
咱們能夠經過eclipse提供的功能,讓eclipse幫咱們解除pom中的jar包,對logging這個包的依賴
右鍵spring-boot-strater-logging包,選擇項
這時候,咱們會發現pom.xml發生了變化:
<!-- 支持JDBC --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-logging</artifactId> </exclusion> </exclusions> </dependency>
關聯logback輸出日誌的jar包,都添加了
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
標籤來取消依賴。
重啓項目,發現警告沒有消失!
. ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v1.5.18.RELEASE) 2019-01-11 18:17:16.314 INFO 5272 --- [ main] c.e.d.Demo1Application : Starting Demo1Application on 16101281-6 with PID 5272 (E:\ide\workspace\demo-1\target\classes started by Administrator in E:\ide\workspace\demo-1) 2019-01-11 18:17:16.322 INFO 5272 --- [ main] c.e.d.Demo1Application : No active profile set, falling back to default profiles: default 2019-01-11 18:17:16.676 INFO 5272 --- [ main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@3eb25e1a: startup date [Fri Jan 11 18:17:16 CST 2019]; root of context hierarchy 2019-01-11 18:17:18.258 INFO 5272 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration' of type [org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration$$EnhancerBySpringCGLIB$$6c96c533] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2019-01-11 18:17:18.954 INFO 5272 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 82 (http)
主要結構,和咱們用到的大體以下
咱們來看一篇複雜的log4j2配置:
<?xml version="1.0" encoding="UTF-8"?> <!-- 日誌級別 trace: 是追蹤,就是程序推動如下,你就能夠寫個trace輸出,因此trace應該會特別多,不過不要緊,咱們能夠設置最低日誌級別不讓他輸出。 debug: 調試麼,我通常就只用這個做爲最低級別,trace壓根不用。是在沒辦法就用eclipse或者idea的debug功能就行了麼。 info: 輸出一下你感興趣的或者重要的信息,這個用的最多了。 warn: 有些信息不是錯誤信息,可是也要給程序員的一些提示,相似於eclipse中代碼的驗證不是有error 和warn(不算錯誤可是也請注意,好比如下depressed的方法)。 error: 錯誤信息。用的也比較多。 fatal: 級別比較高了。重大錯誤,這種級別你能夠直接中止程序了,是不該該出現的錯誤麼!不用那麼緊張,其實就是一個程度的問題。 --> <Configuration status="OFF"> <!-- 定義日誌存放目錄 --> <properties> <property name="logPath">logs</property> <!-- 輸出日誌的格式 --> <!-- %d{yyyy-MM-dd HH:mm:ss, SSS} : 日誌生產時間 %p : 日誌輸出格式 %c : logger的名稱 %m : 日誌內容,即 logger.info("message") %n : 換行符 %C : Java類名 %L : 日誌輸出所在行數 %M : 日誌輸出所在方法名 hostName : 本地機器名 hostAddress : 本地ip地址 --> <property name="PATTERN">%d{yyyy-MM-dd HH:mm:ss.SSS} [%t-%L] %-5level %logger{36} %L %M - %msg%xEx%n</property> </properties> <!--先定義全部的appender(輸出器) --> <Appenders> <!--輸出到控制檯 --> <Console name="ConsoleLog" target="SYSTEM_OUT"> <!--只輸出level及以上級別的信息(onMatch),其餘的直接拒絕(onMismatch) --> <ThresholdFilter level="trace" onMatch="ACCEPT" onMismatch="DENY" /> <!--輸出日誌的格式,引用自定義模板 PATTERN --> <PatternLayout pattern="${PATTERN}" /> </Console> <!--輸出到文件 --> <!--文件會打印出全部信息,這個log每次運行程序會自動清空,由append屬性決定,這個也挺有用的,適合臨時測試用 --> <!--append爲TRUE表示消息增長到指定文件中,false表示消息覆蓋指定的文件內容,默認值是true --> <File name="TestLog" fileName="${logPath}/test.log" append="false"> <PatternLayout pattern="${PATTERN}" /> </File> <!-- 把error等級記錄到文件 通常不用 --> <File name="FileLog" fileName="${logPath}/error.log"> <ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY" /> <PatternLayout pattern="${PATTERN}" /> </File> <!--輸出到循環日誌,每次大小超過size,則這size大小的日誌會自動存入按年份-月份創建的文件夾下面並進行壓縮,做爲存檔 --> <RollingFile name="RollingFileLog" fileName="${logPath}/app.log" filePattern="${logPath}/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz"> <ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY" /> <PatternLayout pattern="${PATTERN}" /> <SizeBasedTriggeringPolicy size="10MB" /> </RollingFile> </Appenders> <!--而後定義logger,只有定義了logger並引入的appender,appender纔會生效 --> <!--而後定義logger,只有定義了logger並引入的appender,appender纔會生效 --> <Loggers> <!--創建一個默認的Root的logger,記錄大於level高於warn的信息,若是這裏的level高於Appenders中的,則Appenders中也是以此等級爲起點,好比,這裏level="fatal",則Appenders中只出現fatal信息 --> <!-- 生產環境level>=warn --> <Root level="debug"> <!-- 輸出器,可選上面定義的任何項組合,或全選,作到可隨意定製 --> <appender-ref ref="ConsoleLog" /> <appender-ref ref="TestLog" /> <appender-ref ref="FileLog" /> <appender-ref ref="RollingFileLog" /> </Root> <!-- 第三方日誌系統 --> <!--過濾掉spring和mybatis的一些無用的DEBUG信息,也能夠在spring boot 的logging.level.org.springframework=FATAL設置--> <!-- <logger name="org.springframework" level="INFO"></logger> --> <!-- <logger name="org.mybatis" level="INFO"></logger> --> <!-- <logger name="org.apache.http" level="warn" /> --> </Loggers> </Configuration>
該配置文件的,參數配置方式,與logback-spring.xml的配置文件,幾乎一致。
log4j 2.x版本再也不支持像1.x中的.properties後綴的文件配置方式,2.x版本配置文件後綴名只能爲".xml",".json"或者".jsn".
系統選擇配置文件的優先級(從先到後)以下:
(1).classpath下的名爲log4j2-test.json 或者log4j2-test.jsn的文件.
(2).classpath下的名爲log4j2-test.xml的文件.
(3).classpath下名爲log4j2.json 或者log4j2.jsn的文件.
(4).classpath下名爲log4j2.xml的文件.
咱們通常默認使用log4j2.xml進行命名。若是本地要測試,能夠把log4j2-test.xml放到classpath,而正式環境使用log4j2.xml,則在打包部署的時候不要打包log4j2-test.xml便可。
<?xml version="1.0" encoding="UTF-8"?> <Configuration status="WARN"> <Appenders> <Console name="Console" target="SYSTEM_OUT"> <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/> </Console> </Appenders> <Loggers> <Root level="error"> <AppenderRef ref="Console"/> </Root> </Loggers> </Configuration>
(1).根節點Configuration有兩個屬性:status和monitorinterval,有兩個子節點:Appenders和Loggers(代表能夠定義多個Appender和Logger).
status用來指定log4j自己的打印日誌的級別.
monitorinterval用於指定log4j自動從新配置的監測間隔時間,單位是s,最小是5s.
(2).Appenders節點,常見的有三種子節點:Console、RollingFile、File.
Console節點用來定義輸出到控制檯的Appender.
name:指定Appender的名字.
target:SYSTEM_OUT 或 SYSTEM_ERR,通常只設置默認:SYSTEM_OUT.
PatternLayout:輸出格式,不設置默認爲:%m%n.
File節點用來定義輸出到指定位置的文件的Appender.
name:指定Appender的名字.
fileName:指定輸出日誌的目的文件帶全路徑的文件名.
PatternLayout:輸出格式,不設置默認爲:%m%n.
RollingFile節點用來定義超過指定大小自動刪除舊的建立新的的Appender.
name:指定Appender的名字.
fileName:指定輸出日誌的目的文件帶全路徑的文件名.
PatternLayout:輸出格式,不設置默認爲:%m%n.
filePattern:指定新建日誌文件的名稱格式.
Policies:指定滾動日誌的策略,就是何時進行新建日誌文件輸出日誌.
TimeBasedTriggeringPolicy:Policies子節點,基於時間的滾動策略,interval屬性用來指定多久滾動一次,默認是1 hour。modulate=true用來調整時間:好比如今是早上3am,interval是4,那麼第一次滾動是在4am,接着是8am,12am...而不是7am.
SizeBasedTriggeringPolicy:Policies子節點,基於指定文件大小的滾動策略,size屬性用來定義每一個日誌文件的大小.
DefaultRolloverStrategy:用來指定同一個文件夾下最多有幾個日誌文件時開始刪除最舊的,建立新的(經過max屬性)。
(3).Loggers節點,常見的有兩種:Root和Logger.
Root節點用來指定項目的根日誌,若是沒有單獨指定Logger,那麼就會默認使用該Root日誌輸出
level:日誌輸出級別,共有8個級別,按照從低到高爲:All < Trace < Debug < Info < Warn < Error < Fatal < OFF.
AppenderRef:Root的子節點,用來指定該日誌輸出到哪一個Appender.
Logger節點用來單獨指定日誌的形式,好比要爲指定包下的class指定不一樣的日誌級別等。
level:日誌輸出級別,共有8個級別,按照從低到高爲:All < Trace < Debug < Info < Warn < Error < Fatal < OFF.
name:用來指定該Logger所適用的類或者類所在的包全路徑,繼承自Root節點.
AppenderRef:Logger的子節點,用來指定該日誌輸出到哪一個Appender,若是沒有指定,就會默認繼承自Root.若是指定了,那麼會在指定的這個Appender和Root的Appender中都會輸出,此時咱們能夠設置Logger的additivity="false"只在自定義的Appender中進行輸出。
共有8個級別,按照從低到高爲:All < Trace < Debug < Info < Warn < Error < Fatal < OFF.
All:最低等級的,用於打開全部日誌記錄.
Trace:是追蹤,就是程序推動如下,你就能夠寫個trace輸出,因此trace應該會特別多,不過不要緊,咱們能夠設置最低日誌級別不讓他輸出.
Debug:指出細粒度信息事件對調試應用程序是很是有幫助的.
Info:消息在粗粒度級別上突出強調應用程序的運行過程.
Warn:輸出警告及warn如下級別的日誌.
Error:輸出錯誤信息日誌.
Fatal:輸出每一個嚴重的錯誤事件將會致使應用程序的退出的日誌.
OFF:最高等級的,用於關閉全部日誌記錄.
程序會打印高於或等於所設置級別的日誌,設置的日誌等級越高,打印出來的日誌就越少。
劃重點:application.properties中配置日誌
#要掃描的包記錄日誌信息 logging.config=classpath:log4j2.xml # 定義記錄某個包內日誌的級別,高於等於則記錄,能夠多個 logging.level.org.springframework=FATAL
在須要的地方使用
mport org.slf4j.Logger; import org.slf4j.LoggerFactory; ... private static Logger logger = LoggerFactory.getLogger(xx.class); ... logger.info("------xxxx-------");
日誌的配置,主要體現爲
設置日誌文件的路勁和名稱,
設置日誌文件的輸出格式,
設置日誌文件,在console中,和file中的,輸出的日誌等級,和掃描的不一樣的包/類。
設置日誌文件的切片維度和保存策略,好比指定日誌文件的大小,按天保存,最大保存多少天,最大保存多少MB。
設置是否輸出第三方框架的日誌,和日誌等級。
指定須要輸出日誌的包/類,和他們的輸出等級。