【问题标题】:How to log Spring Data JPA repository method execution time?如何记录 Spring Data JPA 存储库方法执行时间?
【发布时间】:2014-11-16 15:07:54
【问题描述】:

我有简单的 Spring Data JPA 存储库。

public interface UserRepository extends JpaRepository<UserEntity, Serializable>{ … }

有没有办法监控 Spring 生成的方法的执行时间(例如 findOne(…))?

【问题讨论】:

    标签: java spring jpa spring-data spring-data-jpa


    【解决方案1】:

    最简单的方法是使用CustomizableTraceInterceptor,如下所示:

    @Configuration
    @EnableAspectJAutoProxy
    public class SpringDataExecutionLoggingConfiguration {
    
      @Bean
      public CustomizableTraceInterceptor customizableTraceInterceptor() {
    
        CustomizableTraceInterceptor customizableTraceInterceptor = new CustomizableTraceInterceptor();
        customizableTraceInterceptor.setUseDynamicLogger(true);
        customizableTraceInterceptor.setExitMessage("Executed $[methodName] in $[invocationTime]");
        return customizableTraceInterceptor;
      }
    
      @Bean
      public Advisor advisor() {
    
        AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
        pointcut.setExpression("execution(public * org.springframework.data.repository.CrudRepository+.*(..))");
        return new DefaultPointcutAdvisor(pointcut, customizableTraceInterceptor());
      }
    }
    

    【讨论】:

    • 切入点不应该是:“execution(public * org.springframework.data.repository.Repository+.*(..))”?
    • 它不起作用,我得到:java.lang.IllegalArgumentException:警告此类型名称不匹配:org.springframework.data.jpa.repository.CrudRepository [Xlint:invalidAbsoluteTypeName]
    • 执行(public * org.springframework.data.repository.CrudRepository+.*(..))
    【解决方案2】:

    另一个可行的解决方案:

    @Aspect
    @Component
    public class ProfilerAspect {
        Logger logger = LoggerFactory.getLogger(this.getClass());
    
        @Pointcut("execution(public * org.springframework.data.repository.Repository+.*(..))")
        public void monitor() {}
    
        @Around("monitor()")
        public Object profile(ProceedingJoinPoint pjp) {
            long start = System.currentTimeMillis();
            logger.debug("JVM memory in use = "+ (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()));
            Object output = null;
            try {
                output = pjp.proceed();
            } catch (Throwable e) {
                logger.error(e.getMessage(), e);
            }
            long elapsedTime = System.currentTimeMillis() - start;
            logger.debug(pjp.getTarget()+"."+pjp.getSignature()+": Execution time: " + elapsedTime + " ms. ("+ elapsedTime/60000 + " minutes)");
    
            return output;
        }
    }
    

    【讨论】:

    • 这很酷,只是它会吞下异常并返回 null,这可能不是所需的行为。
    猜你喜欢
    • 2017-08-20
    • 1970-01-01
    • 1970-01-01
    • 2017-01-06
    • 2021-04-01
    • 2021-01-28
    • 1970-01-01
    • 1970-01-01
    • 2018-09-25
    相关资源
    最近更新 更多