故事篇:終於給老婆講明白什麼是logback了!

故事會遲到,但他從不會缺席。今天的故事開始了,你準備好了嗎?html

前奏

簡單介紹一下個人老婆:集智慧與美貌於一身的女子——阿狸,一句「咱們心有靈犀,不是嗎?」讓我瞬間「淪陷」。 java

阿Q: 老婆,還記得往年過節的時候我都送過你什麼禮物嗎?面試

阿狸: 固然記得呀:剛過的兒童節送了一排旺仔牛奶和一大包零食;5·20送了一款我喜歡的香水;女神節給我買了一個超好看的包包......算法

阿Q: 這都是今年的,那去年的還記得嗎?spring

阿狸: 我想一想哈:去年聖誕節買了個聖誕老人的蛋糕還有一雙漂亮的高跟鞋;過生日的時候送了一束鮮花還有一個大紅包;嗯......sql

阿Q: 看看,看看想不起來了吧,我就知道時間久了就記不住了,我來給你說一下吧:巴拉巴拉(露出得意的表情)。數據庫

阿狸: 哇塞,你真厲害,你是怎麼作到的呢?apache

阿Q: 哈哈,這就不得不說一下我用到的日誌了,你可聽好了。api

正題

LogBack簡介

阿Q: 我說的日誌呢就跟我們以前寫過的日記同樣,只不過它是用來記錄操做系統事件的文件的集合。常見的日誌框架呢有如下幾種:數組

  • JUL(Java Util Logging)
  • Logback
  • Log4j
  • Log4j2
  • JCL(Jakarta Commons Logging)
  • Slf4j(Simple Logging Facade For Java)

阿狸: 這麼多框架,該使用哪一個好呢?

阿Q: 我首推Logback日誌框架:首先它配置比較簡單,比較容易上手;其次配置比較靈活,能知足大部分項目的需求;最後性能比較好,能夠異步存儲日誌。我以爲這也是它在市面上比較流行,項目中使用比較多的緣由吧。

阿狸: 哦哦,那我pick它。

阿Q: Logback是經過slf4j的日誌門面搭建的日誌系統,門面與實現的關係瞭解一下。

接着奉上官網地址,它分爲如下三個模塊:

  • logback-core:其它兩個模塊的基礎模塊;
  • logback-classic:它是log4j的一個改良版本,同時它完整實現了slf4j API,你能夠很方便地更換成其它日誌框架(如log4j或者JUL);
  • logback-access:訪問模塊與Servlet容器集成提供經過Http來訪問日誌的功能,能夠輕鬆地在logback核心之上構建本身的模塊。

logback組件之間的關係 能夠大致瞭解下,實戰篇更容易理解

  • Logger做爲日誌的記錄器,把它關聯到應用的對應的context上後,主要用於存放日誌對象,也能夠定義日誌類型、級別; 
  • Appender主要用於指定日誌輸出的目的地,能夠是控制檯、文件、遠程套接字服務器、MySQLPostreSQLOracle和其餘數據庫、 JMS和遠程UNIX Syslog守護進程等;   
  • Layout負責把事件轉換成字符串,格式化的日誌信息的輸出。在logbackLayout對象被封裝在encoder中;
  • Logger Context:各個logger都被關聯到一個 LoggerContext,它負責製造logger,也負責以樹結構排列各logger。其餘全部logger也經過org.slf4j.LoggerFactory 類的靜態方法getLogger取得。

Logger 能夠被分配的級別包括:TRACEDEBUGINFOWARNERROR,定義於ch.qos.logback.classic.Level類。若是 logger沒有被分配級別,那麼它將從有被分配級別的最近的祖先那裏繼承級別。root logger 默認級別是 DEBUG

級別排序爲: TRACE < DEBUG < INFO < WARN < ERROR

項目實戰

阿狸: 太囉嗦了,快點進入實戰吧。

阿Q: OK,若是你建立的是普通的maven項目,你須要引入pom文件:

<!-- slf4j日誌門面 -->
<dependency>
	<groupId>org.slf4j</groupId>
	<artifactId>slf4j-api</artifactId>
	<version>1.7.30</version>
</dependency>

<!-- logback日誌實現 -->
<dependency>
	<groupId>ch.qos.logback</groupId>
	<artifactId>logback-classic</artifactId>
	<version>1.2.3</version>
</dependency>

logback會從 classpath 下依次讀取如下類型的配置文件:

  • logback.groovy
  • logback-test.xml
  • logback.xml

若是文件都不存在,logbackBasicConfigurator 自動對本身進行配置,這會致使記錄輸出到控制檯。

基本信息配置

代碼測試樣例奉上:

public class TestLogBack {

    private static final Logger logger = LoggerFactory.getLogger(TestLogBack.class);

    public static void main(String[] args) {
        for (int i = 0; i < 10000; i++) {

            logger.error("error");
            logger.warn("warn");
            logger.info("info");
            logger.debug("debug");
            logger.trace("trace");

        }
    }
}

首先咱們在resources下建立一個logback.xml,而後進行配置

<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
    <!--
        配置集中管理屬性
        咱們能夠直接改屬性的 value 值
        格式:${name}
     -->

    <property name="pattern" value="[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} %c %M %L [%thread] %m%n"/>
    <!--
        日誌輸出格式:
        %-5level 日誌輸出級別,佔5位,靠左補全
        %d{yyyy-MM-dd HH:mm:ss.SSS} 時間
        %c 類的完整名稱
        %M method
        %L 行號
        %thread 線程名稱
        %m或者%msg 信息
        %n 換行
     -->

    <!-- 控制檯日誌輸出的 appender -->
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <!-- 控制輸出流對象 默認 System.out  咱們爲了測試能夠改成 System.err(項目中使用 System.out ) -->
        <target>System.err</target>
        <!-- 日誌消息格式配置 -->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${pattern}</pattern>
        </encoder>
    </appender>


    <!-- 定義日誌文件保存路徑屬性 -->
    <property name="log_dir" value="/logs"/>

    <!-- 日誌文件輸出的 appender -->
    <appender name="file" class="ch.qos.logback.core.FileAppender">
        <!-- 日誌文件保存路徑 -->
        <file>${log_dir}/logback.log</file>
        <!--  日誌消息格式配置 -->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${pattern}</pattern>
        </encoder>
    </appender>

    <!-- html 格式文件輸出的 appender -->
    <appender name="htmlFile" class="ch.qos.logback.core.FileAppender">
        <!-- 日誌文件保存路徑 -->
        <file>${log_dir}/logback.html</file>
        <!-- html消息格式配置 -->
        <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
            <layout class="ch.qos.logback.classic.html.HTMLLayout">
<!--                <pattern>${pattern}</pattern>-->
                <pattern>%-5level%d{yyyy-MM-dd HH:mm:ss.SSS}%c%M%L%thread%m</pattern>
            </layout>
        </encoder>
    </appender>
  <!-- root logger 配置 -->
    <root level="ALL">
        <appender-ref ref="console"/>
        <appender-ref ref="file"/>
        <appender-ref ref="htmlFile"/>
    </root>
    
</configuration>

運行以後發如今控制檯打印出紅色字體的日誌信息,在/log文件下有logback.loglogback.html兩個日誌文件,在項目中通常都只會使用.log結尾的日誌的。

阿狸: 奧,你就是經過這個文件找到的吧,那天天都產生這麼多行日誌,找起來不是太費勁了嗎?另外文件太大,打開都很費勁呀。

阿Q: 固然了,請接着往下看

<!-- 日誌拆分和歸檔壓縮的 appender -->
<appender name="rollFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <!-- 日誌文件保存路徑(拆分的話此處能夠省略) -->
    <file>${log_dir}/roll_logback.log</file>
    <!-- 日誌消息格式配置-->
    <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
        <pattern>${pattern}</pattern>
    </encoder>
    <!-- 指定拆分規則 -->
    <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
        <!-- 每滿1M或者 每秒 產生一個新文件,%i產生0 或者 1 的文件名 ,gz爲壓縮,
        咱們通常設置爲天天產生一個文件%d{yyyy-MM-dd} -->
        <!-- 按照文件大小拆分 -->
        <maxFileSize>1MB</maxFileSize>
        <!-- 按照時間和壓縮格式聲明拆分的文件名 -->
        <fileNamePattern>${log_dir}/rolling.%d{yyyy-MM-dd-HH-mm-ss}.log%i.gz</fileNamePattern>
    </rollingPolicy>
</appender>

此時咱們對測試程序加上for循環,循環1w次,發現每秒或者每超過1M都會產生新的文件。固然也能夠在appender下增長過濾器,過濾須要的日誌級別。

<!-- 日誌級別過濾器 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
    <!-- 日誌過濾規則 -->
    <level>ERROR</level>
    <!-- 匹配時的操做:接收(記錄) -->
    <onMatch>ACCEPT</onMatch>
    <!-- 不匹配時的操做:拒絕(不記錄) -->
    <onMismatch>DENY</onMismatch>
</filter>

阿狸: 這樣就清晰多了,那你上邊提到的那個分文件的策略是怎麼發現的呢?能跟我說一下你的依據嗎?

阿Q: 好的,那就來幾張圖感覺一下吧

  1. 先打開RollingFileAppender,能夠看到他底下有個RollingPolicy策略
  2. 點進去發現它是一個接口,而後看一下它的實現類,咱們找到SizeAndTimeBasedRollingPolicy策略看一下 3.發現這個類裏邊就有文件大小的屬性maxFileSize,卻沒有找到按照時間份文件的屬性,咱們進入它的父類TimeBasedRollingPolicy查看 4.發現裏邊就有該屬性,翻譯一下:必須在使用TimeBasedRollingPolicy以前設置FileNamePattern選項

阿狸: 我還有一個問題,就是系統在執行時還要完成打印日誌的工做,它的效率會不會很低呀?

阿Q: 不會的,爲了提升性能,它還支持異步輸出日誌,這樣就能夠大大提升性能了。

<!-- 異步日誌 -->
<appender name="async" class="ch.qos.logback.classic.AsyncAppender">
    <!-- 指定具體的appender -->
    <appender-ref ref="rollFile"/>
</appender>

除了上邊用到的root,還支持自定義的logger呢。

<!-- 自定義logger對象
  additivity="false" 自定義的logger 對象是否繼承root logger
  name 用來指定受此loger約束的某一個包或者具體的某一個類
-->
<logger name="com.aq.logback" level="info" additivity="false">
  <appender-ref ref="console"/>
</logger>

SpringBoot中使用

阿狸: 說到這我想起來了,你說的是普通的maven項目,那經常使用的SpringBoot項目也是這樣使用嗎?

阿Q: 若是是SpringBoot項目的話,它默認使用slf4j做爲日誌門面,logback做爲日誌實現來記錄日誌,因此咱們不須要引入任何依賴,默認是info級別。

咱們還能夠直接使用@Slf4j的註解來代替上邊的

private static final Logger logger = LoggerFactory.getLogger(TestLogBack.class);

引用是使用log.info("info");來實現。它的默認加載順序是logback-spring.xml->logback.xml

咱們能夠在application.properties中簡單配置

#指定自定義 logger 對象的日誌級別
logging.level.com.itzyq.sblogback=trace

#指定控制檯輸出消息格式
logging.pattern.console=[%-5level] %d{yyyy-MM-dd HH:mm:ss} %c [%thread] ===== %m %n

#指定存放日誌文件的具體路徑(已經棄用)
#logging.file=/logs/springboot.log
#指定日誌文件存放的目錄,默認的文件名爲spring.log
logging.file.path=/logs/springboot/
#指定日誌文件的消息格式
logging.pattern.file=[%-5level] %d{yyyy-MM-dd HH:mm:ss} %c [%thread] ===== %m %n

由於在properties中配置功能有限,咱們仍是使用上文中的logback.xml來配置。

阿狸: 艾,那爲啥不使用logback-spring.xml呢?

阿Q: SpringBoot中是推薦使用logback-spring.xml的,由於上文中是普通的maven項目,爲了好理解就搞成logback.xml了。

logback-spring.xml只有在Spring應用程序運行的時候才生效,即帶有@SpringBootApplication註解的類啓動的時候纔會生效。這裏咱們徹底可使用它。

另外它還有個特殊的功能,能夠用來解析日誌的配置。

<?xml version="1.0" encoding="UTF-8"?>
<configuration>

    <property name="pattern" value="[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} %c %M %L [%thread] %m%n"/>

    <!-- 定義日誌文件保存路徑屬性 -->
    <property name="log_dir" value="/logs"/>

    <!-- 日誌文件輸出的 appender -->
    <appender name="file" class="ch.qos.logback.core.FileAppender">
        <!-- 日誌文件保存路徑 -->
        <file>${log_dir}/logback.log</file>
        <!-- 日誌消息格式配置-->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <springProfile name="dev">
                <pattern>${pattern}</pattern>
            </springProfile>
            <springProfile name="pro">
                <pattern> %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %m%n</pattern>
            </springProfile>
        </encoder>
    </appender>

    <root level="info">
        <appender-ref ref="file"/>
    </root>

</configuration>

此時在application.properties中引入spring.profiles.active=dev或者pro能夠切換測試和正式環境了,是否是很方便呀。

Logback-access

阿狸: 確實是,那既然都說到這了,你能說下上邊提到的logback-access嗎?

阿Q: 好吧,那我就大致說一下它的配置和使用吧:logback-access模塊與Servlet容器(如Tomcatjetty)集成,已提供HTTP訪問日誌功能。咱們可使用logback-access模塊來替換tomcat的訪問日誌;

  1. logback-access.jarlogback-core.jar 複製到$TOMCAT_HOME/lib/(安裝 Tomcat 的文件夾)目錄下;

  2. 修改$TOMCAT_HOME/conf/server.xml中的Host元素中添加:

<Value className="ch.qos.logback.access.tomcat.LogbackValue" />

這一行一般嵌套在一個<Engine><Host>元素中。

  1. logback 默認會在$TOMCAT_HOME/conf下查找文件logback-access.xml,該配置的官方地址:http://logback.qos.ch/access.html#configuration
<configuration>
  <!-- always a good activate OnConsoleStatusListener -->
  <statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" />  

  <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>access.log</file>
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
      <fileNamePattern>access.%d{yyyy-MM-dd}.log.zip</fileNamePattern>
    </rollingPolicy>

    <encoder>
      <!-- 日誌消息表達格式 -->
      <pattern>%h %l %u [%t] "%r" %s %b "%i{Referer}" 「%i{User-Agent}」</pattern>
      <pattern>combined</pattern>
    </encoder>
  </appender>
 
  <appender-ref ref="FILE" />
</configuration>

配置信息補充

阿狸: 講到這就結束了嗎?

阿Q: 由於logback的配置信息在上文中難以所有展現,特將具體的配置信息列出來,供你們參考學習。

(1)根節點configuration,包含下面三個屬性:

  • scan: 當此屬性設置爲true時,配置文件若是發生改變,將會被從新加載,默認值爲true
  • scanPeriod: 設置監測配置文件是否有修改的時間間隔,若是沒有給出時間單位,默認單位是毫秒。當scantrue時,此屬性生效。默認的時間間隔爲1分鐘。
  • debug: 當此屬性設置爲true時,將打印出logback內部日誌信息,實時查看logback運行狀態。默認值爲false
<configuration scan="true" scanPeriod="60 seconds" debug="false"> 
</configuration> 

(2)contextName:用來設置上下文名稱,每一個logger都關聯到logger上下文,默認上下文名稱爲default。但可使用contextName設置成其餘名字,用於區分不一樣應用程序的記錄。一旦設置,不能修改。

<configuration scan="true" scanPeriod="60 seconds" debug="false"> 
     <contextName>myAppName</contextName> 
  </configuration>

(3) property :用來定義變量值,它有兩個屬性namevalue,經過property定義的值會被插入到logger上下文中,可使「${}」來使用變量。  

  • name: 變量的名稱
  • value: 的值時變量定義的值

(4) timestamp:獲取時間戳字符串,他有兩個屬性keydatePattern    

  • key: 標識此timestamp的名字;
  • datePattern: 設置將當前時間(解析配置文件的時間)轉換爲字符串的模式,遵循java.txt.SimpleDateFormat的格式。
<configuration scan="true" scanPeriod="60 seconds" debug="false"> 
    <timestamp key="bySecond" datePattern="yyyyMMdd'T'HHmmss"/> 
</configuration>

(5)appender:負責寫日誌的組件,它有兩個必要屬性nameclassname指定appender名稱,class指定appender的全限定名

5.一、ConsoleAppender 把日誌輸出到控制檯,有如下子節點:

  • encoder:對日誌進行格式化。
  • target:字符串System.out(默認)或者System.err

5.二、FileAppender:把日誌添加到文件,有如下子節點:      

  • file:被寫入的文件名,能夠是相對目錄,也能夠是絕對目錄,若是上級目錄不存在會自動建立,沒有默認值。      
  • append:若是是 true,日誌被追加到文件結尾,若是是 false,清空現存文件,默認是true。      
  • encoder:對記錄事件進行格式化。     
  • prudent:若是是 true,日誌會被安全的寫入文件,即便其餘的FileAppender也在向此文件作寫入操做,效率低,默認是 false

5.三、RollingFileAppender:滾動記錄文件,先將日誌記錄到指定文件,當符合某個條件時,將日誌記錄到其餘文件。有如下子節點:      

  • file:被寫入的文件名,能夠是相對目錄,也能夠是絕對目錄,若是上級目錄不存在會自動建立,沒有默認值。      
  • append:若是是 true,日誌被追加到文件結尾,若是是 false,清空現存文件,默認是true。      
  • rollingPolicy:當發生滾動時,決定RollingFileAppender的行爲,涉及文件移動和重命名。屬性class定義具體的滾動策略類。

5.四、策略: class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy": 最經常使用的滾動策略,它根據時間來制定滾動策略,既負責滾動也負責觸發滾動。 有如下子節點:

  • fileNamePattern:必要節點,包含文件名及「%d」轉換符,「%d」能夠包含一個java.text.SimpleDateFormat指定的時間格式,如:%d{yyyy-MM}。若是直接使用 %d,默認格式是 yyyy-MM-dd
  • RollingFileAppenderfile子節點無關緊要,經過設置file,能夠爲活動文件和歸檔文件指定不一樣位置,當前日誌老是記錄到file指定的文件(活動文件),活動文件的名字不會改變;若是沒設置file,活動文件的名字會根據fileNamePattern 的值,每隔一段時間改變一次。「/」或者「\」會被當作目錄分隔符。        
  • maxHistory:可選節點,控制保留的歸檔文件的最大數量,超出數量就刪除舊文件。 假設設置每月滾動,且<maxHistory>是6,則只保存最近6個月的文件,刪除以前的舊文件。注意,刪除舊文件時,那些爲了歸檔而建立的目錄也會被刪除。  

class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy": 查看當前活動文件的大小,若是超過指定大小會告知RollingFileAppender 觸發當前活動文件滾動。只有一個節點:        

  • maxFileSize:這是活動文件的大小,默認值是10MB
  • prudent:當爲true時,不支持FixedWindowRollingPolicy。支持TimeBasedRollingPolicy,可是有兩個限制,1不支持也不容許文件壓縮,2不能設置file屬性,必須留空。
  • triggeringPolicy: 告知 RollingFileAppender 合適激活滾動。 

class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy" 根據固定窗口算法重命名文件的滾動策略。有如下子節點:        

  • minIndex:窗口索引最小值        
  • maxIndex:窗口索引最大值,當用戶指定的窗口過大時,會自動將窗口設置爲12。        
  • fileNamePattern:必須包含「%i」例如,假設最小值和最大值分別爲1和2,命名模式爲 mylog%i.log,會產生歸檔文件mylog1.logmylog2.log。還能夠指定文件壓縮選項,例如,mylog%i.log.gz 或者 沒有log%i.log.zip
<configuration> 
      <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> 
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> 
          <fileNamePattern>logFile.%d{yyyy-MM-dd}.log</fileNamePattern> 
          <maxHistory>30</maxHistory> 
        </rollingPolicy> 
        <encoder> 
          <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern> 
        </encoder> 
      </appender> 

      <root level="DEBUG"> 
        <appender-ref ref="FILE" /> 
      </root> 
    </configuration>
   //上述配置表示天天生成一個日誌文件,保存30天的日誌文件。
<configuration> 
      <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> 
        <file>test.log</file> 

        <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy"> 
          <fileNamePattern>tests.%i.log.zip</fileNamePattern> 
          <minIndex>1</minIndex> 
          <maxIndex>3</maxIndex> 
        </rollingPolicy> 

        <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> 
          <maxFileSize>5MB</maxFileSize> 
        </triggeringPolicy> 
        <encoder> 
          <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern> 
        </encoder> 
      </appender> 

      <root level="DEBUG"> 
        <appender-ref ref="FILE" /> 
      </root> 
    </configuration>
    //上述配置表示按照固定窗口模式生成日誌文件,當文件大於5MB時,生成新的日誌文件。窗口大小是1到3,當保存了3個歸檔文件後,將覆蓋最先的日誌。

encoder:對記錄事件進行格式化。負責兩件事,一是把日誌信息轉換成字節數組,二是把字節數組寫入到輸出流。

PatternLayoutEncoder 是惟一有用的且默認的encoder ,有一個pattern節點,用來設置日誌的輸入格式。使用「%」加「轉換符」方式,若是要輸出「%」,則必須用「\」「\%」進行轉義。

(6)子節點logger:用來設置某一個包或具體的某一個類的日誌打印級別、以及指定appender。僅有一個name屬性,一個可選的level和一個可選的additivity單詞必定要注意寫對,好多地方都寫成了addtivity)屬性。能夠包含零個或多個<appender-ref>元素,標識這個appender將會添加到這個logger

  • name:用來指定受此 logger 約束的某一個包或者具體的某一個類;
  • level:用來設置打印級別(日誌級別),大小寫無關:TRACE, DEBUG, INFO, WARN, ERROR, ALLOFF,還有一個特殊值INHERITED或者同義詞NULL,表明強制執行上級的級別。若是未設置此屬性,那麼當前 logger 將會繼承上級的級別。
  • additivity:是否向上級loger傳遞打印信息。默認是true

(7)子節點root:它也是logger元素,可是它是根 logger ,是全部logger的上級。只有一個level屬性,由於name已經被命名爲"root",且已是最上級了。同logger同樣,能夠包含零個或多個appender-ref元素,標識這個appender將會添加到這個logger。    

  • level: 用來設置打印級別,大小寫無關:TRACE, DEBUG, INFO, WARN, ERROR, ALLOFF,不能設置爲INHERITED或者同義詞NULL。 默認是DEBUG

經常使用logger配置

<!-- 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" />

<!--myibatis log configure-->
<logger name="com.apache.ibatis" level="TRACE"/>
<logger name="java.sql.Connection" level="DEBUG"/>
<logger name="java.sql.Statement" level="DEBUG"/>
<logger name="java.sql.PreparedStatement" level="DEBUG"/>

阿狸: 老公你也太貼心了,我也要用起來,記錄美好的生活!

以上就是今天的全部內容了,若是你有不一樣的意見或者更好的idea,歡迎聯繫阿Q:qingqing-4132,阿Q期待你的到來!

後臺留言領取java乾貨資料:學習筆記與大廠面試題
相關文章
相關標籤/搜索