前文介绍过使用自定义的接口使用日志收集,好处是,需要哪个类打印日志的,直接注入类就可以,而不是所有方法都打印日志,缺点就是手动另入,如果想一把这个类下所有的请求都打印日志,那就都要手动干预,麻烦并且,还入侵了别人的代码,其它人要是增加了请求方法,还得去注入日志类,
今天就介绍下,也是常用的配置表达式的方式采集日志,无侵入代码,全量收集,写请求的人或者是写代码的人不需要需要知道有日志收集这回事,
下面直接代码了, 都 是些比较简单的代码,希望对大家有点帮助 都是自己亲自测试过的
@Aspect
@Component
这两个必须注入的接口类
/**
* @author lmc
* @version date:2018年9月30日 下午2:39:29
*/
package com.yitai.tms.version.app;
import java.util.Arrays;
import java.util.Date;
import javax.servlet.http.HttpServletRequest;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
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;
/**
* @author
* @Email huyang@126.com
* @date 2018年9月30日
* 下面应用的一些配置,都经过测试通过
*/
@Aspect
@Component
public class RequestAspect {
private static final Logger logger= LoggerFactory.getLogger(LogWebAspect.class);
// 定义切点 Pointcut
@Pointcut("execution(* com.yitai.tms.version.controller.*.*(..))")//Pointcut表示式
public void pointcut(){} //Point签名
//表示匹配com.yitai.tms.version.dao..*包及其子包下的所有方法 点号就路径
@Pointcut("execution(* com.yitai.tms.version.service.impl.*.*(..))")
public void pointcutB(){}
//Pointcut定义时,还可以使用&&、||、! 这三个运算 指定签名
// @Before("execution(* com.yitai.tms.version.controller.*.*(..))") //也可直接定义execution表达式使用,配置表示式测试完美通过
@Before("pointcut() || pointcutB()") // 或者 满足这两个配置都执行
public void before(JoinPoint joinPoint){
// 接收到请求,记录请求内容
logger.info("LogWebAspect.doBefore()");
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
//有格式的打印日志,收集日志信息到ES
logger.info("*************************************************** "+new Date().getTime()+"|" + request.getRequestURL().toString()+"|"+request.getMethod()+"|"+
joinPoint.getSignature().getDeclaringTypeName() +"|"+Arrays.toString(joinPoint.getArgs()));
}
//所有配置方法调用后再执行的方法
// @AfterReturning(returning = "ret", pointcut = "execution(* com.yitai.tms.version.controller.*.*(..))")//两个配置的类下所有方法
@AfterReturning(returning = "ret", pointcut = "pointcut() || pointcutB()")//两个配置的类下所有方法
public void doAfterReturning(Object ret) throws Throwable {
// 处理完请求,返回内容
logger.info("doAfterReturning : " + ret);
}
}
下面的是把公用的采集日志的方法放到一个类里面,然后指定绝对路径找到Pointcut签名的方法,就会指定收集配置类的信息
特别注意些方法 @Before("com.sagage.aop.Pointcuts.logMessage()") 绝对路径
/*还可以将一些公用的Pointcut放到一个类中,以供整个应用程序使用,如下:*/
public class Pointcuts {
@Pointcut("execution(* *Message(..))")
public void logMessage(){}
@Pointcut("execution(* *Attachment(..))")
public void logAttachment(){}
@Pointcut("execution(* *Service.*(..))")
public void auth(){}
}
/*在使用上面定义Pointcut时,指定完整的类名加上Pointcut签名就可以了,如:*/
@Before("com.sagage.aop.Pointcuts.logMessage()") //重点是包名必须找到签名的讲法 ,也就是Pointcut定义方法
public void beforedfff(JoinPoint joinPoint) {
System.out.println("Logging before " + joinPoint.getSignature().getName());
}
完结