Springboot记录日志

Springboot + AOP记录日志

Springboot对日志的记录,并保存到数据库中

1.pom.xml文件导入aop

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

2.自定义注解

@Target:描述注解能够作用的位置
@Retention:描述注解被保留的阶段
​	1、RetentionPolicy.SOURCE:注解只保留在源文件,当Java文件编译成class文件的时候,注解被遗弃;
​	2、RetentionPolicy.CLASS:注解被保留到class文件,但jvm加载class文件时候被遗弃,这是默认的生命周期;
​	3、RetentionPolicy.RUNTIME:注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在;
@Documented:描述注解是否被抽取到api文档中
@Inherited:描述注解是否被子类继承

@Documented
@Inherited
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface LogAnno {
    String value(); //描述,可自行扩展
}

3.切面类

这其中列出了日志的一些属性,并没有存入数据库,请自行按需编写日志实体类并存入数据库

@Component
@Aspect
public class LogAopAspect {
    @Around("@annotation(com.victor.SpringbootQuartz.myAnno.LogAnno)")
    public Object aroundAdvice(ProceedingJoinPoint pjp) {
        //1.获取方法签名
        MethodSignature signature = (MethodSignature) pjp.getSignature();
        //2.获取方法
        Method method = signature.getMethod();
        //获取请求的类名
        String className = pjp.getTarget().getClass().getName();
        System.out.println("方法所在的类: " + className);
        System.out.println("方法名: " + method.getName());
        //3.获取方法上自定义的注解
        LogAnno annotation = method.getAnnotation(LogAnno.class);
        System.out.println("操作描述: " + annotation.value());
        System.out.println("参数: " + Arrays.toString(signature.getParameterNames()));
        System.out.println("输入参数: " + Arrays.toString(pjp.getArgs()));

        //获取IP地址
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        System.out.println("IP地址: " + IpAdrressUtil.getIpAdrress(request));


        Object result = null;
        try {
            //4.调用方法
            result = pjp.proceed();
            System.out.println("操作结果: 执行成功");
        } catch (Throwable throwable) {
            //5。出现异常
            System.out.println("操作结果: 执行失败");
        } finally {
            //6。记录操作时间,记录到数据库表中
            System.out.println("操作时间:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        }
        return result;
    }
}

4.获取IP地址所需的工具类

public class IpAdrressUtil {
	
	public static String getIpAdrress(HttpServletRequest request) {
		 	String ip = null;

		    //X-Forwarded-For:Squid 服务代理
		    String ipAddresses = request.getHeader("X-Forwarded-For");
		    String unknown = "unknown";
		    if (ipAddresses == null || ipAddresses.length() == 0 || unknown.equalsIgnoreCase(ipAddresses)) {
		        //Proxy-Client-IP:apache 服务代理
		        ipAddresses = request.getHeader("Proxy-Client-IP");
		    }

		    if (ipAddresses == null || ipAddresses.length() == 0 || unknown.equalsIgnoreCase(ipAddresses)) {
		        //WL-Proxy-Client-IP:weblogic 服务代理
		        ipAddresses = request.getHeader("WL-Proxy-Client-IP");
		    }

		    if (ipAddresses == null || ipAddresses.length() == 0 || unknown.equalsIgnoreCase(ipAddresses)) {
		        //HTTP_CLIENT_IP:有些代理服务器
		        ipAddresses = request.getHeader("HTTP_CLIENT_IP");
		    }

		    if (ipAddresses == null || ipAddresses.length() == 0 || unknown.equalsIgnoreCase(ipAddresses)) {
		        //X-Real-IP:nginx服务代理
		        ipAddresses = request.getHeader("X-Real-IP");
		    }

		    //有些网络通过多层代理,那么获取到的ip就会有多个,一般都是通过逗号(,)分割开来,并且第一个ip为客户端的真实IP
		    if (ipAddresses != null && ipAddresses.length() != 0) {
		        ip = ipAddresses.split(",")[0];
		    }

		    //还是不能获取到,最后再通过request.getRemoteAddr();获取
		    if (ip == null || ip.length() == 0 || unknown.equalsIgnoreCase(ipAddresses)) {
		        ip = request.getRemoteAddr();
		    }
		    return ip;
	  }
	
	
}

5.编写测试的Controller

@RestController
public class HelloController {

    @GetMapping("/hello")
    @LogAnno("获取了hello world")
    public String HelloWorld(String name){
        return "<h1>hello world</h1>";
    }
}

6.测试结果

方法所在的类: com.victor.SpringbootQuartz.controller.HelloController
方法名: HelloWorld
操作描述: 获取了hello world
参数: [name]
输入参数: [11]
IP地址: 127.0.0.1
操作结果: 执行成功
操作时间:2021-04-15 15:32:15
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值