我們首先學(xué)習(xí)了Spring的兩個(gè)核心技術(shù):IOC和AOP,然后為滿足真實(shí)的項(xiàng)目需求我們又學(xué)習(xí)了Spring的基礎(chǔ)JDBC操作以及如何再Spring框架下整合mybatis數(shù)據(jù)持久化框架。到目前為止我們已經(jīng)可以完成簡單的Spring后臺(tái)項(xiàng)目開發(fā)工作。但是在實(shí)際的項(xiàng)目中,為了方便調(diào)試和追蹤問題,我們往往需要打印日志信息來幫助我們發(fā)現(xiàn)和追蹤問題。因此,為完善項(xiàng)目實(shí)際開發(fā)能力,本文我們主要學(xué)習(xí)在Spring框架中如何引入目前流行的日志框架Log4J2。
一、Log4j2簡介
Log4J2是Log4j 1.x的升級(jí)版版,在Log4j 1.x的基礎(chǔ)上有顯著的改進(jìn),并且提供了Logback中許多i可用的功能,同時(shí)也修復(fù)了一些Logback上的一些固有的問題。
二、引入Log4j2的jar包依賴
官網(wǎng)文檔指出,如果需要依賴Log4j2需要依賴log4j-api
、log4j-core
兩個(gè)jar包,因此我們?cè)趃radle.build文件中添加如下依賴:
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.11'
compile 'org.apache.logging.log4j:log4j-api:2.8.1'
compile 'org.apache.logging.log4j:log4j-core:2.8.1'
}
log4j-api
和log4j-core
的依賴版本我們都選擇2.8.1
,在命令行下運(yùn)行如下命令,gradle會(huì)自動(dòng)完成依賴解析。
gradle build
三、Hello-log4j2
在將log4j2整合到Spring之前我們先完成一個(gè)使用log4j2最簡單的例子:hello-log4j2。
首先創(chuàng)建主java運(yùn)行程序:
public class Application {
private static final Logger logger = LogManager.getLogger(Application.class);
public static void main(String[] args){
logger.info("Hello, Log4j2!");
}
}
這個(gè)例子很簡單,我們定義了類Application
并為其定義靜態(tài)常量logger
,其使用LogManager進(jìn)行實(shí)例化,并獲取一個(gè)命名的logger對(duì)象。在main方法中,我們直接使用logger.info輸出“Hello,Log4j2”信息。
Tip : Log4j2 將日志級(jí)別分為8個(gè)級(jí)別:All < Trace < Debug < Info < Warn < Error < Fatal < OFF,級(jí)別越高打印的日志越少,Logger也提供了相應(yīng)的方法對(duì)應(yīng)相應(yīng)的日志級(jí)別。
Log4j2提供XML、JSON、YAML和properties格式進(jìn)行配置,我們這里主要以XML配置方式進(jìn)行學(xué)習(xí),如果想了解更多的配置方式,讀者可自動(dòng)查看官網(wǎng)文檔。
log4j2.xml配置,該文件需在classpath路徑下,log4j2會(huì)自動(dòng)進(jìn)行加載解析:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<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="debug">
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
如上我們定義了最簡單的log4j2配置文件,我們對(duì)該文件中的元素標(biāo)簽進(jìn)行簡單介紹:
Configuration 標(biāo)簽
log4j的所有配置信息需要包含在該標(biāo)簽下,這里我們用到了status
屬性,它用于指定log4j內(nèi)部日志信息打印級(jí)別,這里我們?cè)O(shè)置為WARN
,它同時(shí)可被設(shè)置為如下數(shù)值:trace
、debug
、info
、error
,共5種不同級(jí)別。同時(shí)該標(biāo)簽下可包含<Appenders>
和<Loggers>
標(biāo)簽,<Appenders>
用于定義日志信息所傳輸(寫入)的目標(biāo)地,當(dāng)然它還會(huì)定義輸出格式等信息;<Loggers>
關(guān)聯(lián)一個(gè)具體的Appender
,上面的配置文件關(guān)聯(lián)的名為“Console”的Appender
,Loggers
內(nèi)部可定義<Root>
和<Logger>
,統(tǒng)稱為Logger,其中Root為所有Logger的父親,當(dāng)代碼中定義的Logger沒有對(duì)應(yīng)匹配的<Logger>
時(shí)則會(huì)直接使用Root的配置信息。
Appenders 標(biāo)簽
該標(biāo)簽下定義所有的Appender,其中常見的為Console
、File
、RollingFile
......,這里我們使用Console標(biāo)簽定義一個(gè)中斷輸出,其中target可設(shè)置為"SYSTEM_OUT"或者“SYSTEM_ERR”,一般設(shè)置為“SYSTEM_OUT”且默認(rèn)為該值。這里我們使用<PatternLayout>
來設(shè)置了日志輸出格式。每個(gè)Appender提供了豐富的屬性或標(biāo)簽進(jìn)行設(shè)置相應(yīng)的輸出結(jié)果,使得我們可以在不改變?cè)创a的情況下,對(duì)日志輸出進(jìn)行靈活改動(dòng)。詳細(xì)學(xué)習(xí)該標(biāo)簽下屬性的設(shè)置超出了本文的范圍,我們會(huì)放在后面進(jìn)行學(xué)習(xí)。
Loggers 標(biāo)簽
該標(biāo)簽下定義所有的Logger,用來關(guān)聯(lián)代碼中定義的Logger和Appender。該標(biāo)簽下包含兩種標(biāo)簽:<Root>
和<Logger>
。Root為所有Logger的根(父親),所有的Logger自動(dòng)繼承Root的配置信息。我們使用level來設(shè)置該Logger輸出的日志級(jí)別。并且使用?<AppenderRef>
來關(guān)聯(lián)一個(gè)前面定義好的Appender。
完成以上配置后運(yùn)行代碼我們會(huì)在控制臺(tái)看到如信息:
17:54:29.921 [main] INFO com.liangwei.learnspring.Application - Hello, Log4j2!
如上,我們記錄了時(shí)間、方法名、日志級(jí)別、類名、輸出信息。
三、Spring整合Log4j2
Spring強(qiáng)制依賴commons-logging
jar包,該jar包由spring-core
間接引入。commons-logging
是JCL(Jakarta Commons Logging API)的一種典型實(shí)現(xiàn),Spring的框架日志信息都是使用JCL標(biāo)準(zhǔn)接口來進(jìn)行輸出的,如果我們想將Spring的框架日志輸出按照log4j的配置方式進(jìn)行輸出,我們需要完成JCL-log4j之間的映射,而log4j為我們提供了相關(guān)依賴jar包。為完成Spring框架整合Log4j日志框架,我們只需要增加如下依賴信息:
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.11'
compile 'org.apache.logging.log4j:log4j-api:2.8.1'
compile 'org.apache.logging.log4j:log4j-core:2.8.1'
compile 'org.apache.logging.log4j:log4j-jcl:2.8.1'
compile 'org.springframework:spring-context:4.3.6.RELEASE'
}
如上,我們?cè)黾恿?code>compile 'org.apache.logging.log4j:log4j-jcl:2.8.1'配置信息,增加了log4j-jcl的jar包。接下來我們需要修改log4j2.xml文件,來完成Spring框架日志文件的輸出:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
</Appenders>
<Loggers>
<Logger name="org.springframework.beans.factory" level="DEBUG"/>
<Root level="debug">
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
如上,我們定義了一個(gè)名為org.springframework.beans.factory
的Logger,該Logger的日志級(jí)別為DEBUG,這樣Spring 框架內(nèi)的DEBUG以上級(jí)別的日志信息會(huì)被輸出,由于該Logger并沒有定義AppenderRef信息,因此它自動(dòng)集成Root設(shè)置的Console,該信息會(huì)被輸出到控制臺(tái)。
我們?cè)谠创aApplication.java中增加Spring加載啟動(dòng)代碼:
public class Application {
private static final Logger logger = LogManager.getLogger(Application.class);
public static void main(String[] args){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("dao.xml");
logger.info("Hello, Log4j2!");
}
}
重新運(yùn)行程序,我們將在控制臺(tái)看到如下信息:
19:06:24.314 [main] DEBUG org.springframework.core.env.StandardEnvironment - Adding [systemProperties] PropertySource with lowest search precedence
19:06:24.318 [main] DEBUG org.springframework.core.env.StandardEnvironment - Adding [systemEnvironment] PropertySource with lowest search precedence
19:06:24.319 [main] DEBUG org.springframework.core.env.StandardEnvironment - Initialized StandardEnvironment with PropertySources [systemProperties,systemEnvironment]
...... ......
19:06:25.073 [main] INFO com.liangwei.learnspring.Application - Hello, Log4j2!
為保持簡潔,省略了大部分Spring框架啟動(dòng)時(shí)的信息,讀者可自行下載代碼進(jìn)行運(yùn)行查看。
四、總結(jié)
本文我們將log4j2引入Spring框架,我們通過最簡單的Hello-log4j程序?qū)W習(xí)了Log4j2日志框架配置方式:1. 使用LogManager定義Logger;2,配置log4j2.xml文件。最后我們通過增加jar包依賴和配置關(guān)于Spring框架日志的Logger將Spring框架日志信息通過Log4j日志框架進(jìn)行輸出,至此,我們已完成將log4j2引入Spring的工作。
當(dāng)然,本文并沒有詳細(xì)學(xué)習(xí)log4j2.xml文件的配置以及配置文件中各標(biāo)簽的用法,這超出簡單將log4j2引入Spring框架的目的以及本系列文章學(xué)習(xí)Spring知識(shí)的初衷,關(guān)于log4j的學(xué)習(xí),后面有機(jī)會(huì)會(huì)專門開辟系列文章進(jìn)行共同學(xué)習(xí)。
本文實(shí)例代碼地址