《手把手教你》系列基礎篇(八十七)-java+ selenium自動化測試-框架設計基礎-Log4j 2實現日誌輸出-上篇(詳解教程)
1.簡介
Apache Log4j 是一個非常古老的日誌框架,並且是多年來最受歡迎的日誌框架。 它引入了現代日誌框架仍在使用的基本概念,如分層日誌級別和記錄器。
2015 年 8 月 5 日,該專案管理委員會宣佈 Log4j 1.x 已達到使用壽命。 建議使用者使用 Log4j 1 升級到 Apache Log4j 2。因此巨集哥覺得有必要介紹一下Log4j 2,今天就單獨一篇介紹一下。
2.Log4j2簡介
Apache Log4j 2是對 Log4j 的升級,它比其前身 Log4j 1.x 提供了重大改進,並提供了 Logback 中可用的許多改進,同時修復了 Logback 架構中的一些固有問題。
與 Logback 一樣,Log4j2 提供對 SLF4J 的支援,自動重新載入日誌配置,並支援高階過濾選項。 除了這些功能外,它還允許基於 lambda 表示式對日誌語句進行延遲評估,為低延遲系統提供非同步記錄器,並提供無垃圾模式以避免由垃圾收集器操作引起的任何延遲。
所有這些功能使 Log4j2 成為這三個日誌框架中最先進和最快的。
3.log4j2優點
log4j2參考了logback的一些優秀的設計,並且修復了一些問題,因此帶來了一些重大的提升,主要有:
(1)異常處理:在logback中,Appender中的異常不會被應用感知到,但是在log4j2中,提供了一些異常處理機制。
(2)效能提升:log4j2相較於log4j 1和logback都具有很明顯的效能提升。
(3)自動過載配置:參考了logback的設計,提供自動重新整理引數配置,可以動態的修改日誌的級別而不需要重啟應用。
(4)無垃圾機制,log4j2在大部分情況下,都可以使用其設計的一套無垃圾機制,避免頻繁的日誌收集導致的jvm gc。
4.log4j2配置說明
log4j 2.x版本不再支援像1.x中的.properties字尾的檔案配置方式,2.x版本常用.xml字尾的檔案進行配置,除此之外還包含.json和.jsn配置檔案
log4j2雖然採用xml風格進行配置,依然包含三個元件,分別是 Logger(記錄器)、Appender(輸出目的地)、Layout(日誌佈局)。
4.1XML配置檔案解析
(1)根節點Configuration有兩個屬性:status和monitorinterval,有兩個子節點:Appenders和Loggers(表明可以定義多個Appender和Logger).
status用來指定log4j本身的列印日誌的級別.monitorinterval為log4j 2.x新特點自動過載配置。指定自動重新配置的監測間隔時間,單位是s,最小是5s。
(2)Appenders節點,常見的有三種子節點:Console、File、RollingFile
Console節點用來定義輸出到控制檯的Appender.File節點用來定義輸出到指定位置的檔案的Appender.RollingFile節點用來定義超過指定大小自動刪除舊的建立新的的Appender.
通過在子節點中加入<PatternLayout pattern="自定義資訊格式"/>進行日誌佈局
%c 輸出所屬類的全名,可寫為 %c{Num} ,Num類名輸出的範圍 如:"com.sun.aaa.classB",%C{2}將使日誌輸出輸出範圍為:aaa.classB%d 輸出日誌時間其格式為 可指定格式 如 %d{HH:mm:ss}等%l 輸出日誌事件發生位置,包括類目名、發生執行緒,在程式碼中的行數%n 換行符%m 輸出程式碼指定資訊,如info(“message”),輸出message%p 輸出日誌的優先順序,即 FATAL ,ERROR 等%r 輸出從啟動到顯示該條日誌資訊所耗費的時間(毫秒數)%t 輸出產生該日誌事件的執行緒名
(3)Loggers節點,常見的有兩種:Root和Logger.
Root節點用來指定專案的根日誌,如果沒有單獨指定Logger,那麼就會預設使用該Root日誌輸出
Logger節點用來單獨指定日誌的形式,比如要為指定包下的class指定不同的日誌級別等。
5.日誌的級別
我們現在要呼叫logger的方法,不過在這個Logger物件中,有很多方法,所以要先了解log4j的日誌級別,log4j規定了預設的幾個級別:trace<debug<info<warn<error<fatal等。這裡要說明一下:
級別之間是包含的關係,意思是如果你設定日誌級別是trace,則大於等於這個級別的日誌都會輸出。
基本上預設的級別沒多大區別,就是一個預設的設定。你可以通過它的API自己定義級別。你也可以隨意呼叫這些方法,不過你要在配置檔案裡面好好處理了,否則就起不到日誌的作用了,而且也不易讀,相當於一個規範,你要完全定義一套也可以,不用沒多大必要。
這不同的級別的含義大家都很容易理解,這裡就簡單介紹一下:
trace:是追蹤,就是程式推進以下,你就可以寫個trace輸出,所以trace應該會特別多,不過沒關係,我們可以設定最低日誌級別不讓他輸出。
debug:除錯麼,我一般就只用這個作為最低級別,trace壓根不用。是在沒辦法就用eclipse或者idea的debug功能就好了麼。
info:輸出一下你感興趣的或者重要的資訊,這個用的最多了。
warn:有些資訊不是錯誤資訊,但是也要給程式設計師的一些提示,類似於eclipse中程式碼的驗證不是有error 和warn(不算錯誤但是也請注意,比如以下depressed的方法)。
error:錯誤資訊。用的也比較多。
fatal:級別比較高了。重大錯誤,這種級別你可以直接停止程式了,是不應該出現的錯誤麼!不用那麼緊張,其實就是一個程度的問題。
6.環境準備
6.1準備工作
1.下載地址:https://logging.apache.org/log4j/2.x/download.html 巨集哥可以通過下載地址下載最新版本是2.17.2。如下圖所示:
2.去官方下載log4j 2,匯入jar包,基本上你只需要匯入下面兩個jar包就可以了(xx是亂七八糟的版本號):
(1)log4j-core-xx.jar
(2)log4j-api-xx.jar
下載好了之後,將jar包新增到Eclipse專案的lib中去。如下圖所示:
到此準備工作已經完成了,下邊巨集哥開始實戰!
7.專案實戰
7.1開始使用
我們知道,要在某個類中使用log4j記錄日誌,只需要申明下面的成員變數(其實不一定要是成員變數,只是為了方便呼叫而已)
private static Logger logger = LogManager.getLogger(MyApp.class.getName());
這裡getLogger有一個引數指定的是這個logger的名稱,這個名稱在配置檔案裡面可是有需要的,這個待會兒再說。
聲明瞭Logger物件,我們就可以在程式碼中使用他了。
7.2程式碼設計
1.在這裡巨集哥隨便寫個測試類,呼叫就是這麼簡單,log4j的核心在配置檔案上。如下圖所示:
2.如果沒有自定義配置檔案,上面這個類在寫一個main方法,呼叫測試類的方法。就可以執行程式碼測試你寫的測試類。如下圖所示:
7.3參考程式碼
import org.apache.logging.log4j.Level; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; /** * @author 北京-巨集哥 * * @公眾號:北京巨集哥 * * 《手把手教你》系列基礎篇(八十六)-java+ selenium自動化測試-框架設計基礎-Log4j 2實現日誌輸出(詳解教程) * * 2022年3月24日 */ public class Test { static Logger logger = LogManager.getLogger(Test.class.getName()); public boolean hello() { logger.entry(); // trace級別的資訊,單獨列出來是希望你在某個方法或者程式邏輯開始的時候呼叫,和logger.trace("entry")基本一個意思 logger.error("Did it again!"); // error級別的資訊,引數就是你輸出的資訊 logger.info("我是info資訊"); // info級別的資訊 logger.debug("我是debug資訊"); logger.warn("我是warn資訊"); logger.fatal("我是fatal資訊"); logger.log(Level.DEBUG, "我是debug資訊"); // 這個就是制定Level型別的呼叫:誰閒著沒事呼叫這個,也不一定哦! logger.exit(); // 和entry()對應的結束方法,和logger.trace("exit");一個意思 return false; } public static void main(String[] args) { Test t = new Test(); t.hello(); } }
7.4執行程式碼
1.執行程式碼,右鍵Run AS->Java Appliance,控制檯輸出,如下圖所示:
從上圖可以看到,只有>=ERROR的日誌輸出來了(這是因為Log4j有一個預設的配置,它的日誌級別是ERROR,輸出只有控制檯)。
7.5定義日誌級別
1.巨集哥自己新建一個xml檔案放在SRC目錄下,即根目錄下。命令為log4j2.xml,定義好了日誌,把日誌級別改成了TRACE,如下圖所示:
2.參考XML:
<?xml version="1.0" encoding="UTF-8"?> <configuration status="OFF"> <appenders> <Console name="Console" target="SYSTEM_OUT"> <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/> </Console> </appenders> <loggers> <root level="TRACE"> <appender-ref ref="Console"/> </root> </loggers> </configuration>
3.再次執行程式碼,控制檯輸出如下圖所示:
從上邊的xml檔案可以看到巨集哥把configuration>loggers>root的level屬性改為trace,就可以輸出剛才寫的所有資訊了。
8.外部引用xml配置檔案
8.1程式碼設計
8.2參考程式碼
package testSuites;
import java.io.File;
import java.io.FileInputStream;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.config.ConfigurationSource;
import org.apache.logging.log4j.core.config.Configurator;
/**
* @author 北京-巨集哥
*
* @公眾號:北京巨集哥
*
* 《手把手教你》系列基礎篇(八十六)-java+ selenium自動化測試-框架設計基礎-Log4j2實現日誌輸出(詳解教程)
*
* 2022年3月27日
*/
public class ConfigTest {
private static Logger logger = LogManager.getLogger(ConfigTest.class);
/**
* log4j 2讀取配置檔案
* log4j 2讀取的配置檔案可以分為三類:src下的配置檔案、絕對路徑的配置檔案、相對路徑的配置檔案
*/
//第一類 載入src下的配置檔案
public static void test0(){
//src下的配置檔案會預設的被log4j的框架載入,我們就不顯示的載入了
//直接測試
logger.info("我列印了.......");
//輸出內容
//11:06:16.957 [main] INFO testSuites.ConfigTest - 我列印了.......
}
//第二類 絕對路徑的配置檔案
public static void test1(){
//我們將log4j2.xml放在D盤下
//這是需要手動的載入
//絕對路徑配置檔案
ConfigurationSource source;
try {
//方法1 使用 public ConfigurationSource(InputStream stream) throws IOException 建構函式
source = new ConfigurationSource(new FileInputStream("F:\\workspace\\Bjhg_Selenium\\log4j2.xml"));
//方法2 使用 public ConfigurationSource(InputStream stream, File file)建構函式
File config=new File("F:\\workspace\\Bjhg_Selenium\\log4j2.xml");
source = new ConfigurationSource(new FileInputStream(config),config);
//方法3 使用 public ConfigurationSource(InputStream stream, URL url) 建構函式
String path="F:\\workspace\\Bjhg_Selenium\\log4j2.xml";
source = new ConfigurationSource(new FileInputStream(path),new File(path).toURL());
//source.setFile(new File("D:\log4j2.xml"));
//source.setInputStream(new FileInputStream("D:\log4j2.xml"));
Configurator.initialize(null, source);
Logger logger = LogManager.getLogger(ConfigTest.class.getName());
logger.trace("trace...");
logger.debug("debug...");
logger.info("info...");
logger.warn("warn...");
logger.error("error...");
logger.fatal("fatal...");
//一下是執行效果
/*11:57:38.457 [main] ERROR testSuites.ConfigTest - error...
11:57:38.461 [main] FATAL testSuites.ConfigTest - fatal...*/
} catch (Exception e) {
e.printStackTrace();
}
}
//第三類 相對路徑的配置檔案載入
public static void test2(){
//這裡需要注意路徑中不要出現中文和空格,如果存在中文,請使用url轉碼
ConfigurationSource source;
try {
//方法1 使用System.getProperty
String config=System.getProperty("user.dir");
source = new ConfigurationSource(new FileInputStream(config+"/log4j2.xml"));
Configurator.initialize(null, source);
Logger logger = LogManager.getLogger(ConfigTest.class.getName());
logger.trace("trace...");
logger.debug("debug...");
logger.info("info...");
logger.warn("warn...");
logger.error("error...");
logger.fatal("fatal...");
//輸出內容
/*11:57:38.457 [main] ERROR testSuites.ConfigTest - error...
11:57:38.461 [main] FATAL testSuites.ConfigTest - fatal...*/
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
//test0();
//test1();
test2();
}
}
8.3執行程式碼
1.執行程式碼,右鍵Run AS->Java Appliance,控制檯輸出,如下圖所示:
9.小結
好了,時間也不早了,今天就分享和講解到這裡,希望對您有所幫助,感謝您耐心地閱讀!