1. 程式人生 > 其它 >lombok+Logback統一異常和日誌處理

lombok+Logback統一異常和日誌處理

1.xml檔案

<?xml version="1.0" encoding="UTF-8"?>
<configuration  scan="true" scanPeriod="10 seconds">
    <!-- 日誌級別從低到高分為TRACE < DEBUG < INFO < WARN < ERROR < FATAL,如果設定為WARN,則低於WARN的資訊都不會輸出 -->
    <!-- scan:當此屬性設定為true時,配置檔案如果發生改變,將會被重新載入,預設值為true -->
    <!--
scanPeriod:設定監測配置檔案是否有修改的時間間隔,如果沒有給出時間單位,預設單位是毫秒。當scan為true時,此屬性生效。預設的時間間隔為1分鐘。 --> <!-- debug:當此屬性設定為true時,將打印出logback內部日誌資訊,實時檢視logback執行狀態。預設值為false。 --> <contextName>logback</contextName> <!-- name的值是變數的名稱,value的值時變數定義的值。通過定義的值會被插入到logger上下文中。定義變數後,可以使“${}”來使用變數。
--> <property name="log.path" value="F:/guli_log/edu" /> <!-- 彩色日誌 --> <!-- 配置格式變數:CONSOLE_LOG_PATTERN 彩色日誌格式 --> <!-- magenta:洋紅 --> <!-- boldMagenta:粗紅--> <!-- cyan:青色 --> <!-- white:白色 --> <!-- magenta:洋紅 --> <
property name="CONSOLE_LOG_PATTERN" value="%yellow(%date{yyyy-MM-dd HH:mm:ss}) |%highlight(%-5level) |%blue(%thread) |%blue(%file:%line) |%green(%logger) |%cyan(%msg%n)"/> <!--輸出到控制檯--> <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> <!--此日誌appender是為開發使用,只配置最底級別,控制檯輸出的日誌級別是大於或等於此級別的日誌資訊--> <!-- 例如:如果此處配置了INFO級別,則後面其他位置即使配置了DEBUG級別的日誌,也不會被輸出 --> <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>INFO</level> </filter> <encoder> <Pattern>${CONSOLE_LOG_PATTERN}</Pattern> <!-- 設定字符集 --> <charset>UTF-8</charset> </encoder> </appender> <!--輸出到檔案--> <!-- 時間滾動輸出 level為 INFO 日誌 --> <appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!-- 正在記錄的日誌檔案的路徑及檔名 --> <file>${log.path}/log_info.log</file> <!--日誌檔案輸出格式--> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern> <charset>UTF-8</charset> </encoder> <!-- 日誌記錄器的滾動策略,按日期,按大小記錄 --> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!-- 每天日誌歸檔路徑以及格式 --> <fileNamePattern>${log.path}/info/log-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <maxFileSize>100MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> <!--日誌檔案保留天數--> <maxHistory>15</maxHistory> </rollingPolicy> <!-- 此日誌檔案只記錄info級別的 --> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>INFO</level> <onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch> </filter> </appender> <!-- 時間滾動輸出 level為 WARN 日誌 --> <appender name="WARN_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!-- 正在記錄的日誌檔案的路徑及檔名 --> <file>${log.path}/log_warn.log</file> <!--日誌檔案輸出格式--> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern> <charset>UTF-8</charset> <!-- 此處設定字符集 --> </encoder> <!-- 日誌記錄器的滾動策略,按日期,按大小記錄 --> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${log.path}/warn/log-warn-%d{yyyy-MM-dd}.%i.log</fileNamePattern> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <maxFileSize>100MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> <!--日誌檔案保留天數--> <maxHistory>15</maxHistory> </rollingPolicy> <!-- 此日誌檔案只記錄warn級別的 --> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>warn</level> <onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch> </filter> </appender> <!-- 時間滾動輸出 level為 ERROR 日誌 --> <appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!-- 正在記錄的日誌檔案的路徑及檔名 --> <file>${log.path}/log_error.log</file> <!--日誌檔案輸出格式--> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern> <charset>UTF-8</charset> <!-- 此處設定字符集 --> </encoder> <!-- 日誌記錄器的滾動策略,按日期,按大小記錄 --> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${log.path}/error/log-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <maxFileSize>100MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> <!--日誌檔案保留天數--> <maxHistory>15</maxHistory> </rollingPolicy> <!-- 此日誌檔案只記錄ERROR級別的 --> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>ERROR</level> <onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch> </filter> </appender> <!-- <logger>用來設定某一個包或者具體的某一個類的日誌列印級別、以及指定<appender>。 <logger>僅有一個name屬性, 一個可選的level和一個可選的addtivity屬性。 name:用來指定受此logger約束的某一個包或者具體的某一個類。 level:用來設定列印級別,大小寫無關:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF, 如果未設定此屬性,那麼當前logger將會繼承上級的級別。 --> <!-- 使用mybatis的時候,sql語句是debug下才會列印,而這裡我們只配置了info,所以想要檢視sql語句的話,有以下兩種操作: 第一種把<root level="INFO">改成<root level="DEBUG">這樣就會列印sql,不過這樣日誌那邊會出現很多其他訊息 第二種就是單獨給mapper下目錄配置DEBUG模式,程式碼如下,這樣配置sql語句會列印,其他還是正常DEBUG級別: --> <!--開發環境:列印控制檯--> <springProfile name="dev"> <!--可以輸出專案中的debug日誌,包括mybatis的sql日誌--> <logger name="com.guli" level="INFO" /> <!-- root節點是必選節點,用來指定最基礎的日誌輸出級別,只有一個level屬性 level:用來設定列印級別,大小寫無關:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,預設是DEBUG 可以包含零個或多個appender元素。 --> <root level="INFO"> <appender-ref ref="CONSOLE" /> <appender-ref ref="INFO_FILE" /> <appender-ref ref="WARN_FILE" /> <appender-ref ref="ERROR_FILE" /> </root> </springProfile> <!--生產環境:輸出到檔案--> <springProfile name="pro"> <root level="INFO"> <appender-ref ref="CONSOLE" /> <appender-ref ref="DEBUG_FILE" /> <appender-ref ref="INFO_FILE" /> <appender-ref ref="ERROR_FILE" /> <appender-ref ref="WARN_FILE" /> </root> </springProfile> </configuration>

2.自定義異常類

package com.stu.servicebase.exceptionHandler;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor //生成有引數的註解的構造方法
@NoArgsConstructor //生成無引數的註解的構造方法
public class GuliException extends RuntimeException {

    private  Integer code;//狀態碼
    private  String msg;//異常資訊

    @Override
    public String toString() {
        return "GuliException{" +
                "message=" + msg +
                ", code=" + code +
                '}';
    }

}

3.統一異常處理類

package com.stu.servicebase.exceptionHandler;

import com.stu.commonutils.ResultData;
import com.stu.servicebase.util.ExceptionUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

@ControllerAdvice
@Slf4j
public class GlobalExceptionHandler {

    //指定出現什麼異常執行這個方法
    @ExceptionHandler(Exception.class)
    @ResponseBody
    public ResultData error(Exception e){

        e.printStackTrace();
        return ResultData.error().message("執行了全域性異常處理");
    }

    //特定異常
    @ExceptionHandler(ArithmeticException.class)
    @ResponseBody
    public ResultData error(ArithmeticException e){

        e.printStackTrace();
        return ResultData.error().message("執行了除零異常處理");
    }

    //自定義異常
    @ExceptionHandler(GuliException.class)
    @ResponseBody
    public ResultData error(GuliException e){

        log.error(e.getMessage());//log自帶列印方式
        log.error(ExceptionUtil.getMessage(e));//自定義列印方式

        e.printStackTrace();
        return ResultData.error().code(e.getCode()).message(e.getMsg());
    }
}