?我的博客:蘭陵笑笑生,歡迎瀏覽博客!
?上一章 SpringBoot入門實(shí)踐(四)-RESTFUL API 最佳設(shè)計(jì)當(dāng)中,我們介紹了在SpringBoot項(xiàng)目中如何規(guī)范的使用RESTful風(fēng)格的API证鸥,镰官。本章簡(jiǎn)單介紹一下常用的開(kāi)源日志框架。
前言
?日志是程序設(shè)計(jì)中很重要的一部分孟岛,當(dāng)然在我剛接觸編程的時(shí)候扑庞,是不怎么在意的氏淑,正好有空歸納總結(jié)一下兵琳。
? 在JDK1.4版本之后才有JDK Logger狂秘,不過(guò)JDK的日志太雞肋,這里不過(guò)多介紹躯肌,開(kāi)源社區(qū)當(dāng)中應(yīng)用比較廣泛的是Apache Commons Logging和Apache Log4j 者春,Apache Commons Logging是通用的日志API ,Apache Log4j才是很流行的日志實(shí)現(xiàn)清女。后來(lái)Slf4j和Logback取代了Apache Commons Logging和Apache Log4j 钱烟。
一、Apache Commons Logging
-
簡(jiǎn)介:
? Apache Commons Logging 提供了日志的接口嫡丙,具體的實(shí)現(xiàn)根據(jù)配置動(dòng)態(tài)調(diào)整拴袭,它的出現(xiàn)避免了和具體日志實(shí)現(xiàn)框架的直接耦合,在日常開(kāi)發(fā)中曙博,可以選擇第三方的日志:’
-
使用方式
pom.xml引入
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.1</version>
</dependency>
package test;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.Test;
public class CommonLogDemo {
private Log log=LogFactory.getLog(CommonLogDemo.class);
@Test
public void test(){
log.debug("debug .....");
log.info("info .....");
log.warn("warn .....");
log.error("error .....");
log.fatal("fatal .....");
}
}
resource目錄下添加commons-logging.properties拥刻,如果單純的使用commons-logging,默認(rèn)的日志對(duì)象就是Jdk14Logger父泳,工廠就是LogFactoryImpl
#指定日志對(duì)象
org.apache.commons.logging.Log=org.apache.commons.logging.impl.Jdk14Logger
#指定工廠
org.apache.commons.logging.LogFactory=org.apache.commons.logging.impl.LogFactoryImpl
二般哼、Apache Log4j
-
簡(jiǎn)介
? Log4j是java編寫(xiě)的可靠的、靈活的日志框架惠窄,通過(guò)使用Log4j 我們能夠方便的記錄日志蒸眠,不但弄控制日志的輸出,還能控制日志的輸出格式:
日志級(jí)別:
ALL杆融、 DEBUG 楞卡、INFO 、WARN脾歇、 ERROR蒋腮、 FATAL 、OFF
Appender :
日志的輸出地方
常用的包括
- ConsoleAppender控制臺(tái)
- FileAppender 文件
- RollingFileAppender 滾動(dòng)
- DailyRollingFileAppender
當(dāng)然還可以寫(xiě)入數(shù)據(jù)庫(kù)介劫,異步打印等等高級(jí)功能徽惋。
Layout
格式化
HTMLLayout XML形式輸出
PatternLayout 使用自定義的格式輸出
SimpleLayout 只包含日志信息的級(jí)別和信息字符串
TTCCLayout 包括時(shí)間、線程座韵,類別等
一般用都是自定義用的比較多PatternLayout
-
使用方式
public class LoggerDemo {
org.apache.log4j.Logger log= org.apache.log4j.Logger.getLogger(LoggerDemo.class); @Test
public void test(){
log.trace("trace log ...");
log.debug("debug log ...");
log.info("info log ...");
log.warn("warn log ...");
log.error("error log ...");
}
}
在resource目錄下添加log4j.properties或者log4j.xml log4j會(huì)自動(dòng)解析
log4j.properties
log4j.rootLogger=INFO, FILE,CONSOLE
#配置輸出到控制臺(tái)#1 ConsoleAppender控制臺(tái) 2FileAppender 文件 3 RollingFileAppender 滾動(dòng) 4 DailyRollingFileAppender
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.Target=System.out
log4j.appender.CONSOLE.ImmediateFlush=truelog4j.appender.CONSOLE.Threshold=DEBUG
#layout對(duì)日志格式化# 1自定義格式险绘,PatternLayout2
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.encoding=UTF-8
##格式 : %時(shí)間 [%線程] %log級(jí)別 %完整類名 - %消息 %換行
#%d 輸出日志時(shí)間點(diǎn)的日期或時(shí)間,默認(rèn)格式為ISO8601誉碴,也可以在其后指定格式宦棺,比如:%d{yyyy MMM dd
#HH:mm:ss,SSS},輸出類似:2002年10月18日 22:10:28黔帕,921
#%p 輸出優(yōu)先級(jí)代咸,即DEBUG,INFO成黄,WARN呐芥,ERROR逻杖,F(xiàn)ATAL#%l 輸出日志事件的發(fā)生位置,包括類目名思瘟、發(fā)生的線程荸百,以及在代碼中的行數(shù)
#%c 輸出所屬的類目,通常就是所在類的全名
#%L 代碼中的行數(shù)滨攻。
#%m 輸出代碼中指定的消息
# 輸出一個(gè)回車換行符够话,Windows平臺(tái)為“rn”,Unix平臺(tái)為“n”
log4j.appender.CONSOLE.layout.conversionPattern=%d{ABSOLUTE} %5p %c{1}:%L- %m%n
#配置輸出到文件
log4j.appender.FILE=org.apache.log4j.FileAppender
log4j.appender.FILE.File=D:\\log\\log.log
log4j.appender.FILE.ImmediateFlush=truelog4j.appender.FILE.Threshold=DEBUGlog4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.encoding=UTF-8
log4j.appender.FILE.layout.conversionPattern=%d{ABSOLUTE} %5p %c{1}:%L- %m%n
-
Log4j的鎖和性能優(yōu)化
? ?通常來(lái)說(shuō)光绕,打日志總比不打印日志要好女嘲,產(chǎn)生問(wèn)題是有據(jù)可查,但是存在太多的日志诞帐,會(huì)使服務(wù)性能下降欣尼。,Log4J默認(rèn)的Apperders使用同步的鎖來(lái)實(shí)現(xiàn)景埃。
日志事件異步打印
可以使用Log4j 的 AsyncAppender來(lái)實(shí)現(xiàn)異步打印媒至,
-
springBoot修改底層日志為log4j
第一步:添加springBoot的log4j依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j</artifactId>
<version>1.3.8.RELEASE</version>
</dependency>
第二步 :排除springBoot默認(rèn)的logging
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
第三步:resourece目錄下添加log4j.properties文件或者log4j.xml
三、Slf4j(Simple Logging Facade for Java)
-
簡(jiǎn)介
?和Apache Commons Logging谷徙,使用門面模式對(duì)外提供統(tǒng)一的接口拒啰,應(yīng)用程序只依賴于Slf4j來(lái)實(shí)現(xiàn)打印日志,
具體的日志實(shí)現(xiàn)由配置來(lái)決定使用Log4j還是Logback完慧,在不改變應(yīng)用代碼前提下谋旦,切換底層的日志實(shí)現(xiàn)。
springBoot就是實(shí)現(xiàn)了這種方式屈尼,底層使用slf4j+logback的方式進(jìn)行日志記錄 :
?Slf4j任然使用了門面模式册着,相對(duì)于Commons Logging做了一些優(yōu)化,它在編譯的時(shí)候確定底層的實(shí)現(xiàn)脾歧,而不是通過(guò)配置文件動(dòng)態(tài)的狀態(tài)底層的實(shí)現(xiàn)甲捏。,所以只要底層的日志實(shí)現(xiàn)的jar包和Slf4j的靜態(tài)編譯轉(zhuǎn)換包在類路徑下即可鞭执。
?從圖上我們可以看到Slf4j的實(shí)現(xiàn)結(jié)構(gòu)司顿,除了Logger和LoggerFactory還有一個(gè)LoggerFactoryBinder,主要是實(shí)現(xiàn)轉(zhuǎn)接器兄纺。
?什么意思呢大溜,就是Slf4j對(duì)每一種日志實(shí)現(xiàn)的框架都提供了一個(gè)轉(zhuǎn)換的Jar包,這個(gè)Jar包包含了LoggerFactoryBinder接口的實(shí)現(xiàn)估脆,比如:Logback轉(zhuǎn)接的Jar包就是logback-classic-1.0.13.jar钦奋,提供了LoggerFactoryBinder的實(shí)現(xiàn)
-
SLF4J對(duì)不同日志的轉(zhuǎn)接包
-
在springBoot中
底層使用slf4j+logback的方式進(jìn)行日志記錄
其他日志會(huì)轉(zhuǎn)換成slf4j
看看spring-boot-start-logging的依賴
springBoot當(dāng)中的spring-boot-start-logging默認(rèn)引入
四、Logback
-
簡(jiǎn)介
?Logback是由Log4j的創(chuàng)始人設(shè)計(jì)的另一個(gè)日志組件,它也是目前首選的主流日志記錄工具付材。
我們所學(xué)習(xí)的springBoot就是默認(rèn)使用Locback+Slf4j朦拖。
logback 分為3個(gè)部分
logback-core:是以下2個(gè)模塊的基礎(chǔ),包括日志的實(shí)現(xiàn)
logback-classic :是Log4j的改良版本厌衔,在性能方面有較大的提高贞谓,并實(shí)現(xiàn)了上文說(shuō)到的接口。
logback-access:與Servlet集成葵诈,提供了豐富的Http訪問(wèn)日志功能
-
logback-classic結(jié)構(gòu):
-
使用方式
package test;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class LogbackDemo {
Logger logger = LoggerFactory.getLogger(LogbackDemo.class);
@Test
public void Loback() {
logger.debug("debug ..."
);
logger.info("info ...");
logger.error("info ...");
logger.warn("info ...");
}
}
在resource目錄下添加logback.xml配置
<?xml version="1.0" encoding="UTF-8"?><configuration>
<!-- <include resource="org/springframework/boot/logging/logback/base.xml"/> -->
<!--自定義的pattern屬性-->
<property name="pattern"
value="%d{HH:mm:ss.SSS} [%-5level] [%thread] [%logger] %msg%n "/>
<!--控制臺(tái)輸出-->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${pattern}</pattern>
<charset>GBK</charset>
</encoder>
</appender>
<!--滾動(dòng)記錄日志-->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!--當(dāng)前生成的日志文件名稱-->
<file>D:\\log\\logback.out</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!--根據(jù)時(shí)間記錄日志-->
<fileNamePattern>test-log-%d{yyyy-MM-dd}.log</fileNamePattern>
<!--歸檔日志30天-->
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${pattern}</pattern>
<charset>GBK</charset>
</encoder>
</appender>
<logger name="org.springframework.web" level="INFO"/>
<!--根root logger 配置-->
<logger name="test" level="DEBUG">
<appender-ref ref="STDOUT"/>
<appender-ref ref="FILE"/>
</logger>
</configuration>
Logback相對(duì)于Log4j的最大提升是效率,在關(guān)鍵的執(zhí)行路徑上性能提升了至少10倍祟同。同步記錄日志大概是1.5萬(wàn)/s的吞吐量作喘。
五、總結(jié)
?以上就是本期的分享晕城,你還可以關(guān)注本博客的#Spring Boot入門實(shí)踐系列!#
本文由博客一文多發(fā)平臺(tái) OpenWrite 發(fā)布泞坦!