日志是在项目开发与运行阶段的“基础设施”,它可以帮助我们了解系统的运行轨迹,查找系统的运行异常等,接下来将介绍在SpringBoot中如何使用日志记录。
1.yml配置
首先,在yml配置文件中定义日志级别和文件存放位置:
logging:
level:
root: info
com.lsh: debug
file:
name: log/blog-dev.log
除此之外,SpringBoot还可以自定义logback-spring.xml的方式对logback日志配置。
2.AOP切面处理
采用AOP技术进行日志处理,用于记录请求内容和返回内容。Spring AOP技术允许我们以切面方式拦截所有请求,围绕切面前后进行日志处理即可。
创建LogAspect类如下,定义切面,切面前执行方法和切面返回方法;
我们需要记录的是前端请求的请求url,IP地址,请求方法,请求参数以及请求名
请求url和IP可以通过Servlet请求获取;请求方法和参数通过切面连接点Joinpoint获取
【完整代码】
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.Arrays;
/**
* @Description: 日志切面处理
* @Author: lsh
* @QQ: 1076437118
*/
@Aspect
@Component
public class LogAspect {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
//创建切面,拦截所有控制器下的所有方法
@Pointcut("execution(* com.lsh.controller.*.*(..))")
public void log() {}
@Before("log()")
public void doBefore(JoinPoint joinPoint) {
//获取ip,url
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();
RequestLog requestLog = new RequestLog(url, ip, classMethod, args);
logger.info("Request : {}", requestLog);
}
@AfterReturning(returning = "result", pointcut = "log()")
public void doAfterReturn(Object result) {
logger.info("Result : {}", result);
}
//封装日志信息类
private class RequestLog {
private String url;
private String ip;
private String classMethod;
private Object[] args;
public RequestLog(String url, String ip, String classMethod, Object[] args) {
this.url = url;
this.ip = ip;
this.classMethod = classMethod;
this.args = args;
}
@Override
public String toString() {
return "RequestLog{" +
"url='" + url + '\'' +
", ip='" + ip + '\'' +
", classMethod='" + classMethod + '\'' +
", args=" + Arrays.toString(args) +
'}';
}
}
}
3. 为什么项目里使用 slf4j 而不是 log4j 等其他日志系统?
slf4j,即简单日志门面(Simple Logging Facade for Java),它主要有以下两点优势:
slf4j 提供了各类日志记录库的接口,可以兼容各类日志系统。假设项目已经使用了log4j,而且你包含一个名为Apache Active MQ的库,这个库还依赖于另一个日志记录库logback的话,那么你还需要包含它们,那么添加和维护新的日志记录框架比较麻烦。
其次Slf4j还有一个占位符{ }功能,避免了字符串拼接,另外它是运行需要时创建,可以帮助我们节约内存资源。