情形
複習尚學堂mubatis
一、log4J
1.由apache推出的開源免費日志處理的類庫
2.為什麼需要日志:
2.1 在項目編寫中我們會通過sout來輸出到控制台debug,但是當項目釋出到tomcat上時,由于是linux伺服器,即使有控制台,但是檢視結果不容易,不容易找出錯誤和debug
2.2 log4J的作用,不僅僅能把内容輸出到控制台,還能把内容輸出到檔案中,例如我們的tomcat伺服器的log檔案夾下的日志檔案,便于觀察結果
3.使用步驟
3.1 導入log4j-xxx.jar
3.2 必須在src目錄下建立log4j.properties(路徑和名稱都不允許改變)
4.log4j輸出級别
4.1 fatal(緻命錯誤) > error (錯誤) > warn (警告) > info(普通資訊) > debug(調試資訊)
4.2 在 log4j.properties 的第一行中控制輸出級别:如下設定為ERROR,同時需要注意如果我們設定輸出級别為ERROR,則>=error級别的錯誤才會輸出。<error的錯誤不會輸出。
5. log4j 輸出目的地
5.1 在一行控制輸出目的地:表示将資訊輸出到控制台(console)以及輸出到日志檔案(logfile),并且
6. pattern 中常用幾個表達式
詳細表達式:https://blog.csdn.net/hello_word2/article/details/79295344
- %C 包名+類名
- %d {YYYY-MM-dd HH:mm:ss} 時間
- %L 行号
- %m 資訊
- %n 換行
7.log4j.properties檔案配置總體
# 設定輸出級别和将資訊輸出到哪裡
log4j.rootCategory=INFO, CONSOLE, LOGFILE
# 負責向控制台輸出所使用的類
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
# 向控制台輸出的内容格式,由下列類來控制
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
# 向控制台輸出的具體内容,可以用log4j表達式來表示我們要輸出的内容是什麼,詳細可參考文檔
log4j.appender.CONSOLE.layout.ConversionPattern=%c %d{YYYY/MM/dd hh:mm:ss} %F %m %n
# 負責向日志檔案輸出所使用的類
log4j.appender.LOGFILE=org.apache.log4j.FileAppender
# 向具體哪個目錄下的日志檔案進行輸出,如果寫相對路徑,則在目前項目檔案目錄下輸出,輸出位置與src目錄同級
# 如果寫絕對路徑,linux系統則會在根目錄下建立檔案夾和檔案,如果windows系統,則會根據目前項目在哪個磁盤分區
# 并在該磁盤分區下建立檔案夾和檔案。例如如下/log/axis.log表示在windows系統下建立檔案,位置為F:/log/axis.log
log4j.appender.LOGFILE.File=/logs/axis.log
# 向日志檔案輸出的IO是追加還是非追加,肯定設定為可追加
log4j.appender.LOGFILE.Append=true
# 向日志檔案輸出的内容格式,由下列類來控制
log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
# 向日志檔案輸出的具體内容,可以用log4j表達式來表示我們要輸出的内容是什麼,詳細可參考文檔
log4j.appender.LOGFILE.layout.ConversionPattern=%C %L %m %n
四、mybatis內建log4j
1.步驟
- 導入log4j的jar包:
- 将log4j.properties檔案放到src目錄下:
- 在mybatis.xml配置檔案中添加settings标簽,表示mybatis使用log4j,注意settings标簽要放在environment标簽之前,具體标簽的順序可檢視官方文檔:
-
<settings> <!--設定我們輸出到日志檔案中的資訊的字首字元串,友善在各種程式啟動日志中找到相關sql的資訊的日志,便于定位 PS:關于settings标簽中的logPrefix會和log4j.properties檔案中的"log4j.logger.cn.uestc.mapper=DEBUG", 也就是局部日志資訊輸出級别進行沖突。如果我們配置了logPrefix的同時也設定了局部日志資訊的輸出級别 控制台和日志檔案則不會有任何日志的輸入 這是因為logPrefix所控制的日志輸出為調用sql程式的相關日志,而"log4j.logger.cn.uestc.mapper=DEBUG" 正好也是控制sql程式的相關日志。兩者功能都是篩選,是以兩者沖突,導緻日志檔案和控制台沒有資訊。 如果我們将log4j.properties中“log4j.logger.cn.uestc.mapper=DEBUG”删除,則日志檔案和控制台中會輸出所有 debug級别的日志資訊。同時關于sql的日志會在前面加上“關于sql的相關日志”,而如果我們在這裡将logPrefix 注釋掉,則日志檔案資訊和控制台隻會輸出關于sql的日志資訊,而其他資訊可以通過設定全局級别設定成ERROR而過濾 掉其他資訊的debug資訊--> <!--<setting name="logPrefix" value="關于sql的相關日志:"/>--> <setting name="logImpl" value="LOG4J"/> </settings>
- log4j.properties檔案配置
-
# 設定所有日志資訊的輸出級别、将資訊輸出到哪裡 log4j.rootCategory=ERROR, CONSOLE, LOGFILE #設定局部或者指定日志資訊的輸出級别 log4j.logger.cn.uestc.mapper=DEBUG # 負責向控制台輸出所使用的類 log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender # 向控制台輸出的内容格式,由下列類來控制 log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout # 向控制台輸出的具體内容,可以用log4j表達式來表示我們要輸出的内容是什麼,詳細可參考文檔 log4j.appender.CONSOLE.layout.ConversionPattern=%c %p %d{YYYY/MM/dd hh:mm:ss} %F %m %n # 負責向日志檔案輸出所使用的類 log4j.appender.LOGFILE=org.apache.log4j.FileAppender # 向具體哪個目錄下的日志檔案進行輸出,如果寫相對路徑,則在目前項目檔案目錄下輸出,輸出位置與src目錄同級 # 如果寫絕對路徑,linux系統則會在根目錄下建立檔案夾和檔案,如果windows系統,則會根據目前項目在哪個磁盤分區 # 并在該磁盤分區下建立檔案夾和檔案。例如如下/log/mybatis/sql.log表示在windows系統下建立檔案,位置為F:/logs/mybatis/sql.log log4j.appender.LOGFILE.File=/logs/mybatis/sql.log # 向日志檔案輸出的IO是追加還是非追加,肯定設定為可追加 log4j.appender.LOGFILE.Append=true # 向日志檔案輸出的内容格式,由下列類來控制 log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout # 向日志檔案輸出的具體内容,可以用log4j表達式來表示我們要輸出的内容是什麼,詳細可參考文檔 log4j.appender.LOGFILE.layout.ConversionPattern=%C %L %m %n
2.測試
(1)測試類:
package cn.uestc.test;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
public class TestLog4jUse4mybatis {
public static void main(String[] args) throws IOException {
InputStream resourceAsStream = Resources.getResourceAsStream("mybatis.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
List<Object> list = sqlSession.selectList("cn.uestc.mapper.PeopleMapper.selAll");
sqlSession.close();
}
}
(2)結果:
控制台:
日志檔案:
(3)debug
情形:
在log4j.properties檔案中設定了局部或者指定日志資訊的輸出級别,并在mybatis.xml檔案中配置了logPrefix屬性,導緻日志檔案和控制台沒有輸出日志結果,這是因為log4j.properties中的“log4j.logger.cn.uestc.mapper=DEBUG”與mybatis.xml中的“<setting name="logPrefix" value="關于sql的相關日志:"/>”沖突,兩者的作用都是對日志資訊進行過濾和篩選。log4j.properties的篩選範圍更大,可以指定方法,類或者包下的所有類都進行日志輸出。而logPrefix不會過濾日志資訊,但是他會在關于sql調用的日志資訊前加上“關于sql的相關日志:”的字元串,友善查找。
複現
bug複現:上述兩個過濾條件都不注釋,控制台和日志檔案沒有任何輸出資訊
去掉任何一個過濾條件:這裡我們注釋掉log4j.properties的過濾資訊,因為在2.測試中将logPrefix注釋掉了,同時将log4j.properties中的全局日志輸出級别改為debug,否則程式如果正常不會将日志輸出到控制台或者日志檔案
(4)總結
從精準定位來看,通過log4j.properties檔案來配置過濾資訊是比較好的,日志檔案寫入資訊少,而且不光可以指定輸出sql的日志資訊,還可以指定到具體方法,具體類,和具體包,接下來是對log4j.properties對日志級别的控制總結
- 命名級别(包級别): mapper.xml檔案中的namespace 屬性中除去最後一個類名
- 如何通過log4j.properties檔案來配置過濾資訊
- 1. 先在總體級别調成 Error 不輸出無用資訊
- 2. 在設定某個指定位置級别為 DEBUG
- 如圖:
- 類級别: namespace 屬性值 ,namespace 類名
- 如圖:則在log4j.properties中将上圖中的log4j.logger.cn.uestc.mapper=DEBUG改為log4j.logger.cn.uestc.mapper.PeopleMapper=DEBUG
- 方法級别:使用 namespace 屬性值+标簽 id 屬性值
- 如圖:則在log4j.properties中将上圖中的log4j.logger.cn.uestc.mapper=DEBUG改為log4j.logger.cn.uestc.mapper.PeopleMapper.selAll=DEBUG