package tech.powerjob.server.persistence.monitor;
|
|
import lombok.RequiredArgsConstructor;
|
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.data.domain.Slice;
|
import org.springframework.stereotype.Component;
|
import tech.powerjob.server.common.utils.AOPUtils;
|
import tech.powerjob.server.monitor.MonitorService;
|
import tech.powerjob.server.monitor.events.db.DatabaseEvent;
|
import tech.powerjob.server.monitor.events.db.DatabaseType;
|
|
import java.util.Collection;
|
import java.util.Optional;
|
import java.util.stream.Stream;
|
|
/**
|
* 监控切面
|
*
|
* @author tjq
|
* @since 2022/9/6
|
*/
|
@Slf4j
|
@Aspect
|
@Component
|
@RequiredArgsConstructor
|
public class DatabaseMonitorAspect {
|
|
private final MonitorService monitorService;
|
|
@Around("execution(* tech.powerjob.server.persistence.remote.repository..*.*(..))")
|
public Object monitorCoreDB(ProceedingJoinPoint joinPoint) throws Throwable {
|
return wrapperMonitor(joinPoint, DatabaseType.CORE);
|
}
|
|
@Around("execution(* tech.powerjob.server.persistence.local..*.*(..))")
|
public Object monitorLocalDB(ProceedingJoinPoint joinPoint) throws Throwable {
|
return wrapperMonitor(joinPoint, DatabaseType.LOCAL);
|
}
|
|
private Object wrapperMonitor(ProceedingJoinPoint point, DatabaseType type) throws Throwable {
|
String classNameMini = AOPUtils.parseRealClassName(point);
|
final String methodName = point.getSignature().getName();
|
|
DatabaseEvent event = new DatabaseEvent().setType(type)
|
.setServiceName(classNameMini)
|
.setMethodName(methodName)
|
.setStatus(DatabaseEvent.Status.SUCCESS);
|
|
long startTs = System.currentTimeMillis();
|
try {
|
final Object ret = point.proceed();
|
event.setRows(parseEffectRows(ret));
|
return ret;
|
} catch (Throwable t) {
|
event.setErrorMsg(t.getClass().getSimpleName()).setStatus(DatabaseEvent.Status.FAILED);
|
throw t;
|
} finally {
|
long cost = System.currentTimeMillis() - startTs;
|
monitorService.monitor(event.setCost(cost));
|
}
|
}
|
|
private static Integer parseEffectRows(Object ret) {
|
|
// 从性能角度考虑,最高频场景放在最前面判断
|
|
if (ret instanceof Number) {
|
return ((Number) ret).intValue();
|
}
|
if (ret instanceof Optional) {
|
return ((Optional<?>) ret).isPresent() ? 1 : 0;
|
}
|
if (ret instanceof Collection) {
|
return ((Collection<?>) ret).size();
|
}
|
if (ret instanceof Slice) {
|
return ((Slice<?>) ret).getSize();
|
}
|
|
if (ret instanceof Stream) {
|
return null;
|
}
|
// TODO: 直接返回对象的方法全部改成 Optional
|
|
return ret == null ? 0 : 1;
|
}
|
}
|