Springboot项目用SpringAOP获取用户的基本操作日志

一、日志的重要性

对于一个应用程序来说日志记录是必不可少的一部分。线上问题追踪,基于日志的业务逻辑统计分析等都离不日志。

二、实现核心代码(本文不做持久层操作,只提示切入点)

1.创建新的Springboot项目,我使用之前已经创建过的:hello-rabbit
2.核心依赖

<parent>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-parent</artifactId>
	<version>2.2.2.RELEASE</version>
	<relativePath/> 
</parent>

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-aop</artifactId>
</dependency>

<dependency>
	<groupId>org.projectlombok</groupId>
	<artifactId>lombok</artifactId>
	<optional>true</optional>
</dependency>
        <!--spring boot web的依赖-->
        
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</dependency>

3.创建包com.basic.hellorabbit.aspect,创建日志切面操作类LogAspect.java

package com.basic.hellorabbit.aspect;

import com.basic.hellorabbit.entity.RequestLog;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.util.ArrayList;
import java.util.Date;

/**
* @Description:    日志切面操作
* @Author:         Joe
* @CreateDate:     2020/3/18 13:11
*/
@Aspect
@Component
public class LogAspect {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    RequestLog requestLog = null;

    /**
     * 定义一个切面(第1*:所有请求;第2*:com.basic.hellorabbit.controller下所有类;第3*:所有方法;..任何参数)
     */
    @Pointcut("execution(* com.basic.hellorabbit.controller.*.*(..))")
    public void logs(){
    }

    /**
     * 切面之前
     * @param joinPoint
     */
    @Before("logs()")
    public void doBefore(JoinPoint joinPoint){
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        String url = request.getRequestURL().toString();
        String ip = request.getRemoteAddr();
        String classMethod = joinPoint.getSignature().getDeclaringTypeName()+"."+joinPoint.getSignature().getName();
        Object[] args = joinPoint.getArgs();
        ArrayList<Object> objects = new ArrayList<>();
        for (int i = 0; i < args.length; i++) {
            objects.add(args[i]);
        }
        requestLog = new RequestLog(url,ip,classMethod,objects,new Date());
        logger.info("request:{}",requestLog);
    }

    /**
     * 请求之后
     */
    @After("logs()")
    public void doAfter(){
    }

    /**
     * 方法执行完返回结果
     * @param result
     */
    @AfterReturning(returning = "result",pointcut = "logs()")
    public void doAfterReturn(Object result){
        logger.info("return:"+result);
        requestLog.setResult(result);
        
        /*此处可加入写入数据库操作*/
        
        System.out.println(requestLog);
    }
}

4.创建包com.basic.hellorabbit.controller,创建类IndexController.java

package com.basic.hellorabbit.controller;

import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class IndexController {

    @RequestMapping(value ="/{id}/{name}",method = RequestMethod.GET)
    public String index(@PathVariable Integer id, @PathVariable String name){
        System.out.println("测试index方法");
        return "test";
    }
}

5.创建包com.basic.hellorabbit.entity,创建日志记录类RequestLog.java

package com.basic.hellorabbit.entity;

import lombok.Data;
import java.util.Date;

/**
* @Description:    日志类
* @Author:         Joe
* @CreateDate:     2020/3/18 13:36
*/
@Data
public class RequestLog {
    /**
     * 访问的url
     */
    private String url;
    /**
     * 访问的IP
     */
    private String ip;
    /**
     * 访问类的方法
     */
    private String classMethod;
    /**
     * 请求参数的值
     */
    private Object args;
    /**
     * 操作时间
     */
    private Date createTime;
    /**
     * 返回结果
     */
    private Object result;
    public RequestLog() {
    }

    public RequestLog(String url, String ip, String classMethod, Object args, Date createTime) {
        this.url = url;
        this.ip = ip;
        this.classMethod = classMethod;
        this.args = args;
        this.createTime = createTime;
    }

}

三、测试如图

在这里插入图片描述
在这里插入图片描述

四、异常、注意及建议

注意

1.有时候本地测试的IP是:0:0:0:0:0:0:0:1,这是ipv6的表现形式,对应ipv4来说相当于127.0.0.1,也就是本机。
建议
1.1 该用本机自己的IP地址访问;
1.2 将localhost改为127.0.0.1;
1.3修改C:\Windows\System32\drivers\etc\hosts这个文件,文件中的 # ::1 localhost 这一行被注释掉
2. 获取输入参数值的问题,出现类型异常,我使用遍历

后续建议

由于日志操作比较频繁且数据量大,建议抛给RabbitMQ等消息队列处理以减少数据库I/O压力

RabbitMQ搭建和使用,可以去看消息队列——RabbitMQ在Centos的基本搭建消息队列——RabbitMQ与Springboot的简单使用

发布了23 篇原创文章 · 获赞 3 · 访问量 1218

猜你喜欢

转载自blog.csdn.net/Joe14103/article/details/104942407
今日推荐