【SpringBoot探索二】SpringBoot專案整合日誌記錄功能
在之前專案的基礎上新增日誌
1.讓專案具有輸出日誌功能
在pom檔案中加入依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
這樣也包含了日誌功能,在程式碼中就可以使用日誌輸出類了
package com.my.webapp.service.impl;
import com.my.webapp.service.LoginService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
/**
*/
@Service
public class LoginServiceImpl implements LoginService {
private final Logger logger = LoggerFactory.getLogger(this.getClass().getSimpleName());
@Override
public String login () {
logger.debug("使用slf4j進行日誌記錄!");
return "welcome to spring boot world!";
}
}
當然這樣我們還沒法執行程式看到效果,還需要先編寫日誌配置檔案logback.xml
2.配置日誌
編寫logback.xml
在resource目錄下新增logback.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/2002/xmlspec/dtd/2.10/xmlspec.dtd">
<configuration>
<!--web應用名稱-->
<contextName>webapp</contextName>
<!--自定義變數名, 通過${name}來使用-->
<property name="test" value="testValue"/>
<!--獲取時間戳字串,key為名稱,datePattern為格式化時間戳為指定格式字串-->
<timestamp key="time" datePattern="yyyyMMdd'T'HHmmss"/>
<!--自定義輸出源-->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- encoder 預設配置為PatternLayoutEncoder -->
<encoder>
<!--輸出格式
%n 換行
%-5level 從左往右佔5個字元,輸出列印級別
%d 輸出日期,格式為HH:mm:ss
%logger 輸出該日誌的類或包
%msg 日誌記錄
-->
<pattern>%n[%-5level]-%d{HH:mm:ss}-%logger-%thread-%msg</pattern>
</encoder>
</appender>
<!--根logger-->
<root level="DEBUG">
<appender-ref ref="STDOUT"/>
</root>
</configuration>
新增好後,執行專案,則會自動載入該日誌配置檔案
當運行了
logger.debug("使用slf4j進行日誌記錄!");
控制檯則能看到如下效果
[DEBUG]-10:53:31-LoginServiceImpl-http-nio-8080-exec-1-使用slf4j進行日誌記錄!
3.自定義轉義型別資料
在上面我們除了用自帶的格式,如%n,%msg等等,如果我們還想要設定其它型別資料,比如每條日誌上輸出請求url,那麼則需要自定義PatternLayoutEncoder
編寫一個繼承自PatternLayoutEncoderBase的類,覆蓋start()方法,主要往InstanceConverterMap裡新增自定義轉義型別以及值
package com.my.webapp.logback;
import ch.qos.logback.classic.PatternLayout;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.pattern.PatternLayoutEncoderBase;
import com.my.webapp.logback.converter.HttpRequestConverter;
import java.util.HashMap;
import java.util.Map;
/**
*/
public class PatternLayoutEncoder extends PatternLayoutEncoderBase<ILoggingEvent> {
@Override
public void start() {
PatternLayout patternLayout = new PatternLayout();
patternLayout.getInstanceConverterMap().putAll(setPatternType());
patternLayout.setContext(context);
patternLayout.setPattern(getPattern());
patternLayout.setOutputPatternAsHeader(outputPatternAsHeader);
patternLayout.start();
this.layout = patternLayout;
super.start();
super.start();
}
/**
* 自定義轉義型別
* @return
*/
private Map<String, String> setPatternType() {
Map<String, String> map = new HashMap<String, String>();
map.put("request", HttpRequestConverter.class.getName());
return map;
}
}
這裡需要注意Map的value為自定義Converter的類名
編寫對應型別的Converter
需要繼承ClassicConverter並覆蓋converter()方法
HttpRequestConverter.java
package com.my.webapp.logback.converter;
import ch.qos.logback.classic.pattern.ClassicConverter;
import ch.qos.logback.classic.spi.ILoggingEvent;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
/**
*/
public class HttpRequestConverter extends ClassicConverter{
@Override
public String convert(ILoggingEvent iLoggingEvent) {
ServletRequestAttributes requestAttributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
if(requestAttributes == null){
return "";
}
HttpServletRequest request = requestAttributes.getRequest();
if(request == null){
return "";
}
return request.getRequestURI();
}
}
converter()方法輸出的值即為輸出日誌時,%request對應的值
修改encoder屬性,class修改為我們剛自定義的類。
這樣我們就可以在輸出格式中新增%request這種型別了
<encoder charset="UTF-8" class="com.my.webapp.logback.PatternLayoutEncoder">
<pattern>%n[%-5level]--%d{HH:mm:ss}--%logger--%thread--%method--[%request]--%msg</pattern>
</encoder>
日誌執行效果如下:
[DEBUG]–15:09:42–LoginServiceImpl–http-nio-8080-exec-1–login–[/user/loginWithService/31]–[debug]使用slf4j進行日誌記錄!
4.自定義logger
剛剛的配置將所有類的輸出格式都是一致的,如果需要配置特定類或包下的類,比如設定不同列印級別,就需要自定義logger
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/2002/xmlspec/dtd/2.10/xmlspec.dtd">
<configuration>
<!--web應用名稱-->
<contextName>webapp</contextName>
<!--自定義變數名, 通過${name}來使用-->
<property name="test" value="testValue"/>
<!--獲取時間戳字串,key為名稱,datePattern為格式化時間戳為指定格式字串-->
<timestamp key="time" datePattern="yyyyMMdd'T'HHmmss"/>
<!--自定義輸出源-->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- encoder 預設配置為PatternLayoutEncoder -->
<encoder charset="UTF-8">
<!--輸出格式
%n 換行
%-5level 從左往右佔5個字元,輸出列印級別
%d 輸出日期,格式為HH:mm:ss
%logger 輸出該日誌的類或包
%msg 日誌記錄
-->
<pattern>%n[%-5level]-%d{HH:mm:ss}-%logger-%thread-%msg</pattern>
</encoder>
</appender>
<!--logger用於設定某個包或某個類的日誌列印級別,以及設定appender
name: 指定的包或類
level: 列印級別 TRACE, DEBUG, INFO, WARN, ERROR, ALL, OFF,不區分大小寫,還有特殊值INHERITED或者同義詞NULL,代表強制執行上級的級別。
如果未設定此屬性,那麼當前loger將會繼承上級的級別。
additivity: 是否向上級loger傳遞列印資訊。預設是true。
-->
<!--<logger name="com.my.webapp" level="DEBUG" addtivity="false">-->
<!--使用自定義的日誌輸出配置,比如輸出到檔案或者是控制檯-->
<!--ref 引用的appender 對應appender的name值-->
<!--<appender-ref ref="STDOUT"/>-->
<!--</logger>-->
<!--這裡指定springframework包下所有的類,日誌輸出級別為INFO,additivity預設為true。則將日誌資訊遞交給上級logger(root)處理,
要處理的日誌資訊為INFO及之後的級別
-->
<logger name="org.springframework" level="INFO"/>
<!--http包下的日誌輸出到控制檯,並且不會傳遞給上級處理-->
<logger name="org.apache.http" level="INFO" additivity="false">
<appender-ref ref="STDOUT"/>
</logger>
<!--根logger-->
<root level="DEBUG">
<appender-ref ref="STDOUT"/>
</root>
</configuration>
5.設定將日誌輸出到檔案
新增一個新的appender,其負責將日誌記錄在檔案中
<!--輸出到檔案中-->
<appender name="LogFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!--設定日誌滾動策略,比如切換檔案記錄日誌,或重新命名等
clss: 滾動策略 TimeBasedRollingPolicy為最常見滾動策略,根據時間來制定
-->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--日誌檔案輸出的檔名-->
<FileNamePattern>${filePath}/webapp-%d{yyyy-MM-dd}.log</FileNamePattern>
<!--日誌保留的最大個數,超過了則刪除最舊的檔案-->
<MaxHistory>30</MaxHistory>
</rollingPolicy>
<encoder charset="UTF-8">
<pattern>%n[%-5level]-%d{HH:mm:ss}-%logger-%thread-[%method]-%msg</pattern>
</encoder>
<!--日誌檔案最大的大小-->
<!--class 日誌通知觸發策略 SizeBasedTriggeringPolicy,超過設定大小則發出通知-->
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<!--單個日誌檔案大小限制,超過則記錄在新的日誌檔案中-->
<MaxFileSize>10MB</MaxFileSize>
</triggeringPolicy>
</appender>
將想要輸出日誌到檔案中的looger修改appender-ref引用為剛設定的appender(如”LogFile”)
<root level="DEBUG">
<!--輸出到控制檯-->
<!--<appender-ref ref="STDOUT"/>-->
<!--輸出到指定檔案-->
<appender-ref ref="LogFile"/>
</root>
這樣日誌都會記錄到檔案中了,路徑為我設定的
E:\java\logfile\目錄下
最終logback.xml檔案內容:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/2002/xmlspec/dtd/2.10/xmlspec.dtd">
<configuration>
<!--web應用名稱-->
<contextName>webapp</contextName>
<!--自定義變數名, 通過${name}來使用-->
<property name="test" value="testValue"/>
<!--獲取時間戳字串,key為名稱,datePattern為格式化時間戳為指定格式字串-->
<timestamp key="time" datePattern="yyyyMMdd'T'HHmmss"/>
<!--定義一個日誌存放目錄屬性,方便修改-->
<property name="filePath" value="E:/java/logfile"/>
<!--自定義輸出源-->
<!--輸出到控制檯-->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- encoder
class 預設配置為PatternLayoutEncoder -->
<encoder charset="UTF-8" class="com.my.webapp.logback.PatternLayoutEncoder">
<!--輸出格式
%n 換行
%-5level 從左往右佔5個字元,輸出列印級別
%d 輸出日期,格式為HH:mm:ss
%logger 輸出該日誌的類或包
%msg 日誌記錄
%method 列印該日誌的方法
如果需要列印其它型別資料則需要自定義PatternLayoutEncoder方法(比如%request)
-->
<pattern>%n[%-5level]--%d{HH:mm:ss}--%logger--%thread--%method--[%request]--%msg</pattern>
</encoder>
</appender>
<!--輸出到檔案中-->
<appender name="LogFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!--設定日誌滾動策略,比如切換檔案記錄日誌,或重新命名等
clss: 滾動策略 TimeBasedRollingPolicy為最常見滾動策略,根據時間來制定
-->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--日誌檔案輸出的檔名-->
<FileNamePattern>${filePath}/webapp-%d{yyyy-MM-dd}.log</FileNamePattern>
<!--日誌保留的最大個數,超過了則刪除最舊的檔案-->
<MaxHistory>30</MaxHistory>
</rollingPolicy>
<encoder charset="UTF-8">
<pattern>%n[%-5level]-%d{HH:mm:ss}-%logger-%thread-[%method]-%msg</pattern>
</encoder>
<!--日誌檔案最大的大小-->
<!--class 日誌通知觸發策略 SizeBasedTriggeringPolicy,超過設定大小則發出通知-->
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<!--單個日誌檔案大小限制,超過則記錄在新的日誌檔案中-->
<MaxFileSize>10MB</MaxFileSize>
</triggeringPolicy>
</appender>
<!--logger用於設定某個包或某個類的日誌列印級別,以及設定appender
name: 指定的包或類
level: 列印級別 TRACE, DEBUG, INFO, WARN, ERROR, ALL, OFF,不區分大小寫,還有特殊值INHERITED或者同義詞NULL,代表強制執行上級的級別。
如果未設定此屬性,那麼當前loger將會繼承上級的級別。
additivity: 是否向上級loger傳遞列印資訊。預設是true。
-->
<!--http包下的日誌輸出到控制檯,不會傳遞給上級處理-->
<logger name="org.apache.http" level="INFO" additivity="false">
<appender-ref ref="STDOUT"/>
</logger>
<!--這裡指定springframework包下所有的類,日誌輸出級別為INFO,additivity預設為true。則將日誌資訊遞交給上級logger(root)處理,
要處理的日誌資訊為INFO及之後的級別
-->
<logger name="org.springframework" level="INFO"/>
<!--根logger-->
<root level="DEBUG">
<!--輸出到控制檯-->
<!--<appender-ref ref="STDOUT"/>-->
<!--輸出到指定檔案-->
<appender-ref ref="LogFile"/>
</root>
</configuration>
以上即為logback常用配置
部落格參考案例已上傳: