使用Spring Boot和AOP进行性能记录

ndr*_*one 5 java spring spring-aop spring-boot

我正在尝试根据这篇文章实现性能日志记录:http : //www.baeldung.com/spring-performance-logging。我想记录每个控制器端点和每个数据库请求。如果您想查看整个项目,可以在这里找到。当我命中端点时,什么都没有记录。在拦截器类中放置一个断点也不会停止。我已经将软件包的日志记录设置为跟踪级别。我想念什么?我相信这是与之相关的,@PointCut但是在查看了文档之后,我相信我是正确的。

拦截器

public class PerformanceMonitorInterceptor extends AbstractMonitoringInterceptor
{
    @Override
    protected Object invokeUnderTrace(MethodInvocation methodInvocation, Log log) throws Throwable
    {
        String name = createInvocationTraceName(methodInvocation);
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        log.trace(String.format("Method %s execution start at %s", name, LocalDateTime.now()));

        try
        {
            return methodInvocation.proceed();
        }
        finally
        {
            stopWatch.stop();
            log.trace(String.format("Method %s execution took %dms (%s)", name,
                stopWatch.getTotalTimeMillis(), DurationFormatUtils
                    .formatDurationWords(stopWatch.getTotalTimeMillis(), true, true)));
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

组态

@Configuration
@EnableAspectJAutoProxy
@Aspect
public class ContactControllerPerfLogConfig
{
    @Bean
    public PerformanceMonitorInterceptor performanceMonitorInterceptor()
    {
        return new PerformanceMonitorInterceptor();
    }

    // Any public method on the ContactController
    @Pointcut("execution(public * org.example.phonebookexample.app.contact.ContactController.*(..))")
    public void contactControllerMonitor()
    {
    }

    @Bean
    public Advisor contactControllerMonitorAdvisor(
        PerformanceMonitorInterceptor performanceMonitorInterceptor)
    {
        AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
        pointcut.setExpression("org.example.phonebookexample.app.contact.ContactControllerPerfLogConfig.contactControllerMonitor()");
        return new DefaultPointcutAdvisor(pointcut, performanceMonitorInterceptor);
    }
}
Run Code Online (Sandbox Code Playgroud)

Sab*_*han 5

AbstractTraceInterceptor我从来不明白如果你要定制它的重要性。

我总觉得代码对我来说太多了,@Around如果你已经@Aspect准备好了,可以通过一个简单的建议来实现。

    @Around("execution(* com..*.*(..))")
    public Object logStartAndEnd(ProceedingJoinPoint pjp) throws Throwable{
        long startTime = System.currentTimeMillis();
        String className = pjp.getTarget().getClass().getCanonicalName();
        String methodName = pjp.getSignature().getName();
        log.info("started method : " + className+"."+methodName);

        Object obj;
        try {
            obj = pjp.proceed();
            log.info("finished method : " + className+"."+methodName);
            return obj;
        } catch (Throwable e) {
            throw e;
        }finally {
            log.info("Method "+className+"."+methodName+" execution lasted:"+((System.currentTimeMillis() - startTime )/1000f)+" seconds");
        }
    }
Run Code Online (Sandbox Code Playgroud)


jih*_*hor 3

AbstractTraceInterceptor实现MethodInterceptorinvoke()实现其方法如下:

public Object invoke(MethodInvocation invocation) throws Throwable {
    Log logger = getLoggerForInvocation(invocation);
    if (isInterceptorEnabled(invocation, logger)) {
        return invokeUnderTrace(invocation, logger);
    }
    else {
        return invocation.proceed();
    }
}
Run Code Online (Sandbox Code Playgroud)

因此,Interceptor 类的记录器需要设置为TRACE. 对于基本的PerformanceMonitorInterceptor,就这样org.springframework.aop.interceptor.PerformanceMonitorInterceptor。由于您已经编写了自己的拦截器,因此您必须为自己的类设置日志记录级别。查看JamonPerformanceMonitorInterceptor替代方法的示例,如果需要,可以跟踪所有调用,无论日志记录级别如何。

为了完整起见,我还将发布一个 xml 配置示例,因为当涉及到 AOP 时,Spring java 配置与 xml 配置相比并不那么优雅:

<bean id="performanceMonitorInterceptor" class="org.springframework.aop.interceptor.PerformanceMonitorInterceptor"/>

<aop:config>
    <aop:pointcut id="contactControllerMonitor" expression="execution(public * org.example.phonebookexample.app.contact.ContactController.*(..))" />
    <aop:advisor id="contactControllerMonitorAdvisor" pointcut-ref="contactControllerMonitor" advice-ref="performanceMonitorInterceptor"/>
</aop:config>
Run Code Online (Sandbox Code Playgroud)

可以将此配置导入到您的 java 配置中,如下所示:

@ImportResource("classpath:/aop-config.xml")
public class MainConfig { ... }
Run Code Online (Sandbox Code Playgroud)