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());
|
}
|
}
|
}
|
}
|