由于项目需求,要做一个日志系统关联到各个项目上,所以在网上查了查有关日志的一些资料,最终决定使用spring AOP+ELK进行日志的收集分析。
正题开始:
只要是使用spring AOP进行切面切割方法。在方法上添加注解进行标注该方法是做什么的。然后进行记录。
aop代码:
@Aspect
@Component
public class LogAop{
private static Logger logger = Logger.getLogger("mzactionlogs");
@After("execution (public * com.neusoft.agileweb2.mz.demonew.g.manager.impl.*.*(..))")
public void aftercs(JoinPoint joinpoint){
//System.out.println("测试1");
}
@Before(value="execution (public * com.neusoft.agileweb2.mz.demonew.g.manager.impl.*.*(..)) && @annotation(com.neusoft.mz.logs.comment.MzLogs)")
public void beforecs(JoinPoint joinpoint) throws ClassNotFoundException, IllegalArgumentException, IllegalAccessException, NoSuchMethodException, SecurityException{
//获取方法名称
String methodName = joinpoint.getSignature().getName();
//获取参数
List<Object> list = Arrays.asList(joinpoint.getArgs());
//获取类名称
String classType = joinpoint.getTarget().getClass().getName();
Class clazz=Class.forName(classType);
//获取该类的所有方法
Method[] methods=clazz.getMethods();
//方法对应的参数列表的class
Class[] paramtype=null;
//该方法上的MzLogs注解类
MzLogs mzlogs=null;
//循环所有方法获取到需要的方法,根据methodName判断
for(Method method : methods){
String methodname = method.getName();
if(methodname.equals(methodName)){
paramtype=method.getParameterTypes();
//获取到注解上的类
mzlogs=method.getAnnotation(MzLogs.class);
}
}
if(mzlogs.isOpen()){
final Authentication ctx = SecurityContextHolder.getContext().getAuthentication();
if(ctx!=null){
final SessionUserBean user = (SessionUserBean)ctx.getPrincipal();
logger.info(new BusinessLog(user.getId(),user.getCurrentGroup().getName(),user.getFullname(),mzlogs.value(),list.toString()).toString());
}else{
logger.info(new BusinessLog(null,null,null,mzlogs.value(),list.toString()).toString());
}
}
}
}
在网上也查找了一下,有人说直接用
@Pointcut(value="args(param)", argNames="param")
这种方法获取注解上的值,但是我进行了多种尝试,并没有好用。所以利用反射区获取了该方法上的注解。由于业务场景不需要重载,所以利用反射获取方法时,没考虑重载的因素。
注解代码:
package com.neusoft.mz.logs.comment;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MzLogs {
//该注解方法的中文名称
String value() default "未命名方法";
//该注解方法是否开启日志输出
boolean isOpen() default true;
}