AOP拦截日志不生效问题排查方法

日志是我们排查线上问题的主要手段,对于线上的访问性能统计等通常也会通过AOP方式统计方法耗时情况。最近项目中碰到了一个问题,一个用log4j的老项目增加性能统计日志,做法都很通用:

拦截日志的切面定义如下:

@Component
@Aspect
public class TimeLogIntercept {

    private final Logger logger = LoggerFactory.getLogger(TimeLogIntercept.class);
/**
     * 所有serviceClass的类的所有public方法
     */
@Pointcut("execution(public * com.test..*ServiceImpl.*(..))")
    public void serviceClass() {
    }

    /**
     * 所有serviceClass的类的所有public方法
     */
@Pointcut("execution(public * com.test..*Dao.*(..))")
    public void daoClass() {
    }

    /**
     * 所有controller的类的所有public方法
     */
@Pointcut("execution(public * com.test.web..*Controller.*(..))")
    public void controllerClass() {
    }

    @Around("serviceClass() || daoClass() || controllerClass()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        Long startTime = 0L;
String methodName = "";
        try {
            startTime = System.currentTimeMillis();
MethodSignature joinPointObject = (MethodSignature) pjp.getSignature();
Method method = joinPointObject.getMethod();
methodName = pjp.getTarget().getClass().getName();
methodName = methodName + "." + method.getName();
Object proceed = pjp.proceed();
            return proceed;
} finally {
            Long endTime = System.currentTimeMillis();
            long time = endTime - startTime;
            if (time > 1000) {
                logger.warn("  cost time:" + time + "ms." + "methodName is ->" + methodName);
}
logger.warn("  cost time:" + time + "ms." + "methodName is ->" + methodName);
}
 }
}

log4j的配置如下:
# performanceFilter
log4j.appender.PA=org.apache.log4j.DailyRollingFileAppender
log4j.appender.PA.file=../logs/wf_server_performance.log
log4j.appender.PA.DatePattern='.'yyyy-MM-dd
log4j.appender.PA.layout=org.apache.log4j.PatternLayout
log4j.appender.PA.layout.ConversionPattern=[%p]\t%d\t[%t]\t%c{3}\t(%F\:%L)\t-%m%n
log4j.appender.PA.bufferSize=10000
log4j.logger.com.test.TimeLogInterceptor

(1)Logger对象有问题应该用log4j的Logger对象,正确方法是 Logger log = Logger.getLogger(TimeLogInterceptor.class);
改了上面之后,发现还是不打印日志,那应该问题出在AOP上面
检查Spring配置发现确认AOP配置有问题,原来的老项目配置并没有用AOP切面,所以增加了切面相关的配置:增加schema文件声明:
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
 http://www.springframework.org/schema/aop
              http://www.springframework.org/schema/aop/spring-aop-4.0.xsd"
还需要增加:
<aop:aspectj-autoproxy />
测试后发现日志终于可以正常输出了,解决问题!

相关推荐