T31 project day 5


Today is the third day of Gujin class. I learned exception handling and log with Mr. Gong Gong today,

Exception handling and logging

1. java exception system

The exception should describe the cause of the current exception
Quickly determine the location of the exception according to the exception stack
Combine exception description and exception stack to solve exceptions

1.1 exception handling process


After java gets the exception, the system will determine whether there is a try. If there is a try, it will be handled by the try. If there is no try, it will be handled by the jvm by default. If there is a catch in the try, it will be handled by the jvm. If there is a catch, it will be handled by the catch. After the catch is processed, it will determine whether there is finally, if there is, it will be handled by finally, and if not, it will be handled by the jvm

1.2 Java exception handling mechanism


If multiple exceptions occur, grab the exception handling method
1. Separate the correct return and exception return of the method. Return is used for correct return and throw is used for exception return
2. Using multiple catches, low-level exceptions are thrown first, and catch is performed when the exception level is raised

1.4 java exception system

error
Memory exceptions of java virtual machine can not be handled manually
exception:
Checked exceptions: predictable exceptions and exceptions that need to be caught (run-time exceptions), checked exceptions and unchecked exceptions (whether the compiler reports an error during compilation)

2. Exception handling

2.1 principles of exception throwing and catching

1. Unnecessary exception
2. Throw a descriptive exception
3. Exceptions within your ability must be handled
4. Exceptions should be ignored with reason
Summary: don't add too many exceptions. Reduce exception throwing through business processing

2.2 try... catch... finally in Java exception system


Summary:
Don't add return to the code block of try... Catch. Finally, it will invalidate the processing results in catch, and finally return the result set with return

2.3 several processes of exception handling in JDK

Summary:
1. If try... catch... Final is used to read or write resources, open links and other operations, the resources or links need to be closed after final to avoid causing io exceptions or memory overflow exceptions of the jvm

2.4 special NPE treatment

Special NPE: for continuous attribute calls, if a null pointer appears in the code, the system will throw a NULLPOINTException exception
**Processing idea: * * optional feature processing after JDK1.8
optional.ofNullable(obj)
ofElse: set the default value when it is empty
isPresent (consumer <? Super T > consumer) does some processing when value has no value

2.5 special abnormal situations and handling ideas

Foreach loop: add and remove operations are performed in the recycling body, because when traversing resources, it will compare whether the last modification times are consistent with the expected modification times. If they are inconsistent, an error will be thrown. After throwing an exception in foreach, it will not be executed later,

3. Log protocol

3.1 log function

Monitoring alarm: health check, indicator monitoring (alarm)
Record behavior track: indicator monitoring, link (tracking)
Quick fix problem:

3.2 log aging protocol


Setting summary: log naming: T31 sets a log folder. The folder name is not T31log. The log is divided into different folders according to different businesses. For example, the order business log folder name is not order. The directory of the corresponding folder is generated according to the year, month and day. The daily log generates an independent log file according to the hour. The file name is time division format.log
**Other logs: * * the logs of user sensitive information and operations shall be kept for more than 6 months, and multi machine backup shall be used for subsequent business processing

3.3 logging protocol

The system should rely on the API of the logging framework (SLF4J,JCL) rather than in the log library

matters needing attention:

Do not use json tools to convert objects to string s when printing logs

Relationship between logback and SFL4J:
logback is an interface that directly implements slf4j and does not consume memory and computational overhead. Log4j is not the native implementation of slf4j, so the slf4j api needs an adaptation layer when calling log4j.

3.3 core configuration of logback

3.4 log output protocol

Log level (trace, debug, info) switch judgment,
Complete exception log information: incident site information and exception stack information
Avoid duplicate log printing: additivity=false is configured in the log configuration file

3.5 extended log protocol

**Extended log: * * application management, temporary monitoring, access log, etc
**Storage method: * * business logs and error logs are stored separately, and expansion logs and other logs are stored separately

4. Error code protocol

4.1 function of error code

Communication between people and system: corresponding system errors can be identified through error codes
Communication between people: unify the error handling mechanism and maintain the consistency of error handling ideas
Communication between systems: the transmission of different wrong information in the system business flow

4.1 protocol of error code


**Summary: * * the definition of error information needs to be classified and analyzed according to business conditions, and each error condition is represented by error code

4.3 error code


**Summary: * * set different error codes for different situations in the log according to the abnormal and normal payment requests in the system business. Each error code corresponds to different business situations and makes a description

5. Exception and log practice

5.1 catch exceptions in the controller layer


**Summary: * * underlying service.dao. Unified handling of manager exceptions in the Controller layer

5.2 global exception component GlobalExceptionHandler to catch exceptions

package kr.weitao.starter.config;

import kr.weitao.common.exception.CommonException;
import kr.weitao.common.exception.ServiceException;
import kr.weitao.starter.model.DataResponse;
import kr.weitao.starter.model.Status;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.TypeMismatchException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.FieldError;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.io.IOException;
import java.net.SocketTimeoutException;
import java.util.List;

/**
 * Global unified exception handling
 */
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandle {

    /**
     * Business exception
     */
    @ExceptionHandler(value = ServiceException.class)
    public ResponseEntity<DataResponse> handle(ServiceException e) {
        e.printStackTrace();
        DataResponse failure = new DataResponse().setStatus(Status.FAILED).setMsg(e.getMsg());
        return ResponseEntity.ok().body(failure);
    }

    @ExceptionHandler(value = CommonException.class)
    public ResponseEntity<DataResponse> handle(CommonException e) {
        e.printStackTrace();
        DataResponse failure = new DataResponse().setStatus(Status.FAILED).setMsg(e.getMessage());
        return ResponseEntity.ok().body(failure);
    }

    /**
     * 400 error
     */
    @ExceptionHandler({HttpMessageNotReadableException.class})
    public ResponseEntity<DataResponse> requestNotReadable(HttpMessageNotReadableException ex) {
        ex.printStackTrace();
        DataResponse failure = new DataResponse().setStatus(Status.FAILED).setMsg(ex.getMessage());
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(failure);
    }

    /**
     * 400 error
     * @param ex
     * @return
     */
    @ExceptionHandler({TypeMismatchException.class})
    public ResponseEntity<DataResponse> requestTypeMismatch(TypeMismatchException ex) {
        ex.printStackTrace();
        DataResponse failure = new DataResponse().setStatus(Status.FAILED).setMsg(ex.getMessage());
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(failure);
    }

    /**
     * 400 error
     *
     * @param ex
     * @return
     */
    @ExceptionHandler({MissingServletRequestParameterException.class})
    public ResponseEntity<DataResponse> requestMissingServletRequest(MissingServletRequestParameterException ex) {
        ex.printStackTrace();
        DataResponse failure = new DataResponse().setStatus(Status.FAILED).setMsg(ex.getMessage());
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(failure);
    }

    /**
     * IO abnormal
     *
     * @param ex
     * @return
     */
    @ExceptionHandler(IOException.class)
    public ResponseEntity<DataResponse> iOExceptionHandler(IOException ex) {
        ex.printStackTrace();
        DataResponse failure = new DataResponse().setStatus(Status.FAILED).setMsg(ex.getMessage());
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(failure);
    }

    /**
     * 405 error
     *
     * @param ex
     * @return
     */
    @ExceptionHandler({HttpRequestMethodNotSupportedException.class})
    public ResponseEntity<DataResponse> request405(HttpRequestMethodNotSupportedException ex) {
        ex.printStackTrace();
        DataResponse failure = new DataResponse().setStatus(Status.FAILED).setMsg("The request method is not supported");
        return ResponseEntity.status(HttpStatus.METHOD_NOT_ALLOWED).body(failure);
    }


    /**
     * Timeout exception
     *
     * @param ex
     * @return
     */
    @ExceptionHandler(SocketTimeoutException.class)
    public ResponseEntity<DataResponse> SocketTimeoutException(SocketTimeoutException ex) {
        ex.printStackTrace();
        DataResponse failure = new DataResponse().setStatus(Status.FAILED).setMsg("connection timed out,Please check the network environment or try again");
        return ResponseEntity.status(HttpStatus.REQUEST_TIMEOUT).body(failure);
    }

    /**
     * Handle input parameter exception
     */
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public ResponseEntity<DataResponse> handleIllegalParamException(MethodArgumentNotValidException e) {
        e.printStackTrace();
        String message = "Illegal parameter";
        List<FieldError> errors = e.getBindingResult().getFieldErrors();
        if (errors.size() > 0) {
            message = errors.get(0).getDefaultMessage();
        }
        DataResponse failure = new DataResponse().setStatus(Status.FAILED).setMsg(message);
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(failure);
    }

    /**
     * Other types of exceptions
     * @param e
     * @return
     */
    @ExceptionHandler(value = RuntimeException.class)
    public ResponseEntity<DataResponse> handle(Exception e) {
        e.printStackTrace();
        DataResponse failure = new DataResponse().setStatus(Status.FAILED).setMsg(e.getMessage());
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(failure);
    }


}

5.3 practice of API abnormal design

**Summary: * * exception information is user-friendly, and the underlying error information is handled according to the error code and thrown upward,

5.4 abnormal design practice of service layer

**Summary: * * avoid the generation of dirty data (null processing), throw the information corresponding to the exception code, and throw the relevant dao error information to the upper layer

5.5 dao layer anomaly


Summary: use daoException to encapsulate exceptions, throw them up, and selectively record sql statements and operation time information

5.6MDC tracking link


Practice:
The MDC mechanism of Logback adds the sessionId format to the log template, and specifies the output sessionId in the log output format

%d{yyyy-MM-dd HH:mm:ss.SSS}  [%X{sessionId}] -%5p ${PID:-} [%15.15t] %-40.40logger{39} : %m%n

5.7 handle the complex and changeable possibilities in the business with limited exceptions

*Summary:
1. * use general serverException to define the general ServiceException business exception of RuntimeException
2. Combine the error codes associated with the business to realize complex and changeable abnormal requirements

Keywords: log4j Logback

Added by idealbrain on Sun, 31 Oct 2021 06:53:28 +0200