package com.zy.common.config; import lombok.extern.slf4j.Slf4j; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.TimeUnit; @Component @Aspect @Slf4j @Order(Ordered.LOWEST_PRECEDENCE) @ConditionalOnProperty(prefix = "perf.methodTiming", name = "enabled", havingValue = "true") public class MethodTimingAspect { @Value("${perf.methodTiming.thresholdMs:50}") private long thresholdMs; @Value("${perf.methodTiming.sampleRate:1.0}") private double sampleRate; @Around("execution(public * com.zy.core..*(..))") public Object timeCorePublicMethods(ProceedingJoinPoint joinPoint) throws Throwable { if (sampleRate < 1.0d && ThreadLocalRandom.current().nextDouble() > sampleRate) { return joinPoint.proceed(); } long startNs = System.nanoTime(); try { return joinPoint.proceed(); } finally { long costMs = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNs); if (costMs >= thresholdMs) { log.warn("SLOW {} took {} ms (thread={})", joinPoint.getSignature().toShortString(), costMs, Thread.currentThread().getName()); } } } }