LogAspect.java 3.18 KB
package vion.advice;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.lang.Opt;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.servlet.ServletUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
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.aspectj.lang.annotation.Pointcut;
import org.slf4j.MDC;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import vion.vo.UserVO;

import javax.servlet.http.HttpServletRequest;

/**
 * @author HlQ
 * @date 2024/1/17
 */
@Component
@RequiredArgsConstructor
@Aspect
@Slf4j
public class LogAspect {

    private final ObjectMapper objectMapper;

    @Pointcut("execution(* vion.controller.*.*(..))")
    public void logPointcut() {
    }

    @Before("logPointcut()")
    public void doBefore(JoinPoint joinPoint) throws JsonProcessingException {
        // 登录等接口,无需登录可访问,根据 token 获取当前用户会抛未登录的异常,需捕获进行处理
        String username = Opt.ofTry(() -> (UserVO) StpUtil.getTokenSession().get("curLoginUser"))
                .map(UserVO::getUsername)
                .orElse("未知");

        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (ObjUtil.isNull(attributes)) {
            return;
        }
        HttpServletRequest request = attributes.getRequest();

        request.setAttribute("startTime", System.currentTimeMillis());

        MDC.put("requestId", (String) request.getAttribute("requestId"));
        log.info("Request URL:{}, Method:{}, IP:{}, Operator:{}, Args:{}, Body:{}",
                request.getRequestURI(),
                request.getMethod(),
                ServletUtil.getClientIP(request),
                username,
                objectMapper.writeValueAsString(request.getParameterMap()),
                StrUtil.replaceChars(ServletUtil.getBody(request), " \r\n", "")
        );
    }

    @AfterReturning(pointcut = "logPointcut()", returning = "result")
    public void doAfterReturning(JoinPoint joinPoint, Object result) throws JsonProcessingException {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (ObjUtil.isNull(attributes)) {
            return;
        }
        HttpServletRequest request = attributes.getRequest();

        long startTime = (Long) request.getAttribute("startTime");
        long responseTime = System.currentTimeMillis() - startTime;

        String resStr = objectMapper.writeValueAsString(result);
        if (resStr.length() > 1000) {
            resStr = resStr.substring(0, 1000);
        }
        log.info("Response time: {} ms. Return value: {}",
                responseTime,
                resStr);
        MDC.remove("requestId");
    }

}