目地:
我们很多程序每天有大量用户访问,特别是一些增删改操作,如果每一笔操作都写一条SQL插入对程序的侵入太大了,但是这些操作又非常有必要保存。
方案:
这里考虑使用AOP拦截器,在接口请求时对@LogAround的注解进行切面拦截,通过前置通知获取返回的对象,然后遍历对象中的请求的属性和参数进行记录。
前置拦截与公共的3,4,5请看自定义注解通过aop拦截用户访问信息并存入到数据库中(-)
环绕拦截具体代码如下:
1,自定义一个前置@LogAround注解
package com.hcmony.sword.aspect.around;
import com.hcmony.sword.aspect.before.LogBefore;
import java.lang.annotation.*;
/**
*<h3>方法环绕操作日志记录</h3>
* <p>如果想使用广告操作前记录请使用{@link LogBefore}</p>
*
* @author hcmony
* @since V1.0.0, 2018/02/07 15:22
*/
@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface LogAround {
/**
* @return 要记录系统的名称。
*/
String keyName();
/**
* @return 操作类型
*/
String operType() default "";
/**
* @return 操作人
*/
String user() default "";
}
二,切面拦截有这个注解的方法,对这个方法的参数进行输出,我这里是打印到控制台,后面通过ELK收集起来,进行分析处理。
package com.hcmony.sword.aspect.around;
import com.hcmony.sword.aspect.LogAspect;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
/**
* <h3>环绕日志记录</h3>
* <p>可能存在问题,如果此方法失败,可能会影响到该方法注解的方法失败</p>
*
* @author hcmony
* @since V1.0.0, 2018/02/07 15:22
*/
@Aspect
public class LogAroundAspect extends LogAspect {
@Around("within(com.hcmony..*) && @annotation(logAround)")
public Object doAround(ProceedingJoinPoint point, LogAround logAround){
//开始时间
long startTime = System.currentTimeMillis();
//获取所有的参数
String params = getParams(point);
Object result = new Object();
try {
//执行方法,获取返回参数
result = point.proceed();
logger.info("返回参数是:{}" , result);
}catch (Throwable e){
logger.error(e.getMessage(),e);
}
String user = logAround.user();
if(StringUtils.isBlank(user)){
user = getUser(point);
}
logger.info("操作人:{},\n 操作内容:{},\n 参数:{}," +
"\n 系统是:{},,\n 返回参数是:\n 总耗时:{}s",
user,logAround.operType(),params,logAround.keyName(),result,excTime(startTime));
return result;
}
}