SpringBoot使⽤切⾯+注解实现对所有请求的⽇志记录到数据库中
业务场景:项⽬拆分微服务,恰巧鄙⼈负责⼏个基础的服务,各种对接其他服务。到后期运维,接各种锅:我调⽤你接⼝了,你那数据不对。我传递是这个参数,你那处理的有问题......。只好加上⽇志记录,业务场景就是:防⽌背锅!
1.定义注解
package com.haier.hwork.qwrgqk.business.annotation;
import java.lang.annotation.*;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface OperationLog {
String value() default "";
//1-增删改,2-查询,默认是1
int type() default 1;
}
2.定义AOP
@Aspect
@Component
public class OperationLogAspect {
@Autowired
private TlOperationLogDao tlOperationLogDao;
//扫描使⽤这个注解的⽅法
@Pointcut("@annotation(com.haier.hwork.qwrgqk.business.annotation.OperationLog)")
public void logPointCut() {}
@Around("logPointCut()")
public Object around(ProceedingJoinPoint point) throws Throwable {
Date beginTime=new Date();
String result=null;
String status=null;
//执⾏代码,都加try catch,即使出错也不能影响主进程
try {
Object obj = point.proceed();//放⾏请求的主进程并拿到返回值
if(obj!=null) {
JSONString(obj);
}
status="success";
return obj;
} catch (Exception e) {
//请求执⾏出错
Message();
status="error";
throw e;
} finally {
//⽆论成功失败,都保存下⽇志
saveLog(point, beginTime, new Date(), result, status);
}
}
//保存⽇志
springboot aopprivate void saveLog(ProceedingJoinPoint joinPoint, Date beginTime, Date endTime, String result, String status) {
TlOperationLog tlOperationLog=new TlOperationLog();
try {
MethodSignature signature = (MethodSignature) Signature();
Method method = Method();
OperationLog annotation = Annotation(OperationLog.class);
int type=1;//注解类型
if (annotation != null) {
//注解上的描述
tlOperationLog.setOperateModule(annotation.value());
//注解类型
tlOperationLog.setOperateType(String.pe()));
pe();
}
//记录⼊参
Args()!=null) {
try {
tlOperationLog.Args()));
} catch (Exception e) {
e.printStackTrace();
}
}
//如果注解类型是1(增删改)或者是2(查询)报错,记录返回值,如果是查询正常就不记录,有可能返回值太多
if(type==1 || "error".equals(status)) {
tlOperationLog.setResult(result);
}
tlOperationLog.setStartTime(beginTime);//记录请求开始时间
tlOperationLog.setEndTime(endTime);//记录请求结束时间
tlOperationLog.setStatus(status);//记录执⾏状态
HttpServletRequest request = HttpServletRequest();
if (request != null) {
tlOperationLog.Header(HttpHeaders.USER_AGENT));//记录请求头信息
tlOperationLog.Header(Constant.HEADER_CURRENT_USER));//获取登录⼈,登录信息放在了header⾥
RequestURL()!=null) {//记录请求地址
tlOperationLog.RequestURL().toString());
}
}
} catch (Exception e) {
e.printStackTrace();
}
//启动⼀个线程,执⾏报错⽇志,防⽌影响主请求
new Thread() {
@Override
public void run() {
try {
//保存数据到数据库
tlOperationLogDao.insertSelective(tlOperationLog);
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
}
}
3.配置需要记录⽇志的⽅法
@PostMapping("/save")
@OperationLog("新增APP TOKEN管理")
public BaseResponse save() {
return ResponseMsgUtil.success(tsSysAppTokenService.save());
}
凡是加上OperationLog注解的⽅法,都会记录⽇志,注解参数需要⼀个描述当前⽅法的字符串,会记录到数据库中。另外还需要参数type,⾮必填,默认1,代表是增删改,type=2代表查询。@OperationLog("新增APP TOKEN管理")
@OperationLog(value="查询管理客户接⼝", type=2)
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论