1. 程式人生 > >Spring-Boot--日誌操作【全域性異常捕獲訊息處理☞日誌控制檯輸出+日誌檔案記錄】

Spring-Boot--日誌操作【全域性異常捕獲訊息處理☞日誌控制檯輸出+日誌檔案記錄】

       最好的演示說明,不是上來就貼配置檔案和程式碼,而是,先來一波配置檔案的註釋,再來一波程式碼的測試過程,最後再出個技術在專案中的應用效果,這樣的循序漸進的方式,才會讓讀者更加清楚的理解一項技術是如何運用在專案中的,雖然本篇很簡單,幾乎不用手寫什麼程式碼,但是,比起網上其他人寫的同類型的文章來說,我只能說,我很認真,認真的有點帥,哈哈哈哈。

一、日誌記錄相關依賴,首選Spring-Boot"原生態"的logback

Logback是由 log4j創始人設計的又一個開源日誌元件

logback當前分成三個模組:

logback-core

logback- classic

logback-access

logback-core是其它兩個模組的基礎模組

如果在你的pom.xml中,依賴瞭如下內容


恭喜你,本篇你可以不用再新增日誌元件的依賴了,為什麼呢,我們看下spring-boot-starter-web的依賴樹


二、當前Spring-Boot專案的目錄結構

說明:如果只是為了貼程式碼,而不結合專案演示的話,我寫本篇的初衷也就沒什麼意義了


三、本篇重點,logback-boot.xml內容解說
(1)主要看註釋
<configuration>    
    <!-- %m輸出的資訊,%p日誌級別,%t執行緒名,%d日期,%c類的全名,%i索引【從數字0開始遞增】,,, -->    
    <!-- appender是configuration的子節點,是負責寫日誌的元件。 -->
    <!-- ConsoleAppender:把日誌輸出到控制檯 -->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">    
        <encoder>    
            <pattern>%d %p (%file:%line\)- %m%n</pattern>  
            <!-- 控制檯也要使用UTF-8,不要使用GBK,否則會中文亂碼 -->
            <charset>UTF-8</charset>   
        </encoder>    
    </appender>    
    <!-- RollingFileAppender:滾動記錄檔案,先將日誌記錄到指定檔案,當符合某個條件時,將日誌記錄到其他檔案 -->
    <!-- 以下的大概意思是:1.先按日期存日誌,日期變了,將前一天的日誌檔名重新命名為XXX%日期%索引,新的日誌仍然是sys.log -->
    <!--             2.如果日期沒有發生變化,但是當前日誌的檔案大小超過1KB時,對當前日誌進行分割 重新命名-->
    <appender name="syslog"    
        class="ch.qos.logback.core.rolling.RollingFileAppender">    
        <File>log/sys.log</File>    
        <!-- rollingPolicy:當發生滾動時,決定 RollingFileAppender 的行為,涉及檔案移動和重新命名。 -->
        <!-- TimeBasedRollingPolicy: 最常用的滾動策略,它根據時間來制定滾動策略,既負責滾動也負責出發滾動 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">    
            <!-- 活動檔案的名字會根據fileNamePattern的值,每隔一段時間改變一次 -->
            <!-- 檔名:log/sys.2017-12-05.0.log -->
            <fileNamePattern>log/sys.%d.%i.log</fileNamePattern> 
            <!-- 每產生一個日誌檔案,該日誌檔案的儲存期限為30天 --> 
            <maxHistory>30</maxHistory>   
            <timeBasedFileNamingAndTriggeringPolicy  class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">    
                <!-- maxFileSize:這是活動檔案的大小,預設值是10MB,本篇設定為1KB,只是為了演示 -->  
                <maxFileSize>1KB</maxFileSize>    
            </timeBasedFileNamingAndTriggeringPolicy>    
        </rollingPolicy>    
        <encoder>    
            <!-- pattern節點,用來設定日誌的輸入格式 -->
            <pattern>    
                %d %p (%file:%line\)- %m%n  
            </pattern>    
            <!-- 記錄日誌的編碼 -->
            <charset>UTF-8</charset> <!-- 此處設定字符集 -->   
        </encoder>    
    </appender>    
    <!-- 控制檯輸出日誌級別 -->
    <root level="info">    
        <appender-ref ref="STDOUT" />    
    </root>    
    <!-- 指定專案中某個包,當有日誌操作行為時的日誌記錄級別 -->
    <!-- com.appley為根包,也就是隻要是發生在這個根包下面的所有日誌操作行為的許可權都是DEBUG -->
    <!-- 級別依次為【從高到低】:FATAL > ERROR > WARN > INFO > DEBUG > TRACE  -->
    <logger name="com.appleyk" level="DEBUG">    
        <appender-ref ref="syslog" />    
    </logger>    
</configuration>  

(2)application.properties中初始化logback-boot.xml
#在application.properties檔案中引入日誌配置檔案
#=====================================  log  =============================
logging.config=classpath:logback-boot.xml



logback日誌的配置我們已經弄完了,接下來就是演示了

四、定義全域性異常捕獲類【含異常訊息的日誌輔助記錄】

主要看內容,內容看懂了,就知道logback日誌記錄在什麼時候發揮作用了

(1)GlobalExceptionHandler.java

package com.appleyk.exception;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import com.appleyk.result.ResponseResult;

@CrossOrigin
@RestControllerAdvice
public class GlobalExceptionHandler {

	private static Logger LOGGER = LoggerFactory.getLogger(GlobalExceptionHandler.class);

	@ExceptionHandler
	public ResponseResult processException(Exception ex, HttpServletRequest request, HttpServletResponse response) {

		if (ex instanceof MissingServletRequestParameterException) {
			return new ResponseResult(400, ex);
		}
		if (ex instanceof NoPermissions) {

			LOGGER.error("=======" + ex.getMessage() + "=======");
			return new ResponseResult(401, "sorry,無許可權!");

		}

		if (ex instanceof DuplicateKeyException) {
			LOGGER.error("=======違反主鍵約束:主鍵重複插入=======");
			return new ResponseResult(400, "主鍵重複插入!");
		}

		/**
		 * 未知異常
		 */
		LOGGER.error(ex.toString());
		return new ResponseResult(500, ex.getMessage());

	}

}

(2)注意


(3)我們看下這個自定義異常類NoPermissions長什麼樣


(4)NoPermissions這個異常我們在哪裡丟擲呢?

本篇,日誌功能的測試是放在Controller中進行的,因此,這個自定義異常,也是放在Controller中丟擲By手動

五、建立測試Controller

(1)LogTestController.java

package com.appleyk.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.appleyk.exception.NoPermissions;
import com.appleyk.result.ExceptionEnum;
import com.appleyk.result.ResponseMessage;
import com.appleyk.result.ResponseResult;

@RestController
public class LogTestController {

	protected static Logger logger=LoggerFactory.getLogger(HelloController.class);  
	@RequestMapping("/test")
	public ResponseResult Test(@RequestParam(value="role") Integer role) throws Exception{
		
		logger.info("訪問Controller");
		int i = role;
		
		if(i<0){
			throw new NoPermissions(ExceptionEnum.WRONG_PERMISSONS.toString());
			
		}
		else{
		   return new ResponseResult(ResponseMessage.OK);
		}
		
		
	}
	
}

(2)注意


(3)我們來看一下自定義異常列舉裡面的訊息


六、測試Controller,測試日誌記錄功能

(1)測試前


(2)再看一下,logback-boot.xml中,配置的日誌輸出路徑是什麼


(3)啟動Spring-boot專案


(4)瀏覽器中測試

A. 先測試成功的: http://localhost:8080/test?role=100

1.瀏覽器返回資料json解析效果


2.控制檯日誌info級別的輸出


3.檔案日誌info級別的寫入


4.由於日誌檔案的大小在logback-boot.xml中配置了超過1KB就產生新的日誌檔案,命名規則見配置檔案,因此

多次重新整理瀏覽器,我們會發現如下:【注意,得多刷幾十次,才能出來效果,因為1KB的內容還是不少的】


5:注意

A.控制檯日誌輸出級別:INFO


B.日誌記錄到檔案級別:DEBUG


(5)Insomnia專業API測試工具測試

B. 再測試異常的: http://localhost:8080/test?role=-1

1.為了演示最佳效果,先停掉當前專案,再清空log資料夾下面的所有日誌


2.啟動專案

日誌記錄檔案立竿見影【牢記日誌記錄檔案的級別是DEBUG】


3.測試API【顯然role=-1的時候,對應的Controller丟擲自定義異常】


4.觀察下日誌


按照級別,大於DEBUG的都會出現在日誌記錄檔案裡,所以,我們的ERROR出現了


5.多Send一下,觀察日誌檔案變化


這個是今天的日誌,假設我改下系統日期操作如下

6.本篇的創作時間是2017年12月5日13:37:35【週二】,改為2017年12月6日13:37:49【週三】


然後我們在多Send幾次觀察下日誌檔案的變化



演示完,記得把系統日期改過來,偷笑