如何记录 Spring Data JPA 存储库方法执行时间?
Posted
技术标签:
【中文标题】如何记录 Spring Data JPA 存储库方法执行时间?【英文标题】:How to log Spring Data JPA repository method execution time? 【发布时间】:2014-11-16 15:07:54 【问题描述】:我有简单的 Spring Data JPA 存储库。
public interface UserRepository extends JpaRepository<UserEntity, Serializable> …
有没有办法监控 Spring 生成的方法的执行时间(例如 findOne(…)
)?
【问题讨论】:
【参考方案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,这可能不是所需的行为。以上是关于如何记录 Spring Data JPA 存储库方法执行时间?的主要内容,如果未能解决你的问题,请参考以下文章
性能 - 使用 Spring JPA Data 搜索具有 2000 万条记录的表
如何在 Spring Boot 应用程序的同一个域类上同时使用 Spring Data JPA 和 Spring Data Elasticsearch 存储库?