前言
本文使用的項目代碼魏颓,是基于之前文章使用的Spring Boot項目:
日志系統(tǒng)分為兩部分察纯,一部分是日志抽象層林螃,一部分是日志實現(xiàn)層评也。
常見日志抽象層:
- JCL
- SLF4J
- JBoss-Logging
常見日志實現(xiàn)層有:
- logback
- log4j
- log4j2
- JUL
每種Logger都可以通過配置使用控制臺或者文件輸出日志內(nèi)容枕磁,logback是log4j框架的作者開發(fā)的新一代日志框架呐粘,它效率更高十偶、能夠適應諸多的運行環(huán)境热某,同時天然支持slf4j鲜锚,而Spring Boot 默認使用slf4j + logback作為日志系統(tǒng),廣泛應用于Spring Boot項目苫拍。今天我們就一起來學學如何使用slf4j + logback日志系統(tǒng)。
整合logback日志步驟
1. 添加依賴绒极?
2. 創(chuàng)建日志配置文件骏令;
3. 編寫日志配置文件;
4. 日志配置文件介紹垄提;
5. 日志實例榔袋;
6. 日志效果。
1. 添加依賴?
如果要使用logback铡俐,原則上是需要添加dependency依賴的凰兑,但也如前言所說,logback是Spring Boot 默認的日志實現(xiàn)層审丘,因此只要項目中只要有使用了spring-boot-starter或者spring-boot-starter-web依賴吏够,默認已經(jīng)包含logback的相關依賴:
#無需再次引用以下logback依賴:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</dependency>
2. 創(chuàng)建日志配置文件;
在項目src/main/resources底下創(chuàng)建日志配置文件滩报,如:logback-spring.xml;
注意:能夠被Spring Boot自動識別的logback日志配置文件名:logback-spring.xml, logback-spring.groovy, logback.xml, logback.groovy锅知。
如果換成其他名字,如logging-config.xml脓钾,那么需要在application.properties文件內(nèi)額外指定文件名售睹,如:
logging.config=classpath:logging-config.xml
官方推薦優(yōu)先使用帶有“-spring”文件名的文件作為日志配置文件,這樣Spring Boot會為它添加一些Spring Boot特有的配置項可训。
3. 編寫日志配置文件昌妹;
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<contextName>logback</contextName>
<!-- 定義日志的根目錄 -->
<property name="LOG_PATH" value="logs"/>
<property name="LOG_ARCHIVE" value="${LOG_PATH}/archive"/>
<!--輸出到控制臺,即:ConsoleAppender-->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter>
<withJansi>true</withJansi>
<encoder>
<!--格式化輸出:
%d:表示日期
%thread:表示線程名
%-5level:級別從左顯示5個字符寬度
%msg:日志消息
%n:是換行符-->
<pattern>%red([%d{yyyy-MM-dd HH:mm:ss}]) %green([ %thread ]) %highlight([ %-5level ]) %boldMagenta([ %logger ]) - %cyan(%msg%n)
</pattern>
<charset>GBK</charset>
</encoder>
<!--日志過濾器握截,如配置則只有被配置的類型才會被記錄下來-->
<!--<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>-->
</appender>
<!--輸出到文件飞崖,即:RollingFileAppender-->
<appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
<File>${LOG_PATH}/current.log</File>
<!--TimeBasedRollingPolicy: 最常用的滾動策略,它根據(jù)時間來制定滾動策略-->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_ARCHIVE}/app.%d.%i.log.gz</fileNamePattern>
<maxHistory>30</maxHistory>
<totalSizeCap>20GB</totalSizeCap>
<timeBasedFileNamingAndTriggeringPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<!--文件達到最大10MB時會被壓縮和切割-->
<maxFileSize>10MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<encoder>
<pattern>[%d{yyyy-MM-dd HH:mm:ss}] [ %thread ] [ %-5level ] [ %logger ] - %msg%n</pattern>
<charset>GBK</charset>M
</encoder>
</appender>
<root level="info">
<appender-ref ref="console"/>
<appender-ref ref="file"/>
</root>
<logger name="com.mycompany.sample.service.LeadService" level="warn">
<appender-ref ref="file"/>
</logger>
</configuration>
4. 日志配置文件介紹川蒙;
1. <property>節(jié)點:
用于定義變量蚜厉,方便使用。有兩個屬性:name,value畜眨。<property>有兩個屬性:name昼牛、value术瓮,定義變量后,可以使用${}來使用變量贰健,如:
-
聲明變量:
<property name="LOG_PATH" value="logs"/>
<property name="LOG_ARCHIVE" value="${LOG_PATH}/archive"/>
-
使用變量:
<File>${LOG_PATH}/current.log</File>
...
<fileNamePattern>${LOG_ARCHIVE}/app.%d.%i.log.gz</fileNamePattern>
2. <appender>節(jié)點:
用來格式化日志輸出的節(jié)點胞四,<appender>有兩個屬性: name、class伶椿,name用于給該 appender 命名辜伟,class用于指定輸出策略,通常有兩種:
-
控制臺輸出:
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
...
</appender>
-
文件輸出:
<appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
...
</appender>
3. <filter>子節(jié)點:
<filter>日志過濾器或叫過濾策略脊另,在此之前导狡,我們需要先了解一些基礎知識:
過濾器的返回值只能是ACCEPT、DENY和NEUTRAL的其中一個:
- 如果返回DENY偎痛,那么記錄事件立即被拋棄旱捧,不再經(jīng)過剩余過濾器;
- 如果返回NEUTRAL踩麦,那么有序列表里的下一個過濾器會接著處理記錄事件枚赡,下一個過濾器會繼續(xù)執(zhí)行過濾,如無其他過濾器谓谦,則記錄日志贫橙;
- 如果返回ACCEPT,那么記錄事件被立即處理反粥,不再經(jīng)過剩余過濾器卢肃。
日志級別由低到高: trace < debug < info < warm < error
常見過濾策略有:
-
ThresholdFilter: 臨界值過濾器。
過濾掉低于指定臨界值的日志星压,當日志級別等于或高于臨界值時践剂,過濾器返回NEUTRAL;當日志級別低于臨界值時娜膘,日志會被拒絕,即不記錄优质。
例如竣贪,過濾掉所有低于INFO級別的日志:
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter>
-
LevelFilter:級別過濾器。
根據(jù)日志級別進行過濾巩螃。如果日志級別等于配置級別演怎,過濾器會根據(jù)onMath 和 onMismatch接收或拒絕日志。
例如避乏,當且僅當日志級別為ERROR時記錄日志爷耀,否則不記錄:
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
-
EvaluatorFilter:求值過濾器。
求值過濾器拍皮,評估歹叮、鑒別日志是否符合指定條件跑杭。需要額外的兩個JAR包,commons-compiler.jar和janino.jar咆耿,我也沒有嘗試德谅,此處不做介紹。
4. <encoder>子節(jié)點:
用于設置日志格式化策略萨螺、字體等窄做。
5. <rollingPolicy>子節(jié)點:
用于設置滾動策略,所謂的滾動慰技,即自動停止在當前日志文件中打印日志椭盏,同時自動啟用新的日志文件進行記錄,我們可以設置一定的策略吻商,使得這樣的過程在滿足該策略條件時掏颊,自動發(fā)生滾動操作。
最常用的滾動策略是TimeBasedRollingPolicy手报,它根據(jù)時間來制定滾動策略蚯舱,如:
# 日志最多保留30天,且總保存量為20GB;
# 當文件達到10MB時掩蛤,會進行壓縮和切割滾;
# 舊log以${log.path}/app.%d.%i.log.gz文件路徑滾動枉昏,如:logs/app.2020-08-10.0.log.gz,app.2020-08-10.1.log.gz;
# 新生成的日志文件一直還是logs/current.log揍鸟。
<File>${LOG_PATH}/current.log</File>
<!--TimeBasedRollingPolicy: 最常用的滾動策略兄裂,它根據(jù)時間來制定滾動策略-->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${LOG_ARCHIVE}/app.%d.%i.log.gz</fileNamePattern>
<maxHistory>30</maxHistory>
<totalSizeCap>20GB</totalSizeCap>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<!--文件達到最大10MB時會被壓縮和切割-->
<maxFileSize>10MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
滾動實例如:
6. <root>節(jié)點:
root節(jié)點是必選節(jié)點,用來指定最基礎的日志輸出級別阳藻,如:
#低于warn(大小寫均可)級別的日志晰奖,將不被記錄。
<root level="warn">
<appender-ref ref="console"/>
<appender-ref ref="file"/>
</root>
7. <logger>節(jié)點:
logger節(jié)點用于單獨對某個類進行日志策略定制腥泥,如:
#對于com.mycompany.sample.service.LeadService類匾南,最低紀錄日志界別為warn,記錄類型為文件型蛔外,低于warn級別的日志將不被記錄蛆楞。
<logger name="com.mycompany.sample.service.LeadService" level="warn">
<appender-ref ref="file"/>
</logger>
5. 日志實例;
- 實例1:
package com.mycompany.sample;
import org.mybatis.spring.annotation.MapperScan;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
/**
* @author : dylanz
* @since : 07/07/2020
**/
@SpringBootApplication
@EnableSwagger2
@MapperScan(basePackages = "com.mycompany.sample.dao")
public class App {
private static Logger logger = LoggerFactory.getLogger(App.class);
public static void main(String[] args) {
SpringApplication.run(App.class, args);
logger.trace("This is trace logger...");
logger.debug("This is debug logger...");
logger.info("This is info logger...");
logger.warn("This is warn logger...");
logger.error("This is error logger...");
}
}
//關鍵一行代碼:
//private static Logger logger = LoggerFactory.getLogger(App.class);
//getLogger()方法內(nèi)要使用該類類名夹厌;
- 實例2:
package com.mycompany.sample.service;
import com.mycompany.sample.dao.LeadDAO;
import com.mycompany.sample.domain.Lead;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @author : dylanz
* @since : 07/07/2020
**/
@Service
public class LeadService {
private static Logger logger = LoggerFactory.getLogger(LeadService.class);
@Autowired
private LeadDAO leadDAO;
public Lead getLeadByLeadId(Long leadId) {
logger.trace("This is trace logger in LeadService...");
logger.debug("This is debug logger in LeadService...");
logger.info("This is info logger in LeadService...");
logger.warn("This is warn logger in LeadService...");
logger.error("This is error logger in LeadService...");
return leadDAO.getLeadByLeadId(leadId);
}
}
6. 日志效果豹爹;
-
console日志;
-
file日志矛纹;
碼字不容易臂聋,點贊需積極
謝謝!!孩等!