1.概念java
JUL、JCL、Jboss-logging、logback、log4j、log4j二、slf4j....等等不少,通常咱們使用SLF4j做爲日誌的抽象層,Logback或者Log4j2做爲實現類,log4j自身因爲效率問題被淘汰,Logback與log4j與SLF4j是同一我的寫的,springboot默認使用SLF4j+Logbackmysql
2.SLF4jspring
官網 https://www.slf4j.org/sql
依賴數據庫
<dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.25</version> </dependency>
基本使用apache
@Test public void testLog4J(){ Logger logger=LoggerFactory.getLogger(MvcDemoApplicationTests.class); logger.warn("警告");//保存日誌級別warn,還有info,error,fatal,debug,與level級別一致 }
3. SLF4j統一日誌的原理api
即便是別的框架也統一使用slf4j進行輸出安全
原理:先要排除別的日誌的依賴,而後使用相應的SLF4j的jar替換掉原來的jar,而後倒入相應的實現或者適配包以及實現,原理圖以下springboot
相應的SLF4j的jar有下圖可知是採用偷樑換柱的方式修改了相應的日誌類bash
排除日誌包的依賴
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <exclusions> <exclusion> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> </exclusion> </exclusions> </dependency>
4. spring與springboot的日誌記錄
SpringBoot能自動適配全部的日誌(緣由是假如了相應的適配包),底層使用slf4j+logback的方式記錄日誌,引入其餘框架的時候,只須要把這個框架依賴的日誌框架排除掉便可;
logback-spring.xml:添加-spring後,日誌框架就不直接加載日誌的配置項,而是由SpringBoot解析加載,可使用SpringBoot的高級Profile功能,假如沒有-spring,那麼由logback會直接加載
spring使用自動適配全部的日誌時須要的依賴
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring‐boot‐starter‐logging</artifactId> </dependency>
添加上述依賴後的依賴關係圖
springboot的Logback文件的配置(spring-boot-1.5.17.RELEASE.jar下)
假如須要對日誌配置文件進行修改見Logback
5. Logback
Logback與Log4J對比
相對Logback 執行更快,更充分的測試,原生實現了 SLF4J API(有上述可知Log4J 還須要有一箇中間轉換層),內容更豐富的文檔,支持 XML 或者 Groovy 方式配置,配置文件自動熱加載,從 IO 錯誤中優雅恢復,自動刪除日誌歸檔,自動壓縮日誌成爲歸檔文件,支持 Prudent 模式,使多個 JVM 進程能記錄同一個日誌文件,支持配置文件中加入條件判斷來適應不一樣的環境,更強大的過濾器,支持 SiftingAppender(可篩選 Appender),異常棧信息帶有包信息。
Logback的日誌級別
TRACE < DEBUG < INFO < WARN < ERROR
Logback配置說明
<?xml version="1.0" encoding="UTF-8"?>
<!-- scan:當該屬性設置爲true時,配置文件若是發生改變,將會被從新加載,默認值爲true。 scanPeriod:設置監測配置文件是否修改的時間間隔,若是沒有給出時間單位,默認單位是毫秒,默認的時間間隔爲1分鐘,當scan爲true時,此屬性生效 debug:當此屬性設置爲true時,將打印出logback內部日誌信息,實時查看logback運行狀態。默認值爲false。 -->
<configuration scan="true" scanPeriod="60 seconds" debug="false"> <!-- 定義日誌的根目錄 --> <property name="LOG_HOME" value="/app/log" /> <!-- 定義日誌文件名稱 --> <property name="appName" value="SkyTest"></property>
<!-- ch.qos.logback.core.ConsoleAppender 表示控制檯輸出, ch.qos.logback.core.FileAppender 輸出到文件 ch.qos.logback.core.rolling.RollingFileAppender回滾 -->
<!----------------------------------------------------------------------------------> <appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
<!--編碼--> <Encoding>UTF-8</Encoding> <!-- 日誌輸出格式:%d表示日期時間,%thread表示線程名,%-5level:級別從左顯示5個字符寬度 %logger{50} 表示logger名字最長50個字符,不然按照句點分割。 %msg:日誌消息,%n是換行符 --> <layout class="ch.qos.logback.classic.PatternLayout"> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern> </layout> </appender> <!----------------------------------------------------------------------------------> <!-- 滾動記錄文件,先將日誌記錄到指定文件,當符合某個條件時,將日誌記錄到其餘文件 --> <appender name="appLogAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 過濾器,只記錄WARN級別的日誌 ,不經常使用-->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<Encoding>UTF-8</Encoding>
<!-- 指定日誌文件的名稱,<property> 有兩個屬性,name和value;其中name的值是變量的名稱,value的值時變量定義的值。經過<property>定義的值會被插入到logger上下文中。 定義變量後,可使「${}」來使用變量。 --> <file>${LOG_HOME}/${appName}.log</file>
<!-- rollingPolicy回滾策略: TimeBasedRollingPolicy: 最經常使用的滾動策略,它根據時間來制定滾動策略,既負責滾動也負責出發滾動。 --> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 滾動時產生的文件的存放位置及文件名稱 %d{yyyy-MM-dd}:按天進行日誌滾動 %i:當文件大小超過maxFileSize時,按照i進行文件滾動 --> <fileNamePattern>${LOG_HOME}/${appName}-%d{yyyy-MM-dd}-%i.log</fileNamePattern> <!-- 可選節點,控制保留的歸檔文件的最大數量,超出數量就刪除舊文件。假設設置天天滾動, 且maxHistory是365,則只保存最近365天的文件,刪除以前的舊文件。注意,刪除舊文件是, 那些爲了歸檔而建立的目錄也會被刪除。 --> <MaxHistory>365</MaxHistory>
<!-- 當日志文件超過maxFileSize指定的大小時,根據上面提到的%i進行日誌文件滾動,注意此處配置SizeBasedTriggeringPolicy是沒法實現按文件大小進行滾動的,
必須配置timeBasedFileNamingAndTriggeringPolicy --> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <maxFileSize>100MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> </rollingPolicy>
<!-- 日誌輸出格式:%d表示日期時間,%thread表示線程名,%-5level:級別從左顯示5個字符寬度 %logger{50} 表示logger名字最長50個字符,不然按照句點分割。 %msg:日誌消息,%n是換行符 --> <layout class="ch.qos.logback.classic.PatternLayout"> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [ %thread ] - [ %-5level ] [ %logger{50} : %line ] - %msg%n</pattern> </layout>
</appender>
<!----------------------------------------------------------------------------------> <!-- logger主要用於存放日誌對象,也能夠定義日誌類型、級別 name:表示匹配的logger類型前綴,也就是包的前半部分 level:要記錄的日誌級別,包括 TRACE < DEBUG < INFO < WARN < ERROR additivity:是否向上級loger傳遞打印信息。默認是true。<loger>能夠包含零個或多個<appender-ref>元素,標識這個appender將會添加到這個logger。 --> <!-- hibernate logger --> <logger name="org.hibernate" level="error" />
<!-- Spring framework logger --> <logger name="org.springframework" level="error" additivity="false"></logger> <logger name="com.creditease" level="info" additivity="true"> <appender-ref ref="appLogAppender" /> </logger> <!-- root與logger是父子關係,沒有特別定義則默認爲root,任何一個類只會和一個logger對應,有匹配的logger則爲logger,沒有則爲默認的root --> <root level="info"> <appender-ref ref="stdout" /><!--stdouty與appender的name保持一致--> <appender-ref ref="appLogAppender" /> </root> <!-- show parameters for hibernate sql 專爲 Hibernate 定製 --> <logger name="org.hibernate.type.descriptor.sql.BasicBinder" level="TRACE" /> <logger name="org.hibernate.type.descriptor.sql.BasicExtractor" level="DEBUG" /> <logger name="org.hibernate.SQL" level="DEBUG" /> <logger name="org.hibernate.engine.QueryParameters" level="DEBUG" /> <logger name="org.hibernate.engine.query.HQLQueryPlan" level="DEBUG" /> <!--日誌異步到數據庫 --> <appender name="DB" class="ch.qos.logback.classic.db.DBAppender"> <!--日誌異步到數據庫 --> <connectionSource class="ch.qos.logback.core.db.DriverManagerConnectionSource"> <!--鏈接池 --> <dataSource class="com.mchange.v2.c3p0.ComboPooledDataSource"> <driverClass>com.mysql.jdbc.Driver</driverClass> <url>jdbc:mysql://127.0.0.1:3306/databaseName</url> <user>root</user> <password>root</password> </dataSource> </connectionSource> </appender> </configuration>
<!-- <encoder>:對日誌進行格式化。//都有 <target>:字符串 System.out 或者 System.err ,默認 System.out //控制檯 <file>:被寫入的文件名,能夠是相對目錄,也能夠是絕對目錄,若是上級目錄不存在會自動建立,沒有默認值。 //文件,回滾日誌 <append>:若是是 true,日誌被追加到文件結尾,若是是 false,清空現存文件,默認是true。//文件,回滾日誌 <prudent>:若是是 true,日誌會被安全的寫入文件,即便其餘的FileAppender也在向此文件作寫入操做,效率低,默認是 false。//文件,回滾日誌 <rollingPolicy>:當發生滾動時,決定 RollingFileAppender 的行爲,涉及文件移動和重命名。 //回滾日誌 <triggeringPolicy >: 告知 RollingFileAppender 合適激活滾動 //回滾日誌 -->
logback-spring.xml:添加-spring後,日誌框架就不直接加載日誌的配置項,而是由SpringBoot解析加載,可使用SpringBoot的高級Profile功能,假如沒有-spring,那麼由logback會直接加載
6.log4j的配置(LOG4J.xml放在類路徑下會自動加載)
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> <log4j:configuration> <!--STDOUT表示輸出 org.apache.log4j.ConsoleAppender 表示輸出的類,這裏表示輸出到控制檯--> <appender name="STDOUT" class="org.apache.log4j.ConsoleAppender"> <!--表達式輸出的字符集--> <param name="Encoding" value="UTF-8"/> <!--org.apache.log4j.PatternLayout 對象和與之相關的格式化的日誌記錄信息轉換模式,這裏表示表達式--> <layout class="org.apache.log4j.PatternLayout"> <!--ConversionPattern格式 --> <param name="ConversionPattern" value="%-5p %d{yyyy/MM/dd HH:mm:ss,SSS} %m %c (%F:%L) \n"/> </layout> </appender> <!--org.apache.log4j.ConsoleAppender(控制檯)--> <!--org.apache.log4j.FileAppender(文件)--> <!--org.apache.log4j.DailyRollingFileAppender(天天產生一個日誌文件)--> <!--org.apache.log4j.RollingFileAppender(文件大小到達指定尺寸的時候產生一個新的文件)--> <!--org.apache.log4j.WriterAppender(將日誌信息以流格式發送到任意指定的地方)--> <appender name="file" class="org.apache.log4j.FileAppender"> <!--表達式輸出的字符集--> <param name="Encoding" value="UTF-8"/> <!--Threshold=debug:指定日誌消息的輸出最低層次。--> <param name="Threshold" value="debug"/> <!--append:默認值是true,即將消息增長到指定文件中,false指將消息覆蓋指定的文件內容--> <param name="append" value="true"/> <!--File指定消息輸出到mylog.txt文件。--> <param name="File" value="D:/logs/log4j.log"/> <!--ImmediateFlush:默認值是true,意謂着全部的消息都會被當即輸出。--> <param name="ImmediateFlush" value="true"/> <!--org.apache.log4j.PatternLayout 對象和與之相關的格式化的日誌記錄信息轉換模式,這裏表示表達式--> <layout class="org.apache.log4j.PatternLayout"> <!--ConversionPattern格式 %c: 輸出日誌信息所屬的類目,一般就是所在類的全名 %d: 輸出日誌時間點的日期或時間,默認格式爲ISO8601,也能夠在其後指定格式,好比:%d{yyyy/MM/dd HH:mm:ss,SSS}, 輸出相似:2018/10/06 14:16:41,429 %p: 輸出日誌信息優先級,即DEBUG,INFO,WARN,ERROR,FATAL, %F: 輸出日誌消息產生時所在的文件名稱 %L: 輸出代碼中的行號 "-"號指定左對齊。 %m: 輸出代碼中指定的消息,產生的日誌具體信息 \n 換行 %r: 輸出自應用啓動到輸出該log信息耗費的毫秒數 --> <param name="ConversionPattern" value="%-5p %d{yyyy/MM/dd HH:mm:ss,SSS} %m %c (%F:%L) \n"/> </layout> </appender> <!-- <appender name="rolling" class="org.apache.log4j.FileAppender"> 其餘參數 在name="file"的基礎上增長了以下兩個參數 MaxFileSize=200KB: 後綴能夠是KB, MB 或者是 GB. 在日誌文件到達該大小時,將會自動滾動,即將原來的內容移到mylog.log.1文件。 MaxBackupIndex=5:指定能夠產生的滾動文件的最大數。 </appender>--> <!-- properties與xml的配置相似,只是在properties中用的是點,而在xml中是節點 # 應用於socket log4j.appender.socket=org.apache.log4j.RollingFileAppender log4j.appender.socket.RemoteHost=localhost log4j.appender.socket.Port=5001 log4j.appender.socket.LocationInfo=true # Set up for Log Factor 5 log4j.appender.socket.layout=org.apache.log4j.PatternLayout log4j.appender.socket.layout.ConversionPattern=[%-5p] %d(%r) –> [%t] %l: %m %x %n # Log Factor 5 Appender log4j.appender.LF5_APPENDER=org.apache.log4j.lf5.LF5Appender log4j.appender.LF5_APPENDER.MaxNumberOfRecords=2000 # 發送日誌到指定郵件 log4j.appender.mail=org.apache.log4j.net.SMTPAppender log4j.appender.mail.Threshold=FATAL log4j.appender.mail.BufferSize=10 log4j.appender.mail.From = xxx@mail.com log4j.appender.mail.SMTPHost=mail.com log4j.appender.mail.Subject=Log4J Message log4j.appender.mail.To= xxx@mail.com log4j.appender.mail.layout=org.apache.log4j.PatternLayout log4j.appender.mail.layout.ConversionPattern=[%-5p] %d(%r) –> [%t] %l: %m %x %n # 應用於數據庫 log4j.appender.database=org.apache.log4j.jdbc.JDBCAppender log4j.appender.database.URL=jdbc:mysql://localhost:3306/test log4j.appender.database.driver=com.mysql.jdbc.Driver log4j.appender.database.user=root log4j.appender.database.password= log4j.appender.database.sql=INSERT INTO LOG4J (Message) VALUES('=[%-5p] %d(%r) –> [%t] %l: %m %x %n') log4j.appender.database.layout=org.apache.log4j.PatternLayout log4j.appender.database.layout.ConversionPattern=[%-5p] %d(%r) –> [%t] %l: %m %x %n --> <!--指定包名下的輸出級別--> <logger name="cn.mybaties.dao"> <level value="debug"/> </logger> <!--STDOUT的全部的輸出級別 fatal(致命錯誤) > error (錯誤) > warn (警告) > info(普通訊 息) > debug(調試信息) 以下爲相應的name添加級別--> <root> <level value="warn"/> <appender-ref ref="STDOUT"/> <appender-ref ref="file"/> </root> </log4j:configuration>