SpringBoot整合AOP做日志

前言

目前已经实现日志和权限认证功能,配置起来可能麻烦点,但是注意版本问题时,其他的应该没什么问题。
此项目是用springboot+springsecurity+aop实现权限认证和日志功能的,请结合项目所需使用。


一、导入依赖?

<!--aop日志-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
	<version>2.6.6</version>
</dependency>
<!--获取浏览器信息工具-->
<dependency>
    <groupId>eu.bitwalker</groupId>
    <artifactId>UserAgentUtils</artifactId>
    <version>1.21</version>
</dependency>

二、编写配置

1.Log

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)//注解放置的目标位置,METHOD是可注解在方法级别上
@Retention(RetentionPolicy.RUNTIME)//注解在哪个阶段执行
public @interface Log {
    
    
    String value() default "";
}

2.AopLog

import cn.sms.util.LogUtils;
import cn.sms.core.security.SecurityUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
 * Description:LogAspect
 * Date: 2022/4/19 9:51
 * @Version: 1.0
 */
@Aspect
@Component // 开启组件扫描
@Slf4j
public class AopLog {
    
    
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
    ThreadLocal<Long> startTime = new ThreadLocal<>();
    //定义切点(xxx修改成自己的log地址)
    @Pointcut("@annotation(cn.xxx.aop.Log)")
    public void aopWebLog() {
    
    
    }
    //使用环绕通知
    @Around("aopWebLog()")
    public Object myLogger(ProceedingJoinPoint pjp) throws Throwable {
    
    
        startTime.set(System.currentTimeMillis());
        //使用ServletRequestAttributes请求上下文获取方法更多
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        String className = pjp.getSignature().getDeclaringTypeName();
        String methodName = pjp.getSignature().getName();
        //获取方法的@Log自定义内容
        MethodSignature signature = (MethodSignature) pjp.getSignature();
        Method method = signature.getMethod();
        Log myLog = method.getAnnotation(Log.class);
        //使用数组来获取参数
        Object[] array = pjp.getArgs();
        ObjectMapper mapper = new ObjectMapper();

        //执行函数前打印日志
        log.info("调用前:{}:{},传递的参数为:{}", className, methodName, mapper.writeValueAsString(array));
        log.info("URL:{}", request.getRequestURL().toString());
        log.info("请求类型:{}", request.getMethod());
        log.info("IP地址:{}", request.getRemoteAddr());
        log.info("IP地址:{}", LogUtils.getIp(request));
        log.info("浏览器:{}", LogUtils.getBrowser(request).equals("Unknown") ? LogUtils.getBrowser(request):"");
        log.info("操作系统:{}", LogUtils.getOS(request).equals("Unknown") ? LogUtils.getOS(request):"");
        log.info("用户姓名:{}", SecurityUtils.getCurrentUsername());
        log.info("访问时间:{}", simpleDateFormat.format(new Date()));
        log.info("方法注释:{}", myLog.value());

        //调用整个目标函数执行
        Object obj = pjp.proceed();
        //执行函数后打印日志
        log.info("调用后:返回值为:{}", mapper.writeValueAsString(obj));
        log.info("耗时:{}ms", System.currentTimeMillis() - startTime.get());
        调用service层添加日志方法
        return obj;
    }
}

3.LogUtils

import eu.bitwalker.useragentutils.Browser;
import eu.bitwalker.useragentutils.OperatingSystem;
import eu.bitwalker.useragentutils.UserAgent;
import javax.servlet.http.HttpServletRequest;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.InetAddress;
import java.net.UnknownHostException;
/**
 * Description:IPUtil
 * Date: 2022/4/19 11:15
 * @Version: 1.0
 */
public class LogUtils {
    
    
    private static final char SEPARATOR = '_';
    private static final String UNKNOWN = "unknown";
    /**
     * 获取ip地址
     */
    public static String getIp(HttpServletRequest request) {
    
    
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
    
    
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
    
    
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
    
    
            ip = request.getRemoteAddr();
        }
        String comma = ",";
        String localhost = "127.0.0.1";
        if (ip.contains(comma)) {
    
    
            ip = ip.split(",")[0];
        }
        if  (localhost.equals(ip))  {
    
    
            // 获取本机真正的ip地址
            try {
    
    
                ip = InetAddress.getLocalHost().getHostAddress();
            } catch (UnknownHostException e) {
    
    
                e.printStackTrace();
            }
        }
        return ip;
    }
    /**
     * 获取浏览器信息
     * @param request
     * @return
     */
    public static String getBrowser(HttpServletRequest request){
    
    
        UserAgent userAgent = UserAgent.parseUserAgentString(request.getHeader("User-Agent"));
        Browser browser = userAgent.getBrowser();
        return browser.getName();
    }
    /**
     * 获取系统
     * @param request
     * @return
     */
    public static String getOS(HttpServletRequest request){
    
    
        UserAgent userAgent = UserAgent.parseUserAgentString(request.getHeader("User-Agent"));
        OperatingSystem os = userAgent.getOperatingSystem();
        return os.getName();
    }
    /**
     * 获取堆栈信息
     */
    public static String getStackTrace(Throwable throwable){
    
    
        StringWriter sw = new StringWriter();
        try (PrintWriter pw = new PrintWriter(sw)) {
    
    
            throwable.printStackTrace(pw);
            return sw.toString();
        }
    }
}

三、使用

在controller的方法中使用 @Log("xxxxxxx") 注解

猜你喜欢

转载自blog.csdn.net/SmileSunshines/article/details/124276266