Mybatis日志配置方式(slf4j、log4j、log4j2)
1. Mybatis日志
1.1 日志實現原理
Mybatis 通過使用內置的日志工廠提供日志功能。
內置日志工廠將會把日志工作委托給下面的實現之一:
- SLF4J
- Apache Commons Logging
- Log4j2
- Log4j
- JDK logging
MyBatis 內置日志工廠會基于運行時檢測信息選擇日志委托實現。它會(按上面羅列的順序)使用第一個查找到的實現。當沒有找到這些實現時,將會禁用日志功能。
1.2 日志實現方式
不少應用服務器(如 Tomcat 和 WebShpere)的類路徑中已經包含 Commons Logging。
注意,在這種配置環(huán)境下,MyBatis 會把 Commons Logging 作為日志工具。
這就意味著在諸如 WebSphere 的環(huán)境中,由于提供了 Commons Logging 的私有實現,你的 Log4J 配置將被忽略。
這個時候你就會感覺很郁悶:看起來 MyBatis 將你的 Log4J 配置忽略掉了(其實是因為在這種配置環(huán)境下,MyBatis 使用了 Commons Logging 作為日志實現)。
如果你的應用部署在一個類路徑已經包含 Commons Logging 的環(huán)境中,而你又想使用其它日志實現,你可以通過在 MyBatis 配置文件 mybatis-config.xml 里面添加一項 setting 來選擇其它日志實現。
setting配置日志的有效取值
可選的值有: SLF4J、LOG4J、LOG4J2、JDK_LOGGING、COMMONS_LOGGING、STDOUT_LOGGING、NO_LOGGING,或者是實現了 org.apache.ibatis.logging.Log 接口,且構造方法以字符串為參數的類完全限定名。
示例:
僅當運行時類路徑中存在該日志實現時,日志實現的切換才會生效。
如果你的環(huán)境中并不存在 Log4J,你卻試圖調用了相應的方法,MyBatis 就會忽略這一切換請求,并將以默認的查找順序決定使用的日志實現。
2. SLF4J
SLF4J其實只是一個門面服務而已,他并不是真正的日志框架,真正的日志的輸出相關的實現還是要依賴Log4j、logback等日志框架的。
簡單日志門面(simple logging Facade for java),slf4j并不是一個完整的日志框架,他只是為各種日志框架提供統(tǒng)一的API接口,及根據slf4j提供的接口規(guī)則使用Logger,而在部署的時候根據自己的需求配置自己希望使用的日志系統(tǒng)??梢哉f他是將各個日志系統(tǒng)接口進行了抽象,抽象為統(tǒng)一的slf4j接口,這樣只要項目中使用slf4j API,我們可以隨時更換日志實現,而不用更改代碼。
2.1 slf4j日志級別
SLF4J將日志分為trace、debug、info、warn、error五個級別,每個級別對應記錄不同的日志,對應不同的使用場景。
- trace: trace是最低優(yōu)先級的日志,一般用來追蹤詳細的程序運行流,比如程序的運行過程中,運行到了哪一個方法,進入了哪一條分支。通過trace程序的運行流程,可以判斷程序是否按照期望的邏輯在運行。
- debug: debug是比trace高一級別的日志,該級別的日志就是用來debug用的。這類日志往往用在判斷是否有出現bug的場景,且往往記錄了代碼運行的詳細信息,比如方法調用傳入的參數信息。
- info: info比debug高一級別,用來記錄程序運行的一些關鍵信息,比如系統(tǒng)運行到了哪一個階段,到達了哪一個狀態(tài)。
- warn: warn比info的級別更高,用來記錄一些警告信息。警告信息表示,程序進入了一個特殊的狀態(tài),在該狀態(tài)下程序可以繼續(xù)運行,但是不建議讓程序進入該狀態(tài),因為該狀態(tài)可能導致結果出現問題。
- error: error級別的日志是最高優(yōu)先級了,用來記錄運行時的錯誤信息,表示程序運行過程中出現了需要被解決的問題,往往是一些異常。使用error日志的時候,一般會將詳細的異常出現的原因記錄
2.2 日志門面與日志實現
(1)日志門面
日志門面為日志系統(tǒng)也提供一套接口規(guī)范,日志系統(tǒng)通過這套日志門面進行開發(fā)避免了直接依賴具體的日志框架。
(2)日志實面
具體日志功能的實現框架
(3)關系
日志系統(tǒng)一般分為,日志門面和日志實面(實現);在使用了日志門面后,更改日志框架的時候就不需要修改底層代碼;
- 日志門面與日志實現是接口與實現類的關系;
- 日志門面可以理解為java中的一個interface(接口),而日志實面就是就是實現類。
- 日志實面即為日志實現,實現了日志門面中所規(guī)定的日志系統(tǒng)所需實現的功能,也就是說日志實面是日志門面中接口的實現類。
(4)優(yōu)點
- 面向接口開發(fā),不再依賴具體的實現類。減少代碼的耦合。
- 項目通過導入不同的日志實現類,可以靈活的切換日志框架
- 統(tǒng)一API,方便開發(fā)者學習和使用
- 統(tǒng)一配置便于項目日志的管理
2.3 日志門面與日志依賴配置
mybatis日志設置
<settings> <setting name="logImpl" value="SLF4J"/> </settings>
(1)slf4j + log4j
<!-- slf4j日志門面 --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.25</version> </dependency> <!-- 引入slf4j對應log4j的橋接器 --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.25</version> </dependency> <!-- log4j日志實面(日志實現框架) --> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency>
(2)slf4j + log4j2
<!-- slf4j日志門面 --> <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> <scope>runtime</scope> <version>2.11.0</version> </dependency> <!-- log4j2日志實面(日志實現框架) --> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <scope>runtime</scope> <version>2.11.0</version> </dependency>
3. LOG4J
Log4j 是 Apache 的一個開放源代碼項目,通過使用 Log4j,我們可以控制日志信息輸送的目的地是控制臺、文件、GUI 組件、甚至是套接口服務 器、NT 的事件記錄器、UNIX Syslog 守護進程等;我們也可以控制每一條日志的輸出格式;通過定義每一條日志信息的級別,我們能夠更加細致地控制日志的生成過程。
最令人感興趣的就 是,這些可以通過一個配置文件來靈活地進行配置,而不需要修改應用的代碼。
3.1 日志級別
每個Logger都被了一個日志級別(log level),用來控制日志信息的輸出。
日志級別從高到低分為:
- fatal 指出每個嚴重的錯誤事件將會導致應用程序的退出。
- error 指出雖然發(fā)生錯誤事件,但仍然不影響系統(tǒng)的繼續(xù)運行。
- warn 表明會出現潛在的錯誤情形。
- info 一般和在粗粒度級別上,強調應用程序的運行全程。
- debug 一般用于細粒度級別上,對調試應用程序非常有幫助。
- trace 是程序追蹤,可以用于輸出程序運行中的變量,顯示執(zhí)行的流程。
還有兩個特殊的級別:
- OFF,可用來關閉日志記錄。
- ALL,啟用所有消息的日志記錄。
3.2 log4j重要組件
log4j從功能實現來說,主要由三大組件組成:Logger、Appender、Layout。(對應關系如下:)
- Logger是日志記錄器(也可以說是日志級別)
- Appender是日志輸出目的地
- Layout是日志輸出格式控制器
一個日志記錄器可以對應多個輸出目的地,每個輸出目的地有特定的輸出格式。
(1)Logger
日志記錄器,指定輸出日志的級別,并且可以配置輸出日志的指定空間
log4j.prpperties配置
# 自定義logger(指定要輸出日志的全限定路徑、日志級別、選擇的appender) log4j.logger.com.qf.dao=debug,CONSOLE
log4j.xml配置
<!-- 自定義logger,additivity 日志是否在父Logger中輸出(即root中))--> <!-- 自定義logger(指定要輸出日志的全限定路徑、日志級別、選擇的appender)--> <logger name="com.qfedu.dao" additivity="false"> <appender-ref ref="CONSOLE"/> <appender-ref ref="LOGFILE"/> </logger>
(2)Appender
log4j將日志輸出源稱為Appender,每個輸出源一個Appender,一個logger可以對應多個Appender。
常見Appender
- org.apache.log4j.ConsoleAppender:控制臺輸出
- org.apache.log4j.FileAppender:輸出到文件
- org.apache.log4j.DailyRollingFileAppender:每天產生日志輸出到文件
- org.apache.log4j.RollingFileAppender:文件達到指定大小產生新文件
- org.apache.log4j.WriterAppender:以流格式發(fā)送到指定位置
- org.apache.log4j.jdbc.JDBCAppender:輸出到數據庫
log4j.prpperties配置
# CONSOLE is set to be a ConsoleAppender using a PatternLayout. log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout log4j.appender.CONSOLE.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] [%c:%L] [%p] - %m%n
log4j.xml配置
<!-- 日志控制臺輸出配置--> <appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender"> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] [%c:%L] [%p] - %m%n"/> </layout> </appender>
(3)Layout
每個Appender可以指定特定的輸出格式,log4j將輸出格式稱為Layout。
常見Layout
- org.apache.log4j.HTMLLayout:HTML格式Layout
- org.apache.log4j.PatternLayout:自定義格式Layout(常用)
- org.apache.log4j.SimpleLayout:包含日志信息級別及信息
- org.apache.log4j.TTCCLayout:包含生產時間、類別、級別等
常用PatternLayout
- %m 輸出代碼中指定的消息
- %p 輸出優(yōu)先級,即DEBUG,INFO,WARN,ERROR,FATAL
- %r 輸出自應用啟動到輸出該log信息耗費的毫秒數
- %c 輸出所屬的類目,通常就是所在類的全名
- %t 輸出產生該日志事件的線程名
- %n 輸出一個回車換行符,Windows平臺為“\r\n”,Unix平臺為“\n”
- %-x 左對其信息
3.3 mybatis日志配置log4j
mybatis配置log4j有以下兩種配置方式,主要區(qū)別為是否使用日志門面
(1)(日志門面+日志實面):slf4j + log4j
步驟1:mybatis日志設置
<settings> <setting name="logImpl" value="SLF4J"/> </settings>
步驟2:導入相關依賴
<!-- slf4j日志門面 --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.25</version> </dependency> <!-- 引入slf4j對應log4j的橋接器 --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.25</version> </dependency> <!-- log4j日志實面(日志實現框架) --> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency>
步驟3:編寫配置文件
log4j基于自動配置,所以配置文件名稱只能為: log4j.properties
或 log4j.xml
以下示例僅展示文件輸出與控制臺輸出配置
配置1:log4j.properties
# Set root category priority to INFO and its only appender to CONSOLE. log4j.rootLogger=debug, CONSOLE, LOGFILE # 表示自定義的logger不會繼承父Logger的appender輸出,默認為true及輸出 lo4j.log4j.additivity.org.apache=false # CONSOLE is set to be a ConsoleAppender using a PatternLayout. log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout log4j.appender.CONSOLE.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] [%c:%L] [%p] - %m%n # LOGFILE is set to be a File appender using a PatternLayout. log4j.appender.LOGFILE=org.apache.log4j.FileAppender log4j.appender.LOGFILE.File=d:\mybatis.log log4j.appender.LOGFILE.Append=true log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout log4j.appender.LOGFILE.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] [%c:%L] [%p] - %m%n # 自定義logger(指定要輸出日志的全限定路徑、日志級別、選擇的appender) log4j.logger.com.qf.dao=debug,CONSOLE
配置2:log4j.xml
自定義logger(指定要輸出日志的全限定路徑、日志級別、選擇的appender),可以選擇多個appender
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE log4j:configuration SYSTEM "http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/xml/doc-files/log4j.dtd"> <log4j:configuration debug="true"> <!-- 日志控制臺輸出配置--> <appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender"> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] [%c:%L] [%p] - %m%n"/> </layout> </appender> <!-- 日志文件輸出配置--> <appender name="LOGFILE" class="org.apache.log4j.FileAppender"> <param name="File" value="d:\mybatis.log"/> <param name="Append" value="true"/> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] [%c:%L] [%p] - %m%n"/> </layout> </appender> <!-- 自定義logger,additivity 日志是否在父Logger中輸出(即root中))--> <!-- 自定義logger(指定要輸出日志的全限定路徑、日志級別、選擇的appender)--> <logger name="com.qfedu.dao" additivity="false"> <appender-ref ref="CONSOLE"/> <appender-ref ref="LOGFILE"/> </logger> <!-- 根logger--> <root> <level value="debug "/> <appender-ref ref="CONSOLE"/> </root> </log4j:configuration>
(2)(不使用日志門面–不推薦): log4j
步驟1:mybatis日志設置
<settings> <setting name="logImpl" value="LOG4J"/> </settings>
步驟2:導入相關依賴
<dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.16</version> </dependency>
步驟3:編寫配置文件
- log4j基于自動配置,所以配置文件名稱只能為:
log4j.properties
或log4j.xml
- 以下示例僅展示文件輸出與控制臺輸出配置
- 參考上述方式一示例
3. LOG4J2
Apache Log4j2 是對Log4j 的升級:(Log4j2已經不僅僅是Log4j的一個升級版本了,而是從頭到尾被重寫的,這可以認為這其實就是完全不同的兩個框架。)
- 異常處理,在logback中,Appender中的異常不會被應用感知到,但是在log4j2中,提供了一些異常處理機制。
- 性能提升,log4j2 相較于log4j 和 logback 都具有明顯的性能提升,有18倍性能提升。
- 自動重載配置,參考了logback的設計,當然會提供自動刷新參數配置,最實用的就是我們在生產上可以動態(tài)的修改日志的級別而不需要重啟應用。
- 無垃圾機制,log4j2 在大部分情況下,都可以使用其設計的一套無垃圾機制【對象重用、內存緩沖】,避免頻繁的日志收集導致的 jvm gc。
3.1 mybatis配置log4j2
mybatis配置log4j2有以下兩種配置方式,主要區(qū)別為使用哪一個日志門面,一般情況下,由于log4j功能過于強大,所以 slf4j + log4j2
會是后續(xù)流行的搭配!
(1)log4j2(日志+門面)
步驟1:配置mybatis文件
<settings> <setting name="logImpl" value="LOG4J2"/> </settings>
步驟2:導入相關依賴
<!-- log4j2日志門面--> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version>2.11.2</version> </dependency> <!-- log4j2日志實面(日志實現)--> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.11.2</version> </dependency>
步驟3:編寫log4j2配置文件
—— 見下文
(2)slf4j + log4j2
步驟1:配置mybatis文件
<settings> <setting name="logImpl" value="SLF4J"/> </settings>
步驟2:導入相關依賴
<!-- slf4j日志門面 --> <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> <scope>runtime</scope> <version>2.11.0</version> </dependency> <!-- log4j2日志實面(日志實現框架) --> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <scope>runtime</scope> <version>2.11.0</version> </dependency>
步驟3:編寫log4j2配置文件
—— 見下文
3.2 log4j2配置文件
(1)配置文件格式
注意配置文件命名格式
(2)配置文件內容(只展示控制臺輸出和文件輸出)
log4j2從和log4j的組件含義大致相同,只是Appender組件子組件名稱不同,功能實現來說,主要由三大組件組成:Logger、Appender、Layout。(對應關系如下:)
- Logger是日志記錄器(也可以說是日志級別)
- Appender是日志輸出目的地
- Layout是日志輸出格式控制器
一個日志記錄器可以對應多個輸出目的地,每個輸出目的地有特定的輸出格式。
<?xml version="1.0" encoding="UTF-8"?> <Configuration> <Appenders> <!-- 日志輸出到控制臺--> <Console name="CONSOLE" target="SYSTEM_OUT"> <PatternLayout pattern="[%t] %-5level %logger{36} - %msg%n"/> </Console> <!-- 日志輸出到文件--> <File name="LOGFILE" fileName="d:\mybatis.log" append="true"> <PatternLayout pattern="[%t] %-5level %logger{36} - %msg%n"/> </File> </Appenders> <Loggers> <!-- 自定義日志記錄器--> <Logger name="com.j2205.wangwenfei.mapper" level="trace" additivity="false"> <AppenderRef ref="CONSOLE"/> <AppenderRef ref="LOGFILE"/> </Logger> <!-- 根日志記錄器--> <Root level="error" > <AppenderRef ref="CONSOLE"/> </Root> </Loggers> </Configuration>
(3)log4j2 配置文件含義
Loggers 指定logger,logger與appeder進行關聯(lián),將logger中的日志輸出到appender,由appender實現日志的控制臺輸出或者文件記錄。
- Root 用來指定項目的根日志,如果沒有單獨指定Logger,那么就會默認使用該Root日志輸出
- level 日志輸出級別,共有8個級別,按照從低到高為:All < Trace < Debug < Info < Warn < Error < Fatal < OFF.
- AppenderRef用來指定該日志輸出到哪個Appender.(可以配置多項)。
Logger 自定義的子日志
- level 日志輸出級別,共有8個級別,按照從低到高為:All < Trace < Debug < Info < Warn < Error < Fatal < OFF。
- name 用來指定該Logger所適用的類或者類所在的包全路徑,繼承自Root節(jié)點。
- additivity 日志是否在父Logger中輸出。
- AppenderRef用來指定該日志輸出到哪個Appender,如果沒有指定,就會默認繼承自Root.如果指定了,那么會在指定的這個Appender和Root的Appender中都會輸出,此時我們可以設置Logger的additivity="false"只在自定義的Appender中進行輸出。
總結
以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
idea配置tomcat,idea配置web下lib的包詳解
這篇文章主要介紹了idea配置tomcat,idea配置web下lib的包,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-05-05Java反射根據不同方法名動態(tài)調用不同的方法(實例)
下面小編就為大家?guī)硪黄狫ava反射根據不同方法名動態(tài)調用不同的方法(實例)。小編覺得挺不錯的,現在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-08-08淺析Java?NIO?直接緩沖區(qū)和非直接緩沖區(qū)
本篇文章主要為大家介紹了Java?NIO?中直接緩沖區(qū)和非直接緩沖區(qū)的定義以及使用流程,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-11-11