springboot整合log4j日志记录
我们在做项目的时候不可避免的需要接触到日志,通过日志我们可以获取许多重要的信息:
比如:
xxx在什么时间执行了删除等操作,需要进行记录
方法的执行时长,方便我们后续进行优化
项目运行一段时间之后,可能由于数据问题,网络问题,内存问题等出现异常。这时日志可以帮助开发人员快速定位错误位置,更快的解决错误。
在大数据时代,日志可以帮我们确定用户的喜好,比如点击哪个模块、超链接最多,搜索的那个词汇最多
下面准备好一个简单的springboot项目,具体可以参考我的另一篇博客
springboot入门测试
在这个项目的基础上我们加入spring-aop、日志、以及lombok依赖
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j</artifactId>
<version>1.3.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
<version>2.2.1.RELEASE</version>
</dependency>
spring-aop依赖:支持我们增强代码
日志、以及lombok依赖:用来支持lombok输出日志
然后定义一个aop处理日志的类
package com.usian.Aspect;
//Aop处理日志的类
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.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.Enumeration;
@Component
@Aspect
@Slf4j
public class MyAspect {
@Before("execution(* com.usian.controller.HelloSpringBoot.log(..))")
public void doBefore(JoinPoint joinPoint) throws Throwable{
System.out.println("前置方法执行了...");
//接收请求内容
ServletRequestAttributes requestAttributes =(ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
//获取请求
HttpServletRequest request = requestAttributes.getRequest();
//记录下请求内容
log.info("url:"+request.getRequestURI().toString());
log.info("HTTP_METHOD : "+request.getMethod());
log.info("IP:"+request.getRemoteAddr());
//获取请求参数属性的集合
Enumeration<String> enu = request.getParameterNames();
//遍历集合
while (enu.hasMoreElements()){
//获取请求参数的属性
String name = enu.nextElement();
//request.getParameter(name)
log.info("name:{},value:{}",name,request.getParameter(name));
}
}
/**
* returing:该属性指定一个形参名,用于表示Advice方法中可定义与此同名的形参,
* 该形参可用于访问目标方法的返回值。除此之外,
* 在Advice方法中定义该形参(代表目标方法的返回值)时指定的类型,
* 会限制目标方法必须返回指定类型的值或没有返回值。
* @param o
*/
@AfterReturning(value = "execution(* com.usian.controller.HelloSpringBoot.log(..))",returning = "o")
public void doAfter(Object o){
System.out.println("后置方法执行了...");
log.info("response"+o.toString());
}
}
@Component :表示把bean交给spring容器管理
@Aspect:表名这个类是一个切面类
@Slf4j:lombok里面的注解,用来引入日志
@Before(“execution( com.usian.controller.HelloSpringBoot.hello(…))”)
Spring通知分为五种:*
前置通知:调用目标组件前,调用方面组件(before) 后置通知:调用目标组件后,调用方面组件(after-returning
最终通知:调用目标组件后,在finally里调用方面组件(after)
异常通知:目标组件发生异常时,调用方面组件。(after-throwing)
环绕通知:调用目标组件前、后,分别调用一次方面组件。(around)
每种通知的用法这里不做过多描述
这里我们用前置通知和后置通知
里面的execution()是最常用的切点函数,用来确定要被增强的方法,
星号表示所有的类,…表示参数任意
然后我们在controller里定义我们要被增强的方法
@RequestMapping("/log")
public void log(){
log.info("hello,log");
}
运行测试