简介
SLF4J是Simple Logging Facade for Java的缩写。它主要提供了Java目前现有日志框架的简单抽象。它使用户能够使用单个依赖项处理任何日志框架,例如:Log4j,Logback和JUL。也可以在运行/部署时迁移到对应的日志记录框架。
优点
*可以在部署时迁移到所需的日志记录框架。
*提供了对所有流行的日志框架的绑定。
*支持参数化日志记录消息。
*程序和日志记录框架分离。
*提供了一个简单的日志迁移工具。
常规使用
参看slf4j官网网站
参看易佰教程
这个模块需要的知识贮备
实际项目使用自定义注解和aop的方式来实现操作访问记录功能
自定义注解
参看Java的注解
AOP
Spring AOP简单样例
暂时不记录数据库,等学习完jpa后,在记录到数据中。
实践
maven文件
org.springframework.boot
spring-boot-starter-aop
目录结构
源码
定义记录那些信息Log类(Log.java)
package com.springboot.action.saas.common.logging.domain;
import lombok.Data;
import java.sql.Timestamp;
@Data
public class Log {
//描述
private String description;
//方法名
private String method;
//参数
private String params;
//日志类型
private String logType;
//请求ip
private String requestIp;
//请求耗时
private Long time;
//异常详细
private String exceptionDetail;
//请求实践
private Timestamp createTime;
//构造函数(代参)
public Log(String logType, Long time) {
this.logType = logType;
this.time = time;
}
}
日志记录业务接口(LogService.java)
package com.springboot.action.saas.common.logging.service;
import com.springboot.action.saas.common.logging.domain.Log;
import org.aspectj.lang.ProceedingJoinPoint;
import org.springframework.scheduling.annotation.Async;
/*
* 日志记录业务
*
*/
public interface LogService {
/*
* 记录日志,异步执行,不影响正常业务流程
* 参数 joinPoint 切面方法的信息,当前切入点各种信息
* log 要记录的日志信息有那些
* */
@Async
void save(ProceedingJoinPoint joinPoint, Log log);
}
日志记录业务接口实现(LogServiceImpl.java)
package com.springboot.action.saas.common.logging.service.impl;
import com.springboot.action.saas.common.logging.domain.Log;
import com.springboot.action.saas.common.logging.service.LogService;
import com.springboot.action.saas.common.utils.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
@Service
public class LogServiceImpl implements LogService {
/*
* 记录日志接口实现
**/
@Override
public void save(ProceedingJoinPoint joinPoint, Log log) {
//获取request 请求对象
HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes())
.getRequest();
//getSignature获取切面相关信息,比如方法名、目标方法参数等信息
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
//获取抽象类(代理对象)方法
Method method = signature.getMethod();
//返回该元素的指定类型的注释,这里是Log注解
com.springboot.action.saas.common.logging.annotation.Log aopLog = method.getAnnotation(com.springboot.action.saas.common.logging.annotation.Log.class);
//获取注解传递的参数
if (log != null) {
log.setDescription(aopLog.value());
}
//通过最笨的反射方法,获取方法路径
String methodName = joinPoint.getTarget().getClass().getName()+"."+signature.getName()+"()";
log.setMethod(methodName);
//参数处理
//获取参数值
Object[] argValues = joinPoint.getArgs();
//获取参数名
String[] argNames = ((MethodSignature)joinPoint.getSignature()).getParameterNames();
//组织参数列表
String params = "{";
if(argValues != null){
for (int i = 0; i < argValues.length; i++) {
params += " " + argNames[i] + ": " + argValues[i];
}
}
log.setParams(params + " }");
//获取IP地址
log.setRequestIp(StringUtils.getIP(request));
//输出下日志到控制台
System.out.println(log.toString());
}
}
配置切点和切点对应的动作(好多文档都说是通知)
LogAspect.java
package com.springboot.action.saas.common.logging.aspect;
import com.springboot.action.saas.common.logging.domain.Log;
import com.springboot.action.saas.common.logging.service.LogService;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
@Aspect
public class LogAspect {
//日志业务
@Autowired
private LogService logService;
//当前时间
private long currentTime = 0L;
/**
* 配置切入点, 匹配连接点的方法是否有Log注解,定义切点
*/
@Pointcut("@annotation(com.springboot.action.saas.common.logging.annotation.Log)")
public void logPointcut() {
// 该方法无方法体,主要为了让同类中其他方法使用此切入点
}
/**
* 配置环绕通知,使用在方法logPointcut()上注册的切入点,具体要通知在什么条件下执行和执行什么动作
*
* @param joinPoint join point for advice
*/
@Around("logPointcut()")
public Object logAround(ProceedingJoinPoint joinPoint){
//返回值
Object result = null;
//获取当前时间
currentTime = System.currentTimeMillis();
try {
//执行目标方法
result = joinPoint.proceed();
} catch (Throwable e) {
//抛异常
throw new RuntimeException(e.getMessage());
}
//创建日志对象
Log log = new Log("INFO",System.currentTimeMillis() - currentTime);
//记录日志
logService.save(joinPoint, log);
//返回目标方法的返回值
return result;
}
/**
* 配置异常通知,异常的日志也要记录
*
* @param joinPoint join point for advice
* @param e exception
*/
@AfterThrowing(pointcut = "logPointcut()", throwing = "e")
public void logAfterThrowing(JoinPoint joinPoint, Throwable e) {
//创建日志对象
Log log = new Log("ERROR",System.currentTimeMillis() - currentTime);
//异常设置
log.setExceptionDetail(e.getMessage());
//记录异常
logService.save((ProceedingJoinPoint)joinPoint, log);
}
}
REST接口
/**
* 显示所有Member,请求url:"http://xxx/member/v1/findall"
*
* @return List
*/
//这里增加了自定义日志注解
@Log("获取全部用户列表")
@RequestMapping(value = "/v1/findall")
public List findAllMember() {
return memberService.findAllMember();
}
实际运行效果
请求
http://localhost:8080/member/v1/findall
浏览器
{"success":true,"code":0,"data":[{"id":1,"phone":null,"password":null,"nickname":"demo1","email":null,"ctime":null,"utime":null,"last_login_time":null,"last_login_ip":null,"invite_code":null,"is_active":null,"is_delete":null},{"id":2,"phone":null,"password":null,"nickname":"demo2","email":null,"ctime":null,"utime":null,"last_login_time":null,"last_login_ip":null,"invite_code":null,"is_active":null,"is_delete":null}],"message":"","currentTime":1564631416588}
控制台
Log(description=获取全部用户列表, method=com.springboot.action.saas.modules.user.controller.MemberController.findAllMember(), params={ }, logType=INFO, requestIp=127.0.0.1, time=4, exceptionDetail=null, createTime=null)
打tag 1.0.4版本,提交代码。
git tag -a v1.0.4 -m "实现AOP日志信息获取"
git push origin v1.0.4
github地址:https://github.com/horacepei/springsaas