1. 程式人生 > 其它 >springboot+mybatis-plus統一日誌處理

springboot+mybatis-plus統一日誌處理

1、配置logback日誌

<?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="D:/log/edu" /> <!--控制檯日誌格式:彩色日誌--> <!-- 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)"/> <!--檔案日誌格式--> <property name="FILE_LOG_PATTERN" value="%date{yyyy-MM-dd HH:mm:ss} |%-5level |%thread |%file:%line |%logger |%msg%n" /> <!--編碼--> <property name="ENCODING" value="UTF-8" /> <!--輸出到控制檯--> <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <!--日誌級別--> <level>DEBUG</level> </filter> <encoder> <!--日誌格式--> <Pattern>${CONSOLE_LOG_PATTERN}</Pattern> <!--日誌字符集--> <charset>${ENCODING}</charset> </encoder> </appender> <!--輸出到檔案--> <appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!--日誌過濾器:此日誌檔案只記錄INFO級別的--> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>INFO</level> <onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch> </filter> <!-- 正在記錄的日誌檔案的路徑及檔名 --> <file>${log.path}/log_info.log</file> <encoder> <pattern>${FILE_LOG_PATTERN}</pattern> <charset>${ENCODING}</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>500MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> <!--日誌檔案保留天數--> <maxHistory>15</maxHistory> </rollingPolicy> </appender> <appender name="WARN_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!-- 日誌過濾器:此日誌檔案只記錄WARN級別的 --> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>WARN</level> <onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch> </filter> <!-- 正在記錄的日誌檔案的路徑及檔名 --> <file>${log.path}/log_warn.log</file> <encoder> <pattern>${FILE_LOG_PATTERN}</pattern> <charset>${ENCODING}</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> </appender> <appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!-- 日誌過濾器:此日誌檔案只記錄ERROR級別的 --> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>ERROR</level> <onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch> </filter> <!-- 正在記錄的日誌檔案的路徑及檔名 --> <file>${log.path}/log_error.log</file> <encoder> <pattern>${FILE_LOG_PATTERN}</pattern> <charset>${ENCODING}</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> </appender> <!--開發環境--> <springProfile name="dev"> <!--可以靈活設定此處,從而控制日誌的輸出--> <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="ERROR"> <appender-ref ref="ERROR_FILE" /> </root> </springProfile> </configuration>

2、ExceptionUtils工具類 

 呼叫 log.error(ExceptionUtil.getMessage(e));

package com.stu.service.base.utils;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
/******************************
 * 用途說明:
 * 作者姓名: Administrator
 * 建立時間: 2022-04-18 22:26
 ******************************/

public class ExceptionUtils {

    /***********************************
     * 用途說明:
     * 返回值說明: java.lang.String
     ***********************************/
    public static String getMessage(Exception e) {
        StringWriter sw = null;
        PrintWriter pw = null;
        try {
            sw = new StringWriter();
            pw = new PrintWriter(sw);
            // 將出錯的棧資訊輸出到printWriter中
            e.printStackTrace(pw);
            pw.flush();
            sw.flush();
        } finally {
            if (sw != null) {
                try {
                    sw.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
            if (pw != null) {
                pw.close();
            }
        }
        return sw.toString();
    }
}

3、全域性異常

類上添加註解

 @Slf4j

異常輸出語句

log.error(e.getMessage());

package com.stu.servicebase.handler;

import com.stu.service.base.result.R;
import com.stu.service.base.utils.ExceptionUtils;
import com.stu.servicebase.exception.CustomException;
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;

/******************************
 * 用途說明:統一異常處理
 * 作者姓名: Administrator
 * 建立時間: 2022-04-17 23:32
 ******************************/
@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {


    /***********************************
     * 用途說明:自定義異常
     * 返回值說明: com.stu.service.base.result.R
     ***********************************/
    @ExceptionHandler(CustomException.class)
    @ResponseBody
    public R customException(CustomException e){
//        e.printStackTrace();
//        log.error(e.getMessage());
        log.error(ExceptionUtils.getMessage(e));
        return R.error().message(e.getMessage()).code(e.getCode());
    }
    /***********************************
     * 用途說明:數字異常
     * 返回值說明: com.stu.service.base.result.R
     ***********************************/
    @ExceptionHandler(ArithmeticException.class)
    @ResponseBody
    public R arithmeticException(Exception e){
        log.error(ExceptionUtils.getMessage(e));
        return R.error().message(e.getMessage());
    }
    /***********************************
     * 用途說明:全域性異常
     * 返回值說明: com.stu.service.base.result.R
     ***********************************/
    @ExceptionHandler(Exception.class)
    @ResponseBody
    public R error(Exception e){
        log.error(ExceptionUtils.getMessage(e));
        return R.error().message(e.getMessage());
    }

}

4、自定義異常

package com.stu.servicebase.exception;

import com.stu.service.base.result.ResultCodeEnum;
import lombok.Data;

/******************************
 * 用途說明:自定義異常
 * 作者姓名: Administrator
 * 建立時間: 2022-04-18 0:00
 ******************************/
@Data
public class CustomException extends RuntimeException{

    private Integer code;

    public CustomException(ResultCodeEnum resultCodeEnum){
        super(resultCodeEnum.getMessage());
        //this.message = resultCodeEnum.getMessage();
        this.code = resultCodeEnum.getCode();

    }

} 

5、log檔案(error.log為例)

log_error.log檔案

2022-04-18 22:22:23 |ERROR |http-nio-9110-exec-9 |GlobalExceptionHandler.java:28 |com.stu.servicebase.handler.GlobalExceptionHandler |除零錯誤
2022-04-18 22:31:42 |ERROR |http-nio-9110-exec-1 |GlobalExceptionHandler.java:30 |com.stu.servicebase.handler.GlobalExceptionHandler |CustomException(code=29001)
    at com.stu.service.edu.controller.TeacherController.deleteTeacher(TeacherController.java:42)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:105)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:879)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:793)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
    at org.springframework.web.servlet.FrameworkServlet.doDelete(FrameworkServlet.java:931)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:666)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:373)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1590)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:744)