當咱們的系統變的更加複雜的時候,咱們的日誌就容易發生混亂。隨着系統開發的進行,可能會更新不一樣的日誌框架,形成當前系統中存在不一樣的日誌依賴,讓咱們難以統一的管理和控制。就算咱們強制要求全部的模塊使用相同的日誌框架,系統中也難以免使用其餘相似spring,mybatis等其餘的第三方框架,它們依賴於咱們規定不一樣的日誌框架,並且他們自身的日誌系統就有着不一致性,依然會出來日誌體系的混亂。html
因此咱們須要借鑑JDBC的思想,爲日誌系統也提供一套門面,那麼咱們就能夠面向這些接口規範來開發,避免了直接依賴具體的日誌框架。這樣咱們的系統在日誌中,就存在了日誌的門面和日誌的實現。java
常見的日誌門面:
JCL、slf4j
常見的日誌實現:
JUL、log4j、logback、log4j2web
日誌門面和日誌實現的關係:
spring
日誌框架出現的歷史順序:
log4j -->JUL-->JCL--> slf4j --> logback --> log4j2數據庫
簡單日誌門面(Simple Logging Facade For Java) SLF4J主要是爲了給Java日誌訪問提供一套標準、規範的API框架,其主要意義在於提供接口,具體的實現能夠交由其餘日誌框架,例如log4j和logback等。固然slf4j本身也提供了功能較爲簡單的實現,可是通常不多用到。對於通常的Java項目而言,日誌框架會選擇slf4j-api做爲門面,配上具體的實現框架(log4j、logback等),中間使用橋接器完成橋接。apache
官方網站: https://www.slf4j.org/api
SLF4J是目前市面上最流行的日誌門面。如今的項目中,基本上都是使用SLF4J做爲咱們的日誌系統。
SLF4J日誌門面主要提供兩大功能:數組
添加依賴tomcat
<!--slf4j core 使用slf4j必須添加--> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.27</version> </dependency> <!--slf4j 自帶的簡單日誌實現 --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-simple</artifactId> <version>1.7.27</version> </dependency>
編寫代碼springboot
public class Slf4jTest { // 聲明日誌對象 public final static Logger LOGGER = LoggerFactory.getLogger(Slf4jTest.class); @Test public void testQuick() throws Exception { //打印日誌信息 LOGGER.error("error"); LOGGER.warn("warn"); LOGGER.info("info"); LOGGER.debug("debug"); LOGGER.trace("trace"); // 使用佔位符輸出日誌信息 String name = "jack"; Integer age = 18; LOGGER.info("用戶:{},{}", name, age); // 將系統異常信息寫入日誌 try { int i = 1 / 0; } catch (Exception e) { // e.printStackTrace(); LOGGER.info("出現異常:", e); } } }
爲何要使用SLF4J做爲日誌門面?
如前所述,SLF4J支持各類日誌框架。SLF4J發行版附帶了幾個稱爲「SLF4J綁定」的jar文件,每一個綁定對應一個受支持的框架。
使用slf4j的日誌綁定流程:
經過maven引入常見的日誌實現框架:
<!--slf4j core 使用slf4j必須添加--> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.27</version> </dependency> <!-- log4j--> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.27</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> <!-- jul --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-jdk14</artifactId> <version>1.7.27</version> </dependency> <!--jcl --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-jcl</artifactId> <version>1.7.27</version> </dependency> <!-- nop --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-nop</artifactId> <version>1.7.27</version> </dependency>
要切換日誌框架,只需替換類路徑上的slf4j綁定。例如,要從java.util.logging切換到log4j,只需將slf4j-jdk14-1.7.27.jar替換爲slf4j-log4j12-1.7.27.jar便可。
SLF4J不依賴於任何特殊的類裝載。實際上,每一個SLF4J綁定在編譯時都是硬連線的, 以使用一個且只有一個特定的日誌記錄框架。例如,slf4j-log4j12-1.7.27.jar綁定在編譯時綁定以使用log4j。在您的代碼中,除了slf4j-api-1.7.27.jar以外,您只需將您選擇的一個且只有一個綁定放到相應的類路徑位置。不要在類路徑上放置多個綁定。如下是通常概念的圖解說明。
一般,您依賴的某些組件依賴於SLF4J之外的日誌記錄API。您也能夠假設這些組件在不久的未來不會切換到SLF4J。爲了解決這種狀況,SLF4J附帶了幾個橋接模塊,這些模塊將對log4j,JCL和java.util.logging API的調用重定向,就好像它們是對SLF4J API同樣。
橋接解決的是項目中日誌的遺留問題,當系統中存在以前的日誌API,能夠經過橋接轉換到slf4j的實現
遷移的方式:
若是咱們要使用SLF4J的橋接器,替換原有的日誌框架,那麼咱們須要作的第一件事情,就是刪除掉原有項目中的日誌框架的依賴。而後替換成SLF4J提供的橋接器。
<!-- log4j--> <dependency> <groupId>org.slf4j</groupId> <artifactId>log4j-over-slf4j</artifactId> <version>1.7.27</version> </dependency> <!-- jul --> <dependency> <groupId>org.slf4j</groupId> <artifactId>jul-to-slf4j</artifactId> <version>1.7.27</version> </dependency> <!--jcl --> <dependency> <groupId>org.slf4j</groupId> <artifactId>jcl-over-slf4j</artifactId> <version>1.7.27</version> </dependency>
注意問題:
Logback是由log4j創始人設計的另外一個開源日誌組件,性能比log4j要好。
官方網站:https://logback.qos.ch/index.html
Logback主要分爲三個模塊:
後續的日誌代碼都是經過SLF4J日誌門面搭建日誌系統,因此在代碼是沒有區別,主要是經過修改配置文件和pom.xml依賴
添加依賴
<dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.25</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.2.3</version> </dependency>
java代碼
//定義日誌對象 public final static Logger LOGGER = LoggerFactory.getLogger(LogBackTest.class); @Test public void testSlf4j(){ //打印日誌信息 LOGGER.error("error"); LOGGER.warn("warn"); LOGGER.info("info"); LOGGER.debug("debug"); LOGGER.trace("trace"); }
logback會依次讀取如下類型配置文件:
基本配置信息
<?xml version="1.0" encoding="UTF-8"?> <configuration> <!-- 日誌輸出格式: %-5level %d{yyyy-MM-dd HH:mm:ss.SSS}日期 %c類的完整名稱 %M爲method %L爲行號 %thread線程名稱 %m或者%msg爲信息 %n換行 --> <!--格式化輸出:%d表示日期,%thread表示線程名,%-5level:級別從左顯示5個字符寬度,%msg:日誌消息,%n是換行符--> <property name="pattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS} %c [%thread] %-5level %msg%n"/> <!-- Appender: 設置日誌信息的去向,經常使用的有如下幾個 ch.qos.logback.core.ConsoleAppender (控制檯) ch.qos.logback.core.rolling.RollingFileAppender (文件大小到達指定尺寸的時候產生一個新文件) ch.qos.logback.core.FileAppender (文件) --> <appender name="console" class="ch.qos.logback.core.ConsoleAppender"> <!--輸出流對象 默認 System.out 改成 System.err--> <target>System.err</target> <!--日誌格式配置--> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <pattern>${pattern}</pattern> </encoder> </appender> <!-- 用來設置某一個包或者具體的某一個類的日誌打印級別、以及指定<appender>。 <loger>僅有一個name屬性,一個可選的level和一個可選的addtivity屬性 name: 用來指定受此logger約束的某一個包或者具體的某一個類。 level: 用來設置打印級別,大小寫無關:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF, 若是未設置此屬性,那麼當前logger將會繼承上級的級別。 additivity: 是否向上級loger傳遞打印信息。默認是true。 <logger>能夠包含零個或多個<appender-ref>元素,標識這個appender將會添加到這個logger --> <!-- 也是<logger>元素,可是它是根logger。默認debug level:用來設置打印級別,大小寫無關:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF, <root>能夠包含零個或多個<appender-ref>元素,標識這個appender將會添加到這個logger。 --> <root level="ALL"> <appender-ref ref="console"/> </root> </configuration>
FileAppender配置
<?xml version="1.0" encoding="UTF-8"?> <configuration> <!-- 自定義屬性 能夠經過${name}進行引用--> <property name="pattern" value="[%-5level] %d{yyyy-MM-dd HH:mm:ss} %c %M %L [%thread] %m %n"/> <!-- 日誌輸出格式: %d{pattern}日期 %m或者%msg爲信息 %M爲method %L爲行號 %c類的完整名稱 %thread線程名稱 %n換行 %-5level --> <!-- 日誌文件存放目錄 --> <property name="log_dir" value="d:/logs"></property> <!--控制檯輸出appender對象--> <appender name="console" class="ch.qos.logback.core.ConsoleAppender"> <!--輸出流對象 默認 System.out 改成 System.err--> <target>System.err</target> <!--日誌格式配置--> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <pattern>${pattern}</pattern> </encoder> </appender> <!--日誌文件輸出appender對象--> <appender name="file" class="ch.qos.logback.core.FileAppender"> <!--日誌格式配置--> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <pattern>${pattern}</pattern> </encoder> <!--日誌輸出路徑--> <file>${log_dir}/logback.log</file> </appender> <!-- 生成html格式appender對象 --> <appender name="htmlFile" class="ch.qos.logback.core.FileAppender"> <!--日誌格式配置--> <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder"> <layout class="ch.qos.logback.classic.html.HTMLLayout"> <pattern>%level%d{yyyy-MM-dd HH:mm:ss}%c%M%L%thread%m</pattern> </layout> </encoder> <!--日誌輸出路徑--> <file>${log_dir}/logback.html</file> </appender> <!--RootLogger對象--> <root level="all"> <appender-ref ref="console"/> <appender-ref ref="file"/> <appender-ref ref="htmlFile"/> </root> </configuration>
RollingFileAppender配置
<?xml version="1.0" encoding="UTF-8"?> <configuration> <!-- 自定義屬性 能夠經過${name}進行引用--> <property name="pattern" value="[%-5level] %d{yyyy-MM-dd HH:mm:ss} %c %M %L [%thread] %m %n"/> <!-- 日誌輸出格式: %d{pattern}日期 %m或者%msg爲信息 %M爲method %L爲行號 %c類的完整名稱 %thread線程名稱 %n換行 %-5level --> <!-- 日誌文件存放目錄 --> <property name="log_dir" value="d:/logs"></property> <!--控制檯輸出appender對象--> <appender name="console" class="ch.qos.logback.core.ConsoleAppender"> <!--輸出流對象 默認 System.out 改成 System.err--> <target>System.err</target> <!--日誌格式配置--> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <pattern>${pattern}</pattern> </encoder> </appender> <!-- 日誌文件拆分和歸檔的appender對象--> <appender name="rollFile" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!--日誌格式配置--> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <pattern>${pattern}</pattern> </encoder> <!--日誌輸出路徑--> <file>${log_dir}/roll_logback.log</file> <!--指定日誌文件拆分和壓縮規則--> <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> <!--經過指定壓縮文件名稱,來肯定分割文件方式--> <fileNamePattern>${log_dir}/rolling.%d{yyyy-MMdd}.log%i.gz</fileNamePattern> <!--文件拆分大小--> <maxFileSize>1MB</maxFileSize> </rollingPolicy> </appender> <!--RootLogger對象--> <root level="all"> <appender-ref ref="console"/> <appender-ref ref="rollFile"/> </root> </configuration>
Filter和異步日誌配置
<?xml version="1.0" encoding="UTF-8"?> <configuration> <!-- 自定義屬性 能夠經過${name}進行引用--> <property name="pattern" value="[%-5level] %d{yyyy-MM-dd HH:mm:ss} %c %M %L [%thread] %m %n"/> <!-- 日誌輸出格式: %d{pattern}日期 %m或者%msg爲信息 %M爲method %L爲行號 %c類的完整名稱 %thread線程名稱 %n換行 %-5level --> <!-- 日誌文件存放目錄 --> <property name="log_dir" value="d:/logs/"></property> <!--控制檯輸出appender對象--> <appender name="console" class="ch.qos.logback.core.ConsoleAppender"> <!--輸出流對象 默認 System.out 改成 System.err--> <target>System.err</target> <!--日誌格式配置--> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <pattern>${pattern}</pattern> </encoder> </appender> <!-- 日誌文件拆分和歸檔的appender對象--> <appender name="rollFile" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!--日誌格式配置--> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <pattern>${pattern}</pattern> </encoder> <!--日誌輸出路徑--> <file>${log_dir}roll_logback.log</file> <!--指定日誌文件拆分和壓縮規則--> <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> <!--經過指定壓縮文件名稱,來肯定分割文件方式--> <fileNamePattern>${log_dir}rolling.%d{yyyy-MM-dd}.log%i.gz</fileNamePattern> <!--文件拆分大小--> <maxFileSize>1MB</maxFileSize> </rollingPolicy> <!--filter配置--> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <!--設置攔截日誌級別--> <level>error</level> <onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch> </filter> </appender> <!--異步日誌--> <appender name="async" class="ch.qos.logback.classic.AsyncAppender"> <appender-ref ref="rollFile"/> </appender> <!--RootLogger對象--> <root level="all"> <appender-ref ref="console"/> <appender-ref ref="async"/> </root> <!--自定義logger additivity表示是否從 rootLogger繼承配置--> <logger name="com.itheima" level="debug" additivity="false"> <appender-ref ref="console"/> </logger> </configuration>
官方提供的log4j.properties轉換成logback.xml
https://logback.qos.ch/translator/
logback-access模塊與Servlet容器(如Tomcat和Jetty)集成,以提供HTTP訪問日誌功能。咱們可使用logback-access模塊來替換tomcat的訪問日誌。
修改$TOMCAT_HOME/conf/server.xml中的Host元素中添加:
<Valve className="ch.qos.logback.access.tomcat.LogbackValve" />
logback默認會在$TOMCAT_HOME/conf下查找文件 logback-access.xml
<?xml version="1.0" encoding="UTF-8"?> <configuration> <!-- always a good activate OnConsoleStatusListener --> <statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener"/> <property name="LOG_DIR" value="${catalina.base}/logs"/> <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${LOG_DIR}/access.log</file> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>access.%d{yyyy-MM-dd}.log.zip</fileNamePattern> </rollingPolicy> <encoder> <!-- 訪問日誌的格式 --> <pattern>combined</pattern> </encoder> </appender> <appender-ref ref="FILE"/> </configuration>
官方配置: https://logback.qos.ch/access.html#configuration
Apache Log4j 2是對Log4j的升級版,參考了logback的一些優秀的設計,而且修復了一些問題,所以帶來了一些重大的提高,主要有:
官網: https://logging.apache.org/log4j/2.x/
目前市面上最主流的日誌門面就是SLF4J,雖然Log4j2也是日誌門面,由於它的日誌實現功能很是強大,性能優越。因此你們通常仍是將Log4j2看做是日誌的實現,Slf4j + Log4j2應該是將來的大勢所趨。
添加依賴
<!-- Log4j2 門面API--> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version>2.11.1</version> </dependency> <!-- Log4j2 日誌實現 --> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.11.1</version> </dependency>
JAVA代碼
public class Log4j2Test { // 定義日誌記錄器對象 public static final Logger LOGGER = LogManager.getLogger(Log4j2Test.class); @Test public void testQuick() throws Exception { LOGGER.fatal("fatal"); LOGGER.error("error"); LOGGER.warn("warn"); LOGGER.info("info"); LOGGER.debug("debug"); LOGGER.trace("trace"); } }
使用slf4j做爲日誌的門面,使用log4j2做爲日誌的實現
<!-- Log4j2 門面API--> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version>2.11.1</version> </dependency> <!-- Log4j2 日誌實現 --> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.11.1</version> </dependency> <!--使用slf4j做爲日誌的門面,使用log4j2來記錄日誌 --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.25</version> </dependency> <!--爲slf4j綁定日誌實現 log4j2的適配器 --> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-slf4j-impl</artifactId> <version>2.10.0</version> </dependency>
log4j2默認加載classpath下的 log4j2.xml 文件中的配置。
<?xml version="1.0" encoding="UTF-8"?> <Configuration status="warn" monitorInterval="5"> <properties> <property name="LOG_HOME">D:/logs</property> </properties> <Appenders> <Console name="Console" target="SYSTEM_OUT"> <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] [%-5level] %c{36}:%L --- %m%n" /> </Console> <File name="file" fileName="${LOG_HOME}/myfile.log"> <PatternLayout pattern="[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%-5level] %l %c{36} - %m%n" /> </File> <RandomAccessFile name="accessFile" fileName="${LOG_HOME}/myAcclog.log"> <PatternLayout pattern="[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%-5level] %l %c{36} - %m%n" /> </RandomAccessFile> <RollingFile name="rollingFile" fileName="${LOG_HOME}/myrollog.log" filePattern="D:/logs/$${date:yyyy-MM-dd}/myrollog-%d{yyyyMM-dd-HH-mm}-%i.log"> <ThresholdFilter level="debug" onMatch="ACCEPT" onMismatch="DENY" /> <PatternLayout pattern="[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%-5level] %l %c{36} - %msg%n" /> <Policies> <OnStartupTriggeringPolicy /> <SizeBasedTriggeringPolicy size="10 MB" /> <TimeBasedTriggeringPolicy /> </Policies> <DefaultRolloverStrategy max="30" /> </RollingFile> </Appenders> <Loggers> <Root level="trace"> <AppenderRef ref="Console" /> </Root> </Loggers> </Configuration>
異步日誌
log4j2最大的特色就是異步日誌,其性能的提高主要也是從異步日誌中受益,咱們來看看如何使用log4j2的異步日誌。
Log4j2提供了兩種實現日誌的方式,一個是經過AsyncAppender,一個是經過AsyncLogger,分別對應前面咱們說的Appender組件和Logger組件。
注意:配置異步日誌須要添加依賴
<!--異步日誌依賴--> <dependency> <groupId>com.lmax</groupId> <artifactId>disruptor</artifactId> <version>3.3.4</version> </dependency>
AsyncAppender方式
<?xml version="1.0" encoding="UTF-8"?> <Configuration status="warn"> <properties> <property name="LOG_HOME">D:/logs</property> </properties> <Appenders> <File name="file" fileName="${LOG_HOME}/myfile.log"> <PatternLayout> <Pattern>%d %p %c{1.} [%t] %m%n</Pattern> </PatternLayout> </File> <Async name="Async"> <AppenderRef ref="file"/> </Async> </Appenders> <Loggers> <Root level="error"> <AppenderRef ref="Async"/> </Root> </Loggers> </Configuration>
全局異步就是,全部的日誌都異步的記錄,在配置文件上不用作任何改動,只須要添加一個log4j2.component.properties 配置;
Log4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector
混合異步就是,你能夠在應用中同時使用同步日誌和異步日誌,這使得日誌的配置方式更加靈活。
<?xml version="1.0" encoding="UTF-8"?> <Configuration status="WARN"> <properties> <property name="LOG_HOME">D:/logs</property> </properties> <Appenders> <File name="file" fileName="${LOG_HOME}/myfile.log"> <PatternLayout> <Pattern>%d %p %c{1.} [%t] %m%n</Pattern> </PatternLayout> </File> <Async name="Async"> <AppenderRef ref="file"/> </Async> </Appenders> <Loggers> <AsyncLogger name="com.itheima" level="trace" includeLocation="false" additivity="false"> <AppenderRef ref="file"/> </AsyncLogger> <Root level="info" includeLocation="true"> <AppenderRef ref="file"/> </Root> </Loggers> </Configuration>
如上配置: com.itheima 日誌是異步的,root日誌是同步的。
使用異步日誌須要注意的問題:
Log4j2最牛的地方在於異步輸出日誌時的性能表現,Log4j2在多線程的環境下吞吐量與Log4j和Logback的比較以下圖。下圖比較中Log4j2有三種模式:
1)全局使用異步模式;
2)部分Logger採用異步模式;
3)異步Appender。能夠看出在前兩種模式下,Log4j2的性能較之Log4j和Logback有很大的優點。
無垃圾記錄
垃圾收集暫停是延遲峯值的常見緣由,而且對於許多系統而言,花費大量精力來控制這些暫停。
許多日誌庫(包括之前版本的Log4j)在穩態日誌記錄期間分配臨時對象,如日誌事件對象,字符串,字符數組,字節數組等。這會對垃圾收集器形成壓力並增長GC暫停發生的頻率。
從版本2.6開始,默認狀況下Log4j以「無垃圾」模式運行,其中重用對象和緩衝區,而且儘量不分配臨時對象。還有一個「低垃圾」模式,它不是徹底無垃圾,但不使用ThreadLocal字段。
Log4j 2.6中的無垃圾日誌記錄部分經過重用ThreadLocal字段中的對象來實現,部分經過在將文本轉換爲字節時重用緩衝區來實現。
使用Log4j 2.5:內存分配速率809 MB /秒,141個無效集合。
Log4j 2.6沒有分配臨時對象:0(零)垃圾回收。
有兩個單獨的系統屬性可用於手動控制Log4j用於避免建立臨時對象的機制:
springboot框架在企業中的使用愈來愈廣泛,springboot日誌也是開發中經常使用的日誌系統。springboot默認就是使用SLF4J做爲日誌門面,logback做爲日誌實現來記錄日誌。
springboot中的日誌
<dependency> <artifactId>spring-boot-starter-logging</artifactId> <groupId>org.springframework.boot</groupId> </dependency>
依賴關係圖:
總結:
在springboot中測試打印日誌
@SpringBootTest class SpringbootLogApplicationTests { //記錄器 public static final Logger LOGGER = LoggerFactory.getLogger(SpringbootLogApplicationTests.class); @Test public void contextLoads() { // 打印日誌信息 LOGGER.error("error"); LOGGER.warn("warn"); LOGGER.info("info"); // 默認日誌級別 LOGGER.debug("debug"); LOGGER.trace("trace"); } }
修改默認日誌配置
logging.level.com.itheima=trace # 在控制檯輸出的日誌的格式 同logback logging.pattern.console=%d{yyyy-MM-dd} [%thread] [%-5level] %logger{50} - %msg%n # 指定文件中日誌輸出的格式 logging.file=D:/logs/springboot.log logging.pattern.file=%d{yyyy-MM-dd} [%thread] %-5level %logger{50} - %msg%n
指定配置
給類路徑下放上每一個日誌框架本身的配置文件;pringBoot就不使用默認配置的了
日誌框架 | 配置文件 |
---|---|
Logback | logback-spring.xml , logback.xml |
Log4j2 | log4j2-spring.xml , log4j2.xml |
JUL | logging.properties |
logback.xml:直接就被日誌框架識別了
使用SpringBoot解析日誌配置
logback-spring.xml:由SpringBoot解析日誌配置
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <springProfile name="dev"> <pattern>${pattern}</pattern> </springProfile> <springProfile name="pro"> <pattern>%d{yyyyMMdd:HH:mm:ss.SSS} [%thread] %-5level %msg%n</pattern> </springProfile> </encoder>
application.properties
spring.profiles.active=dev
將日誌切換爲log4j2
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <!--排除logback--> <exclusion> <artifactId>spring-boot-starter-logging</artifactId> <groupId>org.springframework.boot</groupId> </exclusion> </exclusions> </dependency> <!-- 添加log4j2 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-log4j2</artifactId> </dependency>