springboot增加请求响应日志类

 

一、修改yml配置文件

logging:
  includePaths:
    - /**
    - /api/**

 

二、增加配置类

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.util.List;


/**
 * @author fengyi
 */
@Component
@ConfigurationProperties(prefix = "logging")
public class LoggingProperties {
    private List<String> includePaths;

    public List<String> getIncludePaths() {
        return includePaths;
    }

    public void setIncludePaths(List<String> includePaths) {
        this.includePaths = includePaths;
    }
}

 

三、编写日志切面类

 

import cn.hutool.json.JSONUtil;
import com.beauty.framework.config.LoggingProperties;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.support.MultipartFilter;

import javax.annotation.Resource;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;


/**
 * @author fengyi
 */
@Slf4j
@Aspect
@Component
public class WhiteListLogAspect {

    @Resource
    private LoggingProperties loggingProperties;

    private AntPathMatcher pathMatcher = new AntPathMatcher();

    private Long startTime;

    @AfterReturning(pointcut = "execution(* com.beauty.*.controller..*(..))", returning = "result")
    public void doAfterReturning(JoinPoint joinPoint, Object result) {
        // 获取请求信息
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String requestURI = request.getRequestURI();
        if (shouldLog(requestURI)) {
            // 将处理结果转换为JSON字符串,这里假设返回类型可以被JSONUtil.toJsonStr处理
            String responseJson = JSONUtil.toJsonStr(result);
            addLog(joinPoint, responseJson, System.currentTimeMillis() - startTime);
        }
    }

    @Before("execution(* com.beauty.*.controller..*(..))")
    public void doBefore(JoinPoint joinPoint) {
        startTime = System.currentTimeMillis();
    }


    /**
     * 日志记录入库操作
     */
    public void addLog(JoinPoint joinPoint, String outParams, long time) {
        HttpServletRequest request = ((ServletRequestAttributes)
                Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
        log.info("\n\r=======================================\n\r" +
                        "请求地址:{} \n\r" +
                        "请求方式:{} \n\r" +
                        "请求参数:{} \n\r" +
                        "请求体:{} \n\r" +
                        "请求类方法:{} \n\r" +
                        "请求方法参数:{} \n\r" +
                        "返回报文:{} \n\r" +
                        "处理耗时:{} ms \n\r" +
                        "=======================================\n\r",
                request.getRequestURI(),
                request.getMethod(),
                request.getQueryString(),
                this.getBody(request),
                joinPoint.getSignature(),
                JSONUtil.toJsonStr(filterArgs(joinPoint.getArgs())),
                outParams,
                time
        );
    }

    /**
     * 解析请求体
     *
     * @param request
     * @return
     */
    public String getBody(HttpServletRequest request) {
        int contentLength = request.getContentLength();
        if (contentLength < 0) {
            return StringUtils.EMPTY;
        }
        byte[] bytes = new byte[contentLength];
        try {
            ServletInputStream inputStream = request.getInputStream();
            inputStream.read(bytes);
            inputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return new String(bytes, 0, contentLength, StandardCharsets.UTF_8);
    }

    /**
     * 过滤参数
     *
     * @param args
     * @return
     */
    private List<Object> filterArgs(Object[] args) {
        return Arrays.stream(args).filter(object -> !(object instanceof MultipartFilter)
                && !(object instanceof HttpServletRequest)
                && !(object instanceof HttpServletResponse)
        ).collect(Collectors.toList());
    }

    /**
     * 判断路径是否需要记录日志
     *
     * @param requestURI
     * @return
     */
    private boolean shouldLog(String requestURI) {
        return loggingProperties.getIncludePaths().stream().anyMatch(pattern -> pathMatcher.match(pattern, requestURI));
    }
}

 

posted @ 2024-06-28 10:28  程序员小艺  阅读(25)  评论(0编辑  收藏  举报