日誌文件: 是用於記錄系統操做事件的文件集合,可分爲事件日誌和消息日誌。具備處理歷史數據、診斷問題的追蹤以及理解系統的活動等重要做用。html
軟件開發中,咱們常常須要去調試程序,作一些信息,狀態的輸出便於咱們查詢程序的運行情況。java
系統日誌是記錄系統中硬件、軟件和系統問題的信息,同時還能夠監視系統中發生的事件。用戶能夠經過它來檢查錯誤發生的緣由,或者尋找受到攻擊時攻擊者留下的痕跡。系統日誌包括系統日誌、應用程序日誌和安全日誌。mysql
現有日誌框架:web
JUL(java util logging)、logback、log4j、log4j2spring
JCL(Jakarta Commons Logging)、slf4j( Simple Logging Facade for Java)sql
日誌門面: JCL SLF4J數據庫
日誌實現: JUL logback log4j log4j2apache
日誌級別說明:api
級別 | 說明 |
---|---|
ALL | 全部信息 |
TRACE | 程序運行軌跡 |
DEBUG | debug調試信息 |
INFO | 應用運行過程信息 |
WARN | 潛在的危險情況 |
ERROR | 錯誤信息,程序還能運行 |
FATAL | 嚴重的錯誤,致使程序終止 |
OFF | 不輸出日誌 |
日誌級別排序: 從上到下,依次增長.數組
TRACE < DEBUG < INFO < WARN < ERROR < FATAL
複製代碼
graph LR A[Application] -->B[Logger] B-->C[Handler] C-->D[Outside World] B-->E[Filter] C-->F[Filter] C-->G[Filter]
參數說明:
總結: 用戶使用Logger來進行記錄日誌,Logger持有若干個Handler,日誌的輸出操做有Handler完成. 在Handler輸出日誌前,會通過Filter的過濾,判斷哪些日誌級別過濾,哪些攔截. Handler將日誌輸出到指定的位置(控制檯or文件等).在輸出日誌時會使用Layout,將輸出內容按照指定格式進行排版.
案列:
@Test
public void contextLoads() {
//建立日誌記錄器對象
Logger logger = Logger.getLogger("com.cf.logger.LoggerApplicationTests");
//日誌輸出
logger.info("Hello Jack");
logger.log(Level.INFO,"Hello Info Msg");
String name = "Jack";
String userName ="Mary";
logger.log(Level.INFO,"日誌信息: {0},{1}",new Object[]{name,userName});
}
//結果
/* 三月 30, 2021 9:39:18 下午 com.cf.logger.LoggerApplicationTests contextLoads 信息: Hello Jack 三月 30, 2021 9:39:18 下午 com.cf.logger.LoggerApplicationTests contextLoads 信息: Hello Info Msg 三月 30, 2021 9:39:18 下午 com.cf.logger.LoggerApplicationTests contextLoads 信息: 日誌信息: Jack,Mary */
複製代碼
JUL日誌的級別:
java.util.logging.Level
源碼:
public static final Level OFF = new Level("OFF",Integer.MAX_VALUE, defaultBundle);
public static final Level SEVERE = new Level("SEVERE",1000, defaultBundle);
public static final Level WARNING = new Level("WARNING", 900, defaultBundle);
public static final Level INFO = new Level("INFO", 800, defaultBundle);
public static final Level CONFIG = new Level("CONFIG", 700, defaultBundle);
public static final Level FINE = new Level("FINE", 500, defaultBundle);
public static final Level FINER = new Level("FINER", 400, defaultBundle);
public static final Level FINEST = new Level("FINEST", 300, defaultBundle);
public static final Level ALL = new Level("ALL", Integer.MIN_VALUE, defaultBundle);
複製代碼
從源碼中能夠得知JUL的日誌級別以下:
ALL(特殊->全部日誌) < FINEST < FINER < FINE < CONFIG<INFO(默認)<WARNING<SEVERE(最高)<OFF(特殊->關閉日誌)
複製代碼
JUL默認INFO級別日誌,因此不指定級別使用時,只能輸出INFO級別以上的日誌信息.
案列:
@Test
public void testLogLevel() throws Exception {
// 1.獲取日誌對象
Logger logger = Logger.getLogger("com.cf.logger.LoggerApplicationTests");
// 2.日誌記錄輸出
logger.severe("severe");
logger.warning("warning");
logger.info("info");
logger.config("cofnig");
logger.fine("fine");
logger.finer("finer");
logger.finest("finest");
}
// 結果
/* 三月 30, 2021 9:51:23 下午 com.cf.logger.LoggerApplicationTests testLogLevel 嚴重: severe 三月 30, 2021 9:51:23 下午 com.cf.logger.LoggerApplicationTests testLogLevel 警告: warning 三月 30, 2021 9:51:23 下午 com.cf.logger.LoggerApplicationTests testLogLevel 信息: info */
複製代碼
自定義日誌級別配置:
@Test
public void testLogConfig() throws Exception {
// 1.建立日誌記錄器對象
Logger logger = Logger.getLogger("com.cf.logger.LoggerApplicationTests");
// 1、自定義日誌級別
// a.關閉系統默認配置
logger.setUseParentHandlers(false);
// b.建立handler對象
ConsoleHandler consoleHandler = new ConsoleHandler();
// c.建立formatter對象
SimpleFormatter simpleFormatter = new SimpleFormatter();
// d.進行關聯
consoleHandler.setFormatter(simpleFormatter);
logger.addHandler(consoleHandler);
// e.設置日誌級別
logger.setLevel(Level.ALL);
consoleHandler.setLevel(Level.ALL);
// 2、輸出到日誌文件
FileHandler fileHandler = new FileHandler("d:/jul.log");
fileHandler.setFormatter(simpleFormatter);
logger.addHandler(fileHandler);
// 2.日誌記錄輸出
logger.severe("severe");
logger.warning("warning");
logger.info("info");
logger.config("cofnig");
logger.fine("fine");
logger.finer("finer");
logger.finest("finest");
}
//結果
/* 三月 30, 2021 9:57:56 下午 com.cf.logger.LoggerApplicationTests testLogConfig 嚴重: severe 三月 30, 2021 9:57:56 下午 com.cf.logger.LoggerApplicationTests testLogConfig 警告: warning 三月 30, 2021 9:57:56 下午 com.cf.logger.LoggerApplicationTests testLogConfig 信息: info 三月 30, 2021 9:57:56 下午 com.cf.logger.LoggerApplicationTests testLogConfig 配置: cofnig 三月 30, 2021 9:57:56 下午 com.cf.logger.LoggerApplicationTests testLogConfig 詳細: fine 三月 30, 2021 9:57:56 下午 com.cf.logger.LoggerApplicationTests testLogConfig 較詳細: finer 三月 30, 2021 9:57:56 下午 com.cf.logger.LoggerApplicationTests testLogConfig 很是詳細: finest 在D盤下生成jul.log.txt文件 */
複製代碼
JUL中Logger之間存在父子關係,該父子關係經過樹狀結構存儲,JUL在初始化時會建立一個頂層RootLogger做爲全部Logger的父Logger.存儲上該父Logger相似 樹狀結構的根節點.父子關係經過路徑來關聯.
案列:
@Test
public void testLogParent() throws Exception {
// 日誌記錄器對象父子關係
Logger logger1 = Logger.getLogger("com.cf.logger.LoggerApplicationTests");
Logger logger2 = Logger.getLogger("com.cf.logger");
System.out.println(logger1.getParent() == logger2);
// 全部日誌記錄器對象的頂級父元素 logger2 parent:java.util.logging.LogManager$RootLogger@299a06ac,name:""
System.out.println("logger2 parent:" + logger2.getParent() + ",name:" + logger2.getParent().getName());
// 1、自定義日誌級別
// a.關閉系統默認配置
logger2.setUseParentHandlers(false);
// b.建立handler對象
ConsoleHandler consoleHandler = new ConsoleHandler();
// c.建立formatter對象
SimpleFormatter simpleFormatter = new SimpleFormatter();
// d.進行關聯
consoleHandler.setFormatter(simpleFormatter);
logger2.addHandler(consoleHandler);
// e.設置日誌級別
logger2.setLevel(Level.ALL);
consoleHandler.setLevel(Level.ALL);
// 測試日誌記錄器對象父子關係
logger1.severe("severe");
logger1.warning("warning");
logger1.info("info");
logger1.config("config");
logger1.fine("fine");
logger1.finer("finer");
logger1.finest("finest");
}
複製代碼
默認的配置文件路徑: $JAVAHOME\jre\lib\logging.properties
logging.properties
日誌配置
## RootLogger使用的處理器(獲取時設置)
handlers= java.util.logging.ConsoleHandler
# RootLogger日誌等級
.level= INFO
## 自定義Logger
com.cf.handlers= java.util.logging.FileHandler
# 自定義Logger日誌等級
com.cf.level= INFO
# 忽略父日誌設置
com.cf.useParentHandlers=false
## 控制檯處理器
# 輸出日誌級別
java.util.logging.ConsoleHandler.level = INFO
# 輸出日誌格式
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
## 文件處理器
# 輸出日誌級別
java.util.logging.FileHandler.level=INFO
# 輸出日誌格式
java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter
# 輸出日誌文件路徑
java.util.logging.FileHandler.pattern = /java%u.log
# 輸出日誌文件限制大小(50000字節)
java.util.logging.FileHandler.limit = 50000
# 輸出日誌文件限制個數
java.util.logging.FileHandler.count = 10
# 輸出日誌文件 是不是追加
java.util.logging.FileHandler.append=true
複製代碼
案列:
@Test
public void testProperties() throws Exception {
// 讀取自定義配置文件
InputStream in = LoggerApplicationTests.class.getClassLoader().getResourceAsStream("logging.properties");
// 獲取日誌管理器對象
LogManager logManager = LogManager.getLogManager();
// 經過日誌管理器加載配置文件
logManager.readConfiguration(in);
Logger logger = Logger.getLogger("com.cf.logger.LoggerApplicationTests");
logger.severe("severe");
logger.warning("warning");
logger.info("info");
logger.config("config");
logger.fine("fine");
logger.finer("finer");
logger.finest("finest");
}
//結果
/* 在D盤中生成 java0.log.0文件名的日誌 */
複製代碼
1 初始化LogManager
2 從單例LogManager中獲取Logger
3 設置級別Level.並指定日誌記錄LogRecord
4 Filter提供了日誌級別以外更細粒度的控制
5 Handler是用來處理日誌輸出位置
6 Formatter是用來格式化LogRecord的.
JUL流程示意圖
graph LR A[應用] -->B[Logger] B-->C[LogRecord] C-->D[Handler] D-->E[輸出] F[LogManager]-->B G[Level]-->C H[Filter]-->D I[Formatter]-->E
Log4j是Apache下的一款開源的日誌框架.
官網: logging.apache.org/log4j/1.2/
添加pom.xml座標
<dependencies>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
複製代碼
案例:
package com.cf.logger;
import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.Logger;
import org.junit.Test;
public class LoggerApplicationTests {
@Test
public void testQuick() throws Exception {
// 初始化系統配置,不須要配置文件
BasicConfigurator.configure();
// 建立日誌記錄器對象
Logger logger = Logger.getLogger(LoggerApplicationTests.class);
// 日誌記錄輸出
logger.info("hello log4j");
// 日誌級別
logger.fatal("fatal"); // 嚴重錯誤,通常會形成系統崩潰和終止運行
logger.error("error"); // 錯誤信息,但不會影響系統運行
logger.warn("warn"); // 警告信息,可能會發生問題
logger.info("info"); // 程序運行信息,數據庫的鏈接、網絡、IO操做等
logger.debug("debug"); // 調試信息,通常在開發階段使用,記錄程序的變量、參數等
logger.trace("trace"); // 追蹤信息,記錄程序的全部流程信息
}
}
複製代碼
org.apache.log4j.Level
源碼:
final static public Level OFF = new Level(OFF_INT, "OFF", 0);
final static public Level FATAL = new Level(FATAL_INT, "FATAL", 0);
final static public Level ERROR = new Level(ERROR_INT, "ERROR", 3);
final static public Level WARN = new Level(WARN_INT, "WARN", 4);
final static public Level INFO = new Level(INFO_INT, "INFO", 6);
final static public Level DEBUG = new Level(DEBUG_INT, "DEBUG", 7);
public static final Level TRACE = new Level(TRACE_INT, "TRACE", 7);
final static public Level ALL = new Level(ALL_INT, "ALL", 7);
複製代碼
從源碼中能夠得知JUL的日誌級別以下:
OFF(特殊->關閉日誌) > Fatal(嚴重錯誤,致使程序退出) > ERROR(可能錯誤,但不影響系統運行) > WARN(潛在錯誤)>INFO(粗粒度)>DUBUG(細粒度)>TRACE(程序追蹤)>ALL(特殊->全部日誌)
複製代碼
一般使用級別: ERROR > WARN > INFO > DEBUG
由下列三大組件組成:
Loggers: 日誌記錄器,收集處理日誌記錄,實例的命名就是類的全限定名,Logger名字大小寫敏感,且命名有繼承機制.
name爲com.cf.logger的logger會繼承name爲con.cf的logger
log4j中有一個特殊的logger叫作root
,它是全部logger的根.根logger能夠用Logger.getRootLogger()方法獲取.
log4j從1.2版本,Logger類取代了Category類
Appenders: 指定日誌輸出的地方.
輸出地方總結圖:
輸出地方 | 說明 |
---|---|
ConsoleAppender | 輸出到控制檯 |
FileAppender | 輸出到文件 |
DailyRollingFileAppender | 天天輸出到一個新文件 |
RollingFileAppender | 輸出到日誌文件,指定文件的尺寸,當文件到達指定尺寸,自定把文件更名,同時產生一個新的文件 |
JDBCAppender | 保存到數據庫中 |
Layouts: 控制日誌輸出內容的格式.
經常使用格式總結:
格式化器類型 | 做用 |
---|---|
HTMLLayout | 輸出爲HTML表格形式 |
SimpleLayout | 志輸出爲HTML表格形式 |
PatternLayout | 能夠自定義格式輸出日誌,沒有定義,就用默認格式 |
* log4j 採用相似 C 語言的 printf 函數的打印格式格式化日誌信息,具體的佔位符及其含義以下:
%m 輸出代碼中指定的日誌信息
%p 輸出優先級,及 DEBUG、INFO 等
%n 換行符(Windows平臺的換行符爲 "\n",Unix 平臺爲 "\n")
%r 輸出自應用啓動到輸出該 log 信息耗費的毫秒數
%c 輸出打印語句所屬的類的全名
%t 輸出產生該日誌的線程全名
%d 輸出服務器當前時間,默認爲 ISO8601,也能夠指定格式,如:%d{yyyy年MM月dd日
HH:mm:ss}
%l 輸出日誌時間發生的位置,包括類名、線程、及在代碼中的行數。如:
Test.main(Test.java:10)
%F 輸出日誌消息產生時所在的文件名稱
%L 輸出代碼中的行號
%% 輸出一個 "%" 字符
* 能夠在 % 與字符之間加上修飾符來控制最小寬度、最大寬度和文本的對其方式。如:
%5c 輸出category名稱,最小寬度是5,category<5,默認的狀況下右對齊
%-5c 輸出category名稱,最小寬度是5,category<5,"-"號指定左對齊,會有空格
%.5c 輸出category名稱,最大寬度是5,category>5,就會將左邊多出的字符截掉,<5不
會有空格
%20.30c category名稱<20補空格,而且右對齊,>30字符,就從左邊交遠銷出的字符截掉
複製代碼
#指定日誌的輸出級別與輸出端
log4j.rootLogger=INFO,Console
# 控制檯輸出配置
log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n
# 文件輸出配置
log4j.appender.A = org.apache.log4j.DailyRollingFileAppender
#指定日誌的輸出路徑
log4j.appender.A.File = D:/log.txt
log4j.appender.A.Append = true
#使用自定義日誌格式化器
log4j.appender.A.layout = org.apache.log4j.PatternLayout
#指定日誌的輸出格式
log4j.appender.A.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [%t:%r] -
[%p] %m%n
#指定日誌的文件編碼
log4j.appender.A.encoding=UTF-8
#mysql
log4j.appender.logDB=org.apache.log4j.jdbc.JDBCAppender
log4j.appender.logDB.layout=org.apache.log4j.PatternLayout
log4j.appender.logDB.Driver=com.mysql.jdbc.Driver
log4j.appender.logDB.URL=jdbc:mysql://localhost:3306/test
log4j.appender.logDB.User=root
log4j.appender.logDB.Password=root
log4j.appender.logDB.Sql=INSERT INTO
log(project_name,create_date,level,category,file_name,thread_name,line,all_categ
ory,message) values('itcast','%d{yyyy-MM-dd
HH:mm:ss}','%p','%c','%F','%t','%L','%l','%m')
複製代碼
sql腳本:
CREATE TABLE `log` (
`log_id` int(11) NOT NULL AUTO_INCREMENT,
`project_name` varchar(255) DEFAULT NULL COMMENT '目項名',
`create_date` varchar(255) DEFAULT NULL COMMENT '建立時間',
`level` varchar(255) DEFAULT NULL COMMENT '優先級',
`category` varchar(255) DEFAULT NULL COMMENT '所在類的全名',
`file_name` varchar(255) DEFAULT NULL COMMENT '輸出日誌消息產生時所在的文件名稱 ',
`thread_name` varchar(255) DEFAULT NULL COMMENT '日誌事件的線程名',
`line` varchar(255) DEFAULT NULL COMMENT '號行',
`all_category` varchar(255) DEFAULT NULL COMMENT '日誌事件的發生位置',
`message` varchar(4000) DEFAULT NULL COMMENT '輸出代碼中指定的消息',
PRIMARY KEY (`log_id`)
);
複製代碼
# RootLogger配置
log4j.rootLogger = trace,console
# 自定義Logger
log4j.logger.com.cf.logger = info,file
log4j.logger.org.apache = error
複製代碼
案例:
@Test
public void testCustomLogger() throws Exception {
// 自定義 com.cf
Logger logger1 = Logger.getLogger(LoggerApplicationTests.class);
logger1.fatal("fatal"); // 嚴重錯誤,通常會形成系統崩潰和終止運行
logger1.error("error"); // 錯誤信息,但不會影響系統運行
logger1.warn("warn"); // 警告信息,可能會發生問題
logger1.info("info"); // 程序運行信息,數據庫的鏈接、網絡、IO操做等
logger1.debug("debug"); // 調試信息,通常在開發階段使用,記錄程序的變量、參數等
logger1.trace("trace"); // 追蹤信息,記錄程序的全部流程信息
// 自定義 org.apache
Logger logger2 = Logger.getLogger(Logger.class);
logger2.fatal("fatal logger2"); // 嚴重錯誤,通常會形成系統崩潰和終止運行
logger2.error("error logger2"); // 錯誤信息,但不會影響系統運行
logger2.warn("warn logger2"); // 警告信息,可能會發生問題
logger2.info("info logger2"); // 程序運行信息,數據庫的鏈接、網絡、IO操做等
logger2.debug("debug logger2"); // 調試信息,通常在開發階段使用,記錄程序的變量、參數等
logger2.trace("trace logger2"); // 追蹤信息,記錄程序的全部流程信息
}
複製代碼
JCL: Jakarta Commons Logging
, 是Apache提供的一個通用日誌API,它自帶一個日誌的實現(SimpleLog),功能比較弱.它也爲Java日誌實現提供一個統一的接口,容許開發人員使用不一樣的具體日誌實現工具: Log4j,JDK自帶的日誌JUL.
JCL的兩個基本抽象類:
graph TD A[Java應用]-->B[JCL] B-->C[log4j] B-->D[jdk14] B-->E[simpleLog]
添加pom.xml
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
複製代碼
案例:
@Test
public void testQuick() throws Exception {
// 建立日誌對象
Log log = LogFactory.getLog(LoggerApplicationTests.class);
// 日誌記錄輸出
log.fatal("fatal");
log.error("error");
log.warn("warn");
log.info("info");
log.debug("debug");
}
//結果
/* 三月 31, 2021 9:03:50 下午 com.cf.logger.LoggerApplicationTests testQuick 嚴重: fatal 三月 31, 2021 9:03:50 下午 com.cf.logger.LoggerApplicationTests testQuick 嚴重: error 三月 31, 2021 9:03:50 下午 com.cf.logger.LoggerApplicationTests testQuick 警告: warn 三月 31, 2021 9:03:50 下午 com.cf.logger.LoggerApplicationTests testQuick 信息: info */
複製代碼
總結: 使用日誌門面的優勢.
1 經過LogFactory動態加載Log實現類.(Log實現類有不少)
2 日誌門面支持的日誌實現數組org.apache.commons.logging.impl.LogFactoryImpl
private static final String[] classesToDiscover =
new String[]{"org.apache.commons.logging.impl.Log4JLogger",
"org.apache.commons.logging.impl.Jdk14Logger",
"org.apache.commons.logging.impl.Jdk13LumberjackLogger",
"org.apache.commons.logging.impl.SimpleLog"};
複製代碼
3 獲取具體的日誌實現org.apache.commons.logging.impl.LogFactoryImpl
for(int i = 0; i < classesToDiscover.length && result == null; ++i) {
result = this.createLogFromClass(classesToDiscover[i], logCategory,
true);
}
複製代碼
常見的日誌門面:
JCL slf4j
常見的日誌實現:
JUL log4j logback log4j2
日誌框架發展順序:
log4j --> JUL --> JCL --> slf4j --> logback --> log4j2
複製代碼
官網: www.slf4j.org/
SLF4J: (Simple Logging Facade For Java)簡單日誌門面. 主要給Java日誌訪問提供一套標準,規範的API框架.提供接口,具體的實現由其餘日誌框架. 經常使用的日誌框架,選擇slf4j-api做爲門面,由log4j,logback等框架去實現,中間使用橋接器完成橋接.
添加pom.xml座標
<!--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>
複製代碼
案列:
public class LoggerApplicationTests {
// 聲明日誌對象
public final static Logger LOGGER = LoggerFactory.getLogger(LoggerApplicationTests.class);
@Test
public void test() 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);
}
}
}
//結果
/* [main] ERROR com.cf.logger.LoggerApplicationTests - error [main] WARN com.cf.logger.LoggerApplicationTests - warn [main] INFO com.cf.logger.LoggerApplicationTests - info [main] INFO com.cf.logger.LoggerApplicationTests - 用戶:jack,18 [main] INFO com.cf.logger.LoggerApplicationTests - 出現異常: java.lang.ArithmeticException: / by zero */
複製代碼
總結:
使用slf4j的日誌綁定流程:
使用時導入依賴:
<!--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綁定.
e.g: 要從java.util.logging
切換到log4j,只須要將slf4j-jdk14
替換成slf4j-log4j12
SLF4J不依賴任何特殊的類裝載.每一個SLF4J綁定在編譯時都是硬鏈接的,使用一個且只有一個特定的日誌記錄框架.
e.g: slf4j-log4j12-1.7.27.jar
綁定在編譯時綁定以使用log4j。在代碼中,除了slf4j-api-1.7.27.jar
以外,只需將選擇的一個且只有一個綁定放到相應的類路徑位置。不要在類路徑上放置多個綁定.
橋接: 解決項目中日誌遺留問題.,當系統中存在以前的日誌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>
複製代碼
tips:
jcl-over-slf4j.jar
和 slf4j-jcl.jar
不能同時部署。前一個jar文件將致使JCL將日誌系統的選擇委託給 SLF4J,後一個jar文件將致使SLF4J將日誌系統的選擇委託給JCL,從而致使無限循環。log4j-over-slf4j.jar
和slf4j-log4j12.jar
不能同時出現.jul-to-slf4j.jar
和slf4j-jdk14.jar
不能同時出現.1 SLF4J經過LoggerFactory加載日誌具體的實現對象。
2 LoggerFactory在初始化的過程當中,會經過performInitialization()方法綁定具體的日誌實現。
3 在綁定具體實現的時候,經過類加載器,加載org/slf4j/impl/StaticLoggerBinder.class。
4 只要是一個日誌實現框架,在org.slf4j.impl包中提供一個本身的StaticLoggerBinder類,在其中提供具體日誌實現的LoggerFactory就能夠被SLF4J所加載。
Logback: 由log4j創始人設計的開源日誌組件,性能比log4j好.
主要分紅三個模塊:
添加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>
複製代碼
案例:
public class LoggerApplicationTests {
// 聲明日誌對象
public final static Logger LOGGER = LoggerFactory.getLogger(LoggerApplicationTests.class);
@Test
public void testSlf4j(){
//打印日誌信息
LOGGER.error("error");
LOGGER.warn("warn");
LOGGER.info("info");
LOGGER.debug("debug");
LOGGER.trace("trace");
}
}
//結果
/* 22:32:30.844 [main] ERROR com.cf.logger.LoggerApplicationTests - error 22:32:30.853 [main] WARN com.cf.logger.LoggerApplicationTests - warn 22:32:30.853 [main] INFO com.cf.logger.LoggerApplicationTests - info 22:32:30.853 [main] DEBUG com.cf.logger.LoggerApplicationTests - debug */
複製代碼
logback會依次讀取如下類型配置文件:(都不存在,採用默認配置)
1 logback組件間的關係
2 基本配置信息
<?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>
複製代碼
3 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>
複製代碼
4 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
複製代碼
5 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-MMdd}.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>
複製代碼
6 官方提供的log4j.properties轉換成logback.xml
logback-access模塊與Servlet容器(如Tomcat和Jetty)集成,以提供HTTP訪問日誌功能。咱們可使 用logback-access模塊來替換tomcat的訪問日誌。
使用方法:
1 將logback-access.jar與logback-core.jar複製到$TOMCAT_HOME/lib/目錄下
2 修改$TOMCAT_HOME/conf/server.xml中的Host元素中添加:
<Valve className="ch.qos.logback.access.tomcat.LogbackValve" />
複製代碼
3 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>
複製代碼
4 官方配置: logback.qos.ch/access.html…
官網: logging.apache.org/log4j/2.x/
log4j2是log4j的升級版,參考了logback的一些優秀的設計,而且修復了一些問題:
目前使用最多的日誌門面是SLF4J. 雖然Log4j2也是日誌門面,由於它的日誌實現功能很是強 大,性能優越。因此你們通常仍是將Log4j2看做是日誌的實現,Slf4j + Log4j2應該是將來的大勢所趨。
1 添加依賴:
<!-- 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>
複製代碼
2 案列:
public class LoggerApplicationTests {
// 定義日誌記錄器對象
public static final Logger LOGGER = LogManager.getLogger(LoggerApplicationTests.class);
@Test
public void test() throws Exception {
LOGGER.fatal("fatal");
LOGGER.error("error");
LOGGER.warn("warn");
LOGGER.info("info");
LOGGER.debug("debug");
LOGGER.trace("trace");
}
}
//結果
/* 23:12:26.384 [main] FATAL com.cf.logger.LoggerApplicationTests - fatal 23:12:26.388 [main] ERROR com.cf.logger.LoggerApplicationTests - error */
複製代碼
3 使用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提供了兩種實現日誌的方式,一個是經過AsyncAppender,一個是經過AsyncLogger,分別對應前面的Appender組件和Logger組件。
tips: 配置異步日誌須要下面依賴
<!--異步日誌依賴-->
<dependency>
<groupId>com.lmax</groupId>
<artifactId>disruptor</artifactId>
<version>3.3.4</version>
</dependency>
複製代碼
1 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>
複製代碼
2 AsyncLogger方式
AsyncLogger纔是log4j2的重點,是官方推薦的異步方式。它可使得調用Logger.log返回的更快。包括: 全局異步和混合異步。
全局異步: 全部的日誌都異步的記錄,在配置文件上不用作任何改動,只須要添加一個 log4j2.component.properties 配置;
Log4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerCon
textSelector
複製代碼
混合異步: 在應用中同時使用同步日誌和異步日誌,這使得日誌的配置方式更加靈活。
<?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.cf.logging" level="trace" includeLocation="false" additivity="false">
<AppenderRef ref="file"/>
</AsyncLogger>
<Root level="info" includeLocation="true">
<AppenderRef ref="file"/>
</Root>
</Loggers>
</Configuration>
複製代碼
如上配置: com.cf.logging日誌是異步的,root日誌是同步的。
tips:
springboot 默認就是使用SLF4J做爲日誌門面,logback做爲日誌實現來記錄日誌。
springboot中的日誌jar包:
<dependency>
<artifactId>spring-boot-starter-logging</artifactId>
<groupId>org.springframework.boot</groupId>
</dependency>
複製代碼
總結:
1 springboot 底層默認使用logback做爲日誌實現
2 使用了SLF4J做爲日誌門面
3 將JUL也轉換成slf4j
4 也可使用log4j2做爲日誌門面,可是最終也是經過slf4j調用logback
1 案列
@SpringBootTest
public class LoggerApplicationTests {
//記錄器
public static final Logger LOGGER = LoggerFactory.getLogger(LoggerApplicationTests.class);
@Test
public void contextLoads() {
// 打印日誌信息
LOGGER.error("error");
LOGGER.warn("warn");
LOGGER.info("info"); // 默認日誌級別
LOGGER.debug("debug");
LOGGER.trace("trace");
}
}
//結果
/* 23:41:25.191 [main] ERROR com.cf.logger.LoggerApplicationTests - error 23:41:25.196 [main] WARN com.cf.logger.LoggerApplicationTests - warn 23:41:25.196 [main] INFO com.cf.logger.LoggerApplicationTests - info 23:41:25.196 [main] DEBUG com.cf.logger.LoggerApplicationTests - debug */
複製代碼
2 修改默認日誌配置
logging.level.com.cf.logger=trace
# 在控制檯輸出的日誌的格式 同logback
logging.pattern.console=%d{yyyy-MM-dd} [%thread] [%-5level] %logger{50} -%msg%n
# 指定文件中日誌輸出的格式
logging.file.path=D:\\springboot.log
logging.pattern.file=%d{yyyy-MM-dd} [%thread] %-5level %logger{50} - %msg%n
複製代碼
3 指定配置
給類路徑下放上每一個日誌框架本身的配置文件,SpringBoot就不使用默認配置.
框架 | 配置文件 |
---|---|
logback | logback-spring.xml , logback.xml |
Log4j2 | log4j2-spring.xml , log4j2.xml |
JUL | logging.properties |
4 使用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
複製代碼
5 將日誌切換爲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>
複製代碼
導入pom.xml
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.16</version>
</dependency>
複製代碼
package com.cf.logger;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@SpringBootTest
@RunWith(SpringRunner.class)
@Slf4j
public class LoggerApplicationTests {
@Test
public void contextLoads() {
log.info("[{}]","小明");
log.error("[{}]","小紅");
log.debug("[{}]","小白");
log.warn("[{}]","小藍");
log.trace("[{}]","小黃");
}
}
//結果
/* 2021-03-29 21:59:52.805 INFO 9260 --- [ main] com.cf.logger.LoggerApplicationTests : [小明] 2021-03-29 21:59:52.805 ERROR 9260 --- [ main] com.cf.logger.LoggerApplicationTests : [小紅] 2021-03-29 21:59:52.805 WARN 9260 --- [ main] com.cf.logger.LoggerApplicationTests : [小藍] */
複製代碼
說明:
@Slf4j
註解,被編譯後的源文件會自動加上private static final Logger log = LoggerFactory.getLogger
方法.