diff --git a/pom.xml b/pom.xml index 52da86c7044089d0f39a4a3b6e26298a59caf8a5..094212f46db93c632e6ba941a62bb0736fc3f801 100644 --- a/pom.xml +++ b/pom.xml @@ -49,6 +49,7 @@ 3.3.4 2.2.2.RELEASE + 1.8.7 3.4 2.4 @@ -81,6 +82,11 @@ import pom + + org.aspectj + aspectjweaver + ${aspectjweaver.version} + diff --git a/sdk/pom.xml b/sdk/pom.xml index 17a78ba02e84151c61d16385ac168fa3d0c4ea7b..c1f4d052f8879881ef2a5b7191ce282965f5acd7 100644 --- a/sdk/pom.xml +++ b/sdk/pom.xml @@ -29,5 +29,9 @@ org.springframework.boot spring-boot-autoconfigure + + org.aspectj + aspectjweaver + \ No newline at end of file diff --git a/sdk/src/main/java/cn/icanci/loopstack/bic/sdk/BicAutoConfiguration.java b/sdk/src/main/java/cn/icanci/loopstack/bic/burying/BicAutoConfiguration.java similarity index 30% rename from sdk/src/main/java/cn/icanci/loopstack/bic/sdk/BicAutoConfiguration.java rename to sdk/src/main/java/cn/icanci/loopstack/bic/burying/BicAutoConfiguration.java index cefc3c1f03e7cdcf0cf79cf83387864e65309a69..ac08633b1b03ede4b9c2579f4105927153cf38b4 100644 --- a/sdk/src/main/java/cn/icanci/loopstack/bic/sdk/BicAutoConfiguration.java +++ b/sdk/src/main/java/cn/icanci/loopstack/bic/burying/BicAutoConfiguration.java @@ -1,32 +1,52 @@ -package cn.icanci.loopstack.bic.sdk; +package cn.icanci.loopstack.bic.burying; + +import javax.annotation.Resource; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; -import cn.icanci.loopstack.bic.sdk.properties.BicProperties; +import cn.icanci.loopstack.bic.burying.burying.BuryingBuilder; +import cn.icanci.loopstack.bic.burying.properties.BicProperties; +import cn.icanci.loopstack.bic.burying.system.SystemConstant; +import cn.icanci.loopstack.bic.burying.thread.BicDataCachePool; +import cn.icanci.loopstack.bic.burying.thread.BicEscalationService; +import cn.icanci.loopstack.bic.burying.thread.TriggerThread; /** * @author icanci * @since 1.0 Created in 2023/08/19 12:02 */ @Configuration -@ComponentScan({ "cn.icanci.loopstack.bic.sdk" }) +@ComponentScan({ "cn.icanci.loopstack.bic.burying" }) @EnableConfigurationProperties(BicProperties.class) @AutoConfigureBefore public class BicAutoConfiguration implements CommandLineRunner { - /** Spring 上下文 */ - private ApplicationContext context; - - public BicAutoConfiguration(ApplicationContext context) { - this.context = context; - } + @Resource + private BicProperties bicProperties; + @Resource + private BicEscalationService bicEscalationService; @Override public void run(String... args) throws Exception { - // no op + // 对服务数据进行修正 + fixBicProperties(); + BuryingBuilder.setBicProperties(bicProperties); + BicDataCachePool.setBicProperties(bicProperties); + TriggerThread.setBicProperties(bicProperties, bicEscalationService); + } + + private void fixBicProperties() { + long maxBatchSubmitTime = bicProperties.getMaxBatchSubmitTime(); + if (maxBatchSubmitTime <= 0 || maxBatchSubmitTime > SystemConstant.MAX_BATCH_SUBMIT_TIME) { + bicProperties.setMaxBatchSubmitTime(SystemConstant.MAX_BATCH_SUBMIT_TIME); + } + + long maxBatchSize = bicProperties.getMaxBatchSize(); + if (maxBatchSize <= 0 || maxBatchSize > SystemConstant.MAX_BATCH_SIZE) { + bicProperties.setMaxBatchSize(SystemConstant.MAX_BATCH_SIZE); + } } } diff --git a/sdk/src/main/java/cn/icanci/loopstack/bic/burying/burying/BuryingBuilder.java b/sdk/src/main/java/cn/icanci/loopstack/bic/burying/burying/BuryingBuilder.java new file mode 100644 index 0000000000000000000000000000000000000000..4966e92d724bdc1ea8b960f7e07550e1581c03e5 --- /dev/null +++ b/sdk/src/main/java/cn/icanci/loopstack/bic/burying/burying/BuryingBuilder.java @@ -0,0 +1,57 @@ +package cn.icanci.loopstack.bic.burying.burying; + +import java.io.Serializable; + +import cn.icanci.loopstack.bic.burying.burying.aop.ThreadLocalUtils; +import cn.icanci.loopstack.bic.burying.properties.BicProperties; +import cn.icanci.loopstack.bic.burying.system.LoggerLevelEnum; + +/** + * @author icanci + * @since 1.0 Created in 2023/09/28 13:19 + */ +public class BuryingBuilder implements Serializable { + private static BicProperties bicProperties; + + public static void setBicProperties(BicProperties bicProperties) { + BuryingBuilder.bicProperties = bicProperties; + } + + public static BuryingDTO debug(String traceId, String businessNo, String module, String category, String subCategory, String ext, String message) { + return common(traceId, businessNo, module, category, subCategory, ext, message, LoggerLevelEnum.DEBUG); + } + + public static BuryingDTO info(String traceId, String businessNo, String module, String category, String subCategory, String ext, String message) { + return common(traceId, businessNo, module, category, subCategory, ext, message, LoggerLevelEnum.INFO); + } + + public static BuryingDTO warning(String traceId, String businessNo, String module, String category, String subCategory, String ext, String message) { + return common(traceId, businessNo, module, category, subCategory, ext, message, LoggerLevelEnum.WARNING); + } + + public static BuryingDTO error(String traceId, String businessNo, String module, String category, String subCategory, String ext, String message) { + return common(traceId, businessNo, module, category, subCategory, ext, message, LoggerLevelEnum.ERROR); + } + + private static BuryingDTO common(String traceId, String businessNo, String module, String category, String subCategory, String ext, String message, + LoggerLevelEnum loggerLevel) { + + String useCase = ThreadLocalUtils.getUseCase(); + String uk = ThreadLocalUtils.getUk(); + + BuryingDTO burying = new BuryingDTO(); + burying.setSystemKey(bicProperties.getSystemKey()); + burying.setTraceId(traceId); + burying.setBusinessNo(businessNo); + burying.setUseCase(useCase); + burying.setModule(module); + burying.setCategory(category); + burying.setSubCategory(subCategory); + burying.setExt(ext); + burying.setTime(System.currentTimeMillis()); + burying.setMessage(message); + burying.setLoggerLevel(loggerLevel.name()); + burying.setUniqueKey(uk); + return burying; + } +} diff --git a/sdk/src/main/java/cn/icanci/loopstack/bic/burying/burying/BuryingDTO.java b/sdk/src/main/java/cn/icanci/loopstack/bic/burying/burying/BuryingDTO.java new file mode 100644 index 0000000000000000000000000000000000000000..5ba072e9c9dc159070ce48fd2c8792049b4ba459 --- /dev/null +++ b/sdk/src/main/java/cn/icanci/loopstack/bic/burying/burying/BuryingDTO.java @@ -0,0 +1,131 @@ +package cn.icanci.loopstack.bic.burying.burying; + +import java.io.Serializable; + +/** + * @author icanci + * @since 1.0 Created in 2023/09/28 13:19 + */ +public class BuryingDTO implements Serializable { + private static final long serialVersionUID = 1L; + /** TraceId */ + private String traceId; + /** 业务标识 */ + private String businessNo; + /** 系统应用唯一标识 */ + private String systemKey; + /** 应用系统用例 */ + private String useCase; + /** 模块 */ + private String module; + /** 分类,用于区分同模块下不同的展示类型 */ + private String category; + /** 子模块,用于区分同模块下不同的展示类型 */ + private String subCategory; + /** 扩展属性 */ + private String ext; + /** 时间 */ + private long time; + /** 执行数据 */ + private String message; + /** 日志等级 */ + private String loggerLevel; + /** 数据的唯一标识 */ + private String uniqueKey; + + public String getTraceId() { + return traceId; + } + + public void setTraceId(String traceId) { + this.traceId = traceId; + } + + public String getBusinessNo() { + return businessNo; + } + + public void setBusinessNo(String businessNo) { + this.businessNo = businessNo; + } + + public String getSystemKey() { + return systemKey; + } + + public void setSystemKey(String systemKey) { + this.systemKey = systemKey; + } + + public String getUseCase() { + return useCase; + } + + public void setUseCase(String useCase) { + this.useCase = useCase; + } + + public String getModule() { + return module; + } + + public void setModule(String module) { + this.module = module; + } + + public String getCategory() { + return category; + } + + public void setCategory(String category) { + this.category = category; + } + + public String getSubCategory() { + return subCategory; + } + + public void setSubCategory(String subCategory) { + this.subCategory = subCategory; + } + + public String getExt() { + return ext; + } + + public void setExt(String ext) { + this.ext = ext; + } + + public long getTime() { + return time; + } + + public void setTime(long time) { + this.time = time; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public String getLoggerLevel() { + return loggerLevel; + } + + public void setLoggerLevel(String loggerLevel) { + this.loggerLevel = loggerLevel; + } + + public String getUniqueKey() { + return uniqueKey; + } + + public void setUniqueKey(String uniqueKey) { + this.uniqueKey = uniqueKey; + } +} diff --git a/sdk/src/main/java/cn/icanci/loopstack/bic/burying/burying/BuryingHolder.java b/sdk/src/main/java/cn/icanci/loopstack/bic/burying/burying/BuryingHolder.java new file mode 100644 index 0000000000000000000000000000000000000000..eb5f338645d5c80f41ed4c0dc5fe0c5ffdd90c6f --- /dev/null +++ b/sdk/src/main/java/cn/icanci/loopstack/bic/burying/burying/BuryingHolder.java @@ -0,0 +1,34 @@ +package cn.icanci.loopstack.bic.burying.burying; + +import java.io.Serializable; +import java.util.List; +import java.util.StringJoiner; + +/** + * @author icanci + * @since 1.0 Created in 2023/08/19 18:20 + */ +public class BuryingHolder implements Serializable { + + private List buryingList; + + public BuryingHolder() { + } + + public BuryingHolder(List buryingList) { + this.buryingList = buryingList; + } + + public List getBuryingList() { + return buryingList; + } + + public void setBuryingList(List buryingList) { + this.buryingList = buryingList; + } + + @Override + public String toString() { + return new StringJoiner(",").add("buryingList=" + buryingList).toString(); + } +} diff --git a/sdk/src/main/java/cn/icanci/loopstack/bic/burying/burying/LoggerBuryingUtils.java b/sdk/src/main/java/cn/icanci/loopstack/bic/burying/burying/LoggerBuryingUtils.java new file mode 100644 index 0000000000000000000000000000000000000000..188f9403e5a3be31dfa94592f7fe30eaf57c3b08 --- /dev/null +++ b/sdk/src/main/java/cn/icanci/loopstack/bic/burying/burying/LoggerBuryingUtils.java @@ -0,0 +1,133 @@ +package cn.icanci.loopstack.bic.burying.burying; + +import cn.icanci.loopstack.bic.burying.thread.BicDataCachePool; + +/** + * @author icanci + * @since 1.0 Created in 2023/09/27 16:32 + */ +@SuppressWarnings("unused") +public class LoggerBuryingUtils { + + private static final String EMPTY = ""; + + public static void debug(String traceId, String message) { + BuryingDTO burying = BuryingBuilder.info(traceId, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, message); + BicDataCachePool.add(burying); + } + + public static void debug(String traceId, String businessNo, String message) { + BuryingDTO burying = BuryingBuilder.info(traceId, businessNo, EMPTY, EMPTY, EMPTY, EMPTY, message); + BicDataCachePool.add(burying); + } + + public static void debug(String traceId, String businessNo, String module, String message) { + BuryingDTO burying = BuryingBuilder.debug(traceId, businessNo, module, EMPTY, EMPTY, EMPTY, message); + BicDataCachePool.add(burying); + } + + public static void debug(String traceId, String businessNo, String module, String category, String message) { + BuryingDTO burying = BuryingBuilder.debug(traceId, businessNo, module, category, EMPTY, EMPTY, message); + BicDataCachePool.add(burying); + } + + public static void debug(String traceId, String businessNo, String module, String category, String subCategory, String message) { + BuryingDTO burying = BuryingBuilder.debug(traceId, businessNo, module, category, subCategory, EMPTY, message); + BicDataCachePool.add(burying); + } + + public static void debug(String traceId, String businessNo, String module, String category, String subCategory, String ext, String message) { + BuryingDTO burying = BuryingBuilder.debug(traceId, businessNo, module, category, subCategory, ext, message); + BicDataCachePool.add(burying); + } + + public static void info(String traceId, String message) { + BuryingDTO burying = BuryingBuilder.info(traceId, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, message); + BicDataCachePool.add(burying); + } + + public static void info(String traceId, String businessNo, String message) { + BuryingDTO burying = BuryingBuilder.info(traceId, businessNo, EMPTY, EMPTY, EMPTY, EMPTY, message); + BicDataCachePool.add(burying); + } + + public static void info(String traceId, String businessNo, String module, String message) { + BuryingDTO burying = BuryingBuilder.info(traceId, businessNo, module, EMPTY, EMPTY, EMPTY, message); + BicDataCachePool.add(burying); + } + + public static void info(String traceId, String businessNo, String module, String category, String message) { + BuryingDTO burying = BuryingBuilder.info(traceId, businessNo, module, category, EMPTY, EMPTY, message); + BicDataCachePool.add(burying); + } + + public static void info(String traceId, String businessNo, String module, String category, String subCategory, String message) { + BuryingDTO burying = BuryingBuilder.info(traceId, businessNo, module, category, subCategory, EMPTY, message); + BicDataCachePool.add(burying); + } + + public static void info(String traceId, String businessNo, String module, String category, String subCategory, String ext, String message) { + BuryingDTO burying = BuryingBuilder.info(traceId, businessNo, module, category, subCategory, ext, message); + BicDataCachePool.add(burying); + } + + public static void warning(String traceId, String message) { + BuryingDTO burying = BuryingBuilder.warning(traceId, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, message); + BicDataCachePool.add(burying); + } + + public static void warning(String traceId, String businessNo, String message) { + BuryingDTO burying = BuryingBuilder.warning(traceId, businessNo, EMPTY, EMPTY, EMPTY, EMPTY, message); + BicDataCachePool.add(burying); + } + + public static void warning(String traceId, String businessNo, String module, String message) { + BuryingDTO burying = BuryingBuilder.warning(traceId, businessNo, module, EMPTY, EMPTY, EMPTY, message); + BicDataCachePool.add(burying); + } + + public static void warning(String traceId, String businessNo, String module, String category, String message) { + BuryingDTO burying = BuryingBuilder.warning(traceId, businessNo, module, category, EMPTY, EMPTY, message); + BicDataCachePool.add(burying); + } + + public static void warning(String traceId, String businessNo, String module, String category, String subCategory, String message) { + BuryingDTO burying = BuryingBuilder.warning(traceId, businessNo, module, category, subCategory, EMPTY, message); + BicDataCachePool.add(burying); + } + + public static void warning(String traceId, String businessNo, String module, String category, String subCategory, String ext, String message) { + BuryingDTO burying = BuryingBuilder.warning(traceId, businessNo, module, category, subCategory, ext, message); + BicDataCachePool.add(burying); + } + + public static void error(String traceId, String message) { + BuryingDTO burying = BuryingBuilder.error(traceId, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, message); + BicDataCachePool.add(burying); + } + + public static void error(String traceId, String businessNo, String message) { + BuryingDTO burying = BuryingBuilder.error(traceId, businessNo, EMPTY, EMPTY, EMPTY, EMPTY, message); + BicDataCachePool.add(burying); + } + + public static void error(String traceId, String businessNo, String module, String message) { + BuryingDTO burying = BuryingBuilder.error(traceId, businessNo, module, EMPTY, EMPTY, EMPTY, message); + BicDataCachePool.add(burying); + } + + public static void error(String traceId, String businessNo, String module, String category, String message) { + BuryingDTO burying = BuryingBuilder.error(traceId, businessNo, module, category, EMPTY, EMPTY, message); + BicDataCachePool.add(burying); + } + + public static void error(String traceId, String businessNo, String module, String category, String subCategory, String message) { + BuryingDTO burying = BuryingBuilder.error(traceId, businessNo, module, category, subCategory, EMPTY, message); + BicDataCachePool.add(burying); + } + + public static void error(String traceId, String businessNo, String module, String category, String subCategory, String ext, String message) { + BuryingDTO burying = BuryingBuilder.error(traceId, businessNo, module, category, subCategory, ext, message); + BicDataCachePool.add(burying); + } +} diff --git a/sdk/src/main/java/cn/icanci/loopstack/bic/burying/burying/aop/SysLog.java b/sdk/src/main/java/cn/icanci/loopstack/bic/burying/burying/aop/SysLog.java new file mode 100644 index 0000000000000000000000000000000000000000..86db4d041037df85efd91e647c6726c58e33f642 --- /dev/null +++ b/sdk/src/main/java/cn/icanci/loopstack/bic/burying/burying/aop/SysLog.java @@ -0,0 +1,16 @@ +package cn.icanci.loopstack.bic.burying.burying.aop; + +import java.lang.annotation.*; + +/** + * 系统关键节点 + * + * @author icanci + * @since 1.0 Created in 2023/09/27 15:12 + */ +@Documented +@Target({ ElementType.METHOD }) +@Retention(RetentionPolicy.RUNTIME) +public @interface SysLog { + +} diff --git a/sdk/src/main/java/cn/icanci/loopstack/bic/burying/burying/aop/SysLogAspect.java b/sdk/src/main/java/cn/icanci/loopstack/bic/burying/burying/aop/SysLogAspect.java new file mode 100644 index 0000000000000000000000000000000000000000..9faa1762d4f1d7ea3f574af9fa655b1630c5c5df --- /dev/null +++ b/sdk/src/main/java/cn/icanci/loopstack/bic/burying/burying/aop/SysLogAspect.java @@ -0,0 +1,29 @@ +package cn.icanci.loopstack.bic.burying.burying.aop; + +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.springframework.stereotype.Service; + +/** + * @author icanci + * @since 1.0 Created in 2023/09/27 16:17 + */ +@Aspect +@Service +public class SysLogAspect { + @Around(value = "execution(* *(..)) && @annotation(sysLog))", argNames = "point,sysLog") + public Object round(final ProceedingJoinPoint point, SysLog sysLog) throws Throwable { + String clazz = ThreadLocalUtils.getClazz(); + String method = ThreadLocalUtils.getMethod(); + try { + ThreadLocalUtils.fillThreadContext(point); + return point.proceed(); + } finally { + ThreadLocalUtils.removeThreadContext(); + ThreadLocalUtils.setClazz(clazz); + ThreadLocalUtils.setMethod(method); + } + } + +} diff --git a/sdk/src/main/java/cn/icanci/loopstack/bic/burying/burying/aop/ThreadLocalUtils.java b/sdk/src/main/java/cn/icanci/loopstack/bic/burying/burying/aop/ThreadLocalUtils.java new file mode 100644 index 0000000000000000000000000000000000000000..42af890682cd384bce8e78035cac9eaf9c9b61d6 --- /dev/null +++ b/sdk/src/main/java/cn/icanci/loopstack/bic/burying/burying/aop/ThreadLocalUtils.java @@ -0,0 +1,87 @@ +package cn.icanci.loopstack.bic.burying.burying.aop; + +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; + +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.reflect.MethodSignature; + +import lombok.val; + +/** + * @author icanci + * @since 1.0 Created in 2023/09/27 16:25 + */ +public class ThreadLocalUtils { + private static final String UK_FORMAT = "%s#%s#%s"; + private static final String USE_CASE_KEY = "$USE_CASE_KEY$"; + private static final String CLASS_KEY = "$CLASS_KEY$"; + private static final String METHOD_KEY = "$METHOD_KEY$"; + + private static final ThreadLocal> THREAD_LOCAL = ThreadLocal.withInitial(() -> new HashMap<>(3)); + + // ======================== use case ======================== + public static void setUseCase(String val) { + THREAD_LOCAL.get().put(USE_CASE_KEY, val); + } + + public static void removeUseCase() { + THREAD_LOCAL.remove(); + } + + public static String getUseCase() { + return THREAD_LOCAL.get().get(USE_CASE_KEY); + } + + // ======================== class ======================== + public static void setClazz(String val) { + THREAD_LOCAL.get().put(CLASS_KEY, val); + } + + public static void removeClazz() { + THREAD_LOCAL.get().remove(CLASS_KEY); + } + + public static String getClazz() { + return THREAD_LOCAL.get().get(CLASS_KEY); + } + // ======================== method ======================== + + public static void setMethod(String val) { + THREAD_LOCAL.get().put(METHOD_KEY, val); + } + + public static void removeMethod() { + THREAD_LOCAL.get().remove(METHOD_KEY); + } + + public static String getMethod() { + return THREAD_LOCAL.get().get(METHOD_KEY); + } + + public static void fillThreadContext(ProceedingJoinPoint point) { + try { + MethodSignature method = (MethodSignature) point.getSignature(); + Method targetMethod = point.getTarget().getClass().getDeclaredMethod(method.getName(), method.getMethod().getParameterTypes()); + + String simpleName = point.getTarget().getClass().getSimpleName(); + String methodName = targetMethod.getName(); + + ThreadLocalUtils.setClazz(simpleName); + ThreadLocalUtils.setMethod(methodName); + } catch (Exception ignore) { + + } + } + + public static void removeThreadContext() { + ThreadLocalUtils.removeClazz(); + ThreadLocalUtils.removeMethod(); + } + + // ======================== uk ======================== + public static String getUk() { + return String.format(UK_FORMAT, getUseCase(), getClazz(), getMethod()); + } +} diff --git a/sdk/src/main/java/cn/icanci/loopstack/bic/burying/burying/aop/UseCaseStart.java b/sdk/src/main/java/cn/icanci/loopstack/bic/burying/burying/aop/UseCaseStart.java new file mode 100644 index 0000000000000000000000000000000000000000..ea27c1e006bb4842f46cf000c247d8ba71ff7f27 --- /dev/null +++ b/sdk/src/main/java/cn/icanci/loopstack/bic/burying/burying/aop/UseCaseStart.java @@ -0,0 +1,16 @@ +package cn.icanci.loopstack.bic.burying.burying.aop; + +import java.lang.annotation.*; + +/** + * 用例开始节点 + * + * @author icanci + * @since 1.0 Created in 2023/09/27 15:12 + */ +@Documented +@Target({ ElementType.METHOD }) +@Retention(RetentionPolicy.RUNTIME) +public @interface UseCaseStart { + String useCaseKey(); +} diff --git a/sdk/src/main/java/cn/icanci/loopstack/bic/burying/burying/aop/UseCaseStartAspect.java b/sdk/src/main/java/cn/icanci/loopstack/bic/burying/burying/aop/UseCaseStartAspect.java new file mode 100644 index 0000000000000000000000000000000000000000..d11ffdfa885403190975f824fd5c058ed5a28139 --- /dev/null +++ b/sdk/src/main/java/cn/icanci/loopstack/bic/burying/burying/aop/UseCaseStartAspect.java @@ -0,0 +1,27 @@ +package cn.icanci.loopstack.bic.burying.burying.aop; + +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.springframework.stereotype.Service; + +/** + * 用例切面 + * @author icanci + * @since 1.0 Created in 2023/09/27 16:17 + */ +@Aspect +@Service +public class UseCaseStartAspect { + + @Around(value = "execution(* *(..)) && @annotation(useCaseStart))", argNames = "point,useCaseStart") + public Object round(final ProceedingJoinPoint point, UseCaseStart useCaseStart) throws Throwable { + try { + ThreadLocalUtils.setUseCase(useCaseStart.useCaseKey()); + ThreadLocalUtils.fillThreadContext(point); + return point.proceed(); + } finally { + ThreadLocalUtils.removeUseCase(); + } + } +} diff --git a/sdk/src/main/java/cn/icanci/loopstack/bic/sdk/package-info.java b/sdk/src/main/java/cn/icanci/loopstack/bic/burying/package-info.java similarity index 62% rename from sdk/src/main/java/cn/icanci/loopstack/bic/sdk/package-info.java rename to sdk/src/main/java/cn/icanci/loopstack/bic/burying/package-info.java index d7e023c065bb76b1d2f9a29dd8bcf8b535f5fe43..be44dea6d22df962f089cf85e67bc3606f8dae1a 100644 --- a/sdk/src/main/java/cn/icanci/loopstack/bic/sdk/package-info.java +++ b/sdk/src/main/java/cn/icanci/loopstack/bic/burying/package-info.java @@ -2,4 +2,4 @@ * @author icanci * @since 1.0 Created in 2023/08/21 15:46 */ -package cn.icanci.loopstack.bic.sdk; \ No newline at end of file +package cn.icanci.loopstack.bic.burying; \ No newline at end of file diff --git a/sdk/src/main/java/cn/icanci/loopstack/bic/sdk/properties/BicProperties.java b/sdk/src/main/java/cn/icanci/loopstack/bic/burying/properties/BicProperties.java similarity index 83% rename from sdk/src/main/java/cn/icanci/loopstack/bic/sdk/properties/BicProperties.java rename to sdk/src/main/java/cn/icanci/loopstack/bic/burying/properties/BicProperties.java index 59c81304cdb26cc00f30c061802460270264d850..88060c620919a24645b010cf17ac75a01589e3d9 100644 --- a/sdk/src/main/java/cn/icanci/loopstack/bic/sdk/properties/BicProperties.java +++ b/sdk/src/main/java/cn/icanci/loopstack/bic/burying/properties/BicProperties.java @@ -1,4 +1,6 @@ -package cn.icanci.loopstack.bic.sdk.properties; +package cn.icanci.loopstack.bic.burying.properties; + +import cn.icanci.loopstack.bic.burying.system.SystemConstant; import java.util.StringJoiner; @@ -6,7 +8,7 @@ import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; /** - * 配置规则说明 TODO + * 配置规则说明 * * @author icanci * @since 1.0 Created in 2023/08/19 12:03 @@ -27,13 +29,13 @@ public class BicProperties { */ private String bicServerUrl; /** - * 最大批量写提交条数 + * 单次请求最大批量写提交条数 */ - private long maxBatchSize = 5000L; + private long maxBatchSize = SystemConstant.DEFAULT_MAX_BATCH_SIZE; /** * 最大批量写提交时间 毫秒 */ - private long maxBatchSubmitTime = 3000L; + private long maxBatchSubmitTime = SystemConstant.DEFAULT_MAX_BATCH_SUBMIT_TIME; public String getSystemKey() { return systemKey; diff --git a/sdk/src/main/java/cn/icanci/loopstack/bic/sdk/system/LoggerLevelEnum.java b/sdk/src/main/java/cn/icanci/loopstack/bic/burying/system/LoggerLevelEnum.java similarity index 93% rename from sdk/src/main/java/cn/icanci/loopstack/bic/sdk/system/LoggerLevelEnum.java rename to sdk/src/main/java/cn/icanci/loopstack/bic/burying/system/LoggerLevelEnum.java index 5d2271c819766171ba180adb94cc042cb16bd113..6faa3c78ba307c80717ee8e34f598eac9e73de74 100644 --- a/sdk/src/main/java/cn/icanci/loopstack/bic/sdk/system/LoggerLevelEnum.java +++ b/sdk/src/main/java/cn/icanci/loopstack/bic/burying/system/LoggerLevelEnum.java @@ -1,4 +1,4 @@ -package cn.icanci.loopstack.bic.sdk.system; +package cn.icanci.loopstack.bic.burying.system; /** * 日志等级 diff --git a/sdk/src/main/java/cn/icanci/loopstack/bic/sdk/system/SystemConstant.java b/sdk/src/main/java/cn/icanci/loopstack/bic/burying/system/SystemConstant.java similarity index 83% rename from sdk/src/main/java/cn/icanci/loopstack/bic/sdk/system/SystemConstant.java rename to sdk/src/main/java/cn/icanci/loopstack/bic/burying/system/SystemConstant.java index 06ea06400d60e608fdb592ba7836ca79d0a50d14..7971f0407fa1ea07bf096ff5ea1b4d017c553085 100644 --- a/sdk/src/main/java/cn/icanci/loopstack/bic/sdk/system/SystemConstant.java +++ b/sdk/src/main/java/cn/icanci/loopstack/bic/burying/system/SystemConstant.java @@ -1,4 +1,4 @@ -package cn.icanci.loopstack.bic.sdk.system; +package cn.icanci.loopstack.bic.burying.system; /** * 常量池 @@ -14,7 +14,7 @@ public interface SystemConstant { /** * 默认最大批量写提交条数 */ - long MAX_BATCH_SIZE = 5000L; + long MAX_BATCH_SIZE = 3000L; /** * 默认最大批量写提交时间 毫秒 */ diff --git a/sdk/src/main/java/cn/icanci/loopstack/bic/burying/thread/BicDataCachePool.java b/sdk/src/main/java/cn/icanci/loopstack/bic/burying/thread/BicDataCachePool.java new file mode 100644 index 0000000000000000000000000000000000000000..ea80a69f8bc9066021bf3c2380aec8a0c72904d9 --- /dev/null +++ b/sdk/src/main/java/cn/icanci/loopstack/bic/burying/thread/BicDataCachePool.java @@ -0,0 +1,55 @@ +package cn.icanci.loopstack.bic.burying.thread; + +import cn.icanci.loopstack.bic.burying.burying.BuryingDTO; +import cn.icanci.loopstack.bic.burying.properties.BicProperties; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.LinkedBlockingQueue; + +/** + * 数据缓存池 + * + * @author icanci + * @since 1.0 Created in 2023/08/21 15:49 + */ +public class BicDataCachePool { + private static BicProperties bicProperties; + + public static void setBicProperties(BicProperties bicProperties) { + BicDataCachePool.bicProperties = bicProperties; + } + + private static final LinkedBlockingQueue QUEUE = new LinkedBlockingQueue<>();; + + public static void add(BuryingDTO burying) { + QUEUE.add(burying); + } + + public static synchronized List take() { + try { + List buryingDTOS = new ArrayList<>(); + + if (QUEUE.isEmpty()) { + return buryingDTOS; + } + + if (bicProperties.isSynchronous()) { + buryingDTOS.add(QUEUE.poll()); + return buryingDTOS; + } + + long maxBatchSize = bicProperties.getMaxBatchSize(); + while (maxBatchSize-- > 0) { + BuryingDTO take = QUEUE.poll(); + if (take == null) { + break; + } + buryingDTOS.add(take); + } + return buryingDTOS; + } catch (Exception ignore) { + return new ArrayList<>(); + } + } +} diff --git a/sdk/src/main/java/cn/icanci/loopstack/bic/sdk/thread/BicEscalationService.java b/sdk/src/main/java/cn/icanci/loopstack/bic/burying/thread/BicEscalationService.java similarity index 47% rename from sdk/src/main/java/cn/icanci/loopstack/bic/sdk/thread/BicEscalationService.java rename to sdk/src/main/java/cn/icanci/loopstack/bic/burying/thread/BicEscalationService.java index 97d5379110b0ae57ae76c1d6d55bd9ffebaed00b..44661544e2e31b8f452b2f09f35b380301ddab19 100644 --- a/sdk/src/main/java/cn/icanci/loopstack/bic/sdk/thread/BicEscalationService.java +++ b/sdk/src/main/java/cn/icanci/loopstack/bic/burying/thread/BicEscalationService.java @@ -1,4 +1,8 @@ -package cn.icanci.loopstack.bic.sdk.thread; +package cn.icanci.loopstack.bic.burying.thread; + +import cn.icanci.loopstack.bic.burying.burying.BuryingDTO; + +import java.util.List; /** * 数据上报服务 @@ -10,5 +14,5 @@ public interface BicEscalationService { /** * 上报 */ - void escalation(); + void escalation(List buryings); } diff --git a/sdk/src/main/java/cn/icanci/loopstack/bic/burying/thread/BicEscalationServiceImpl.java b/sdk/src/main/java/cn/icanci/loopstack/bic/burying/thread/BicEscalationServiceImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..b82b611502e8638686415c160c600c13a5087e45 --- /dev/null +++ b/sdk/src/main/java/cn/icanci/loopstack/bic/burying/thread/BicEscalationServiceImpl.java @@ -0,0 +1,51 @@ +package cn.icanci.loopstack.bic.burying.thread; + +import java.util.List; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +import javax.annotation.Resource; + +import org.springframework.stereotype.Service; + +import cn.hutool.http.HttpUtil; +import cn.hutool.json.JSONUtil; +import cn.icanci.loopstack.bic.burying.burying.BuryingDTO; +import cn.icanci.loopstack.bic.burying.burying.BuryingHolder; +import cn.icanci.loopstack.bic.burying.properties.BicProperties; + +/** + * 数据上报服务 + * + * @author icanci + * @since 1.0 Created in 2023/08/19 12:21 + */ +@Service("bicEscalationService") +public class BicEscalationServiceImpl implements BicEscalationService { + @Resource + private BicProperties bicProperties; + private static final String BIC_SERVER_URL_SUFFIX = "/bicApi/burying/batchSubmit"; + + private static final int CORE_SIZE = Runtime.getRuntime().availableProcessors(); + + private static final ThreadPoolExecutor ESCALATION_POOL = new ThreadPoolExecutor(CORE_SIZE, // + CORE_SIZE << 1, // + 60L, // + TimeUnit.SECONDS, // + new LinkedBlockingQueue<>(2000), // + runnable -> new Thread(runnable, "Escalation Biz Pool-" + runnable.hashCode()), // + (r, executor) -> { + throw new RuntimeException("Escalation Biz Pool is EXHAUSTED!"); + }); + + @Override + public void escalation(List buryings) { + String bicServerUrl = bicProperties.getBicServerUrl() + BIC_SERVER_URL_SUFFIX; + ESCALATION_POOL.execute(() -> doEscalation(bicServerUrl, buryings)); + } + + private void doEscalation(String bicServerUrl, List buryings) { + HttpUtil.post(bicServerUrl, JSONUtil.toJsonStr(new BuryingHolder(buryings))); + } +} diff --git a/sdk/src/main/java/cn/icanci/loopstack/bic/burying/thread/TriggerThread.java b/sdk/src/main/java/cn/icanci/loopstack/bic/burying/thread/TriggerThread.java new file mode 100644 index 0000000000000000000000000000000000000000..74a9416ae50a1eade05f337f3c400b0f34841911 --- /dev/null +++ b/sdk/src/main/java/cn/icanci/loopstack/bic/burying/thread/TriggerThread.java @@ -0,0 +1,66 @@ +package cn.icanci.loopstack.bic.burying.thread; + +import cn.icanci.loopstack.bic.burying.burying.BuryingDTO; +import cn.icanci.loopstack.bic.burying.properties.BicProperties; + +import java.util.List; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.LockSupport; + +/** + * @author icanci + * @since 1.0 Created in 2023/09/28 14:01 + */ +public class TriggerThread { + private static BicProperties bicProperties; + private static BicEscalationService bicEscalationService; + + public static void setBicProperties(BicProperties bicProperties, BicEscalationService bicEscalationService) { + TriggerThread.bicProperties = bicProperties; + TriggerThread.bicEscalationService = bicEscalationService; + + start(); + } + + public static void start() { + // 进行消息通知触达线程 + Thread triggerQueueThread = new Thread(() -> { + while (true) { + doTrigger(); + } + }); + + triggerQueueThread.setDaemon(true); + triggerQueueThread.start(); + } + + private static void doTrigger() { + try { + dispatch(); + } catch (Throwable ignored) { + LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(1)); + } finally { + parkNanos(); + } + } + + private static void dispatch() { + List buryings = BicDataCachePool.take(); + if (!buryings.isEmpty()) { + bicEscalationService.escalation(buryings); + } + } + + private static void parkNanos() { + try { + boolean synchronous = bicProperties.isSynchronous(); + if (synchronous) { + LockSupport.parkNanos(TimeUnit.MILLISECONDS.toNanos(10)); + } else { + LockSupport.parkNanos(TimeUnit.MILLISECONDS.toNanos(bicProperties.getMaxBatchSubmitTime())); + } + } catch (Throwable ignored) { + + } + } +} diff --git a/sdk/src/main/java/cn/icanci/loopstack/bic/sdk/thread/BicDataCachePool.java b/sdk/src/main/java/cn/icanci/loopstack/bic/sdk/thread/BicDataCachePool.java deleted file mode 100644 index 9df3f3c8e94029037272003a8766c62b09634642..0000000000000000000000000000000000000000 --- a/sdk/src/main/java/cn/icanci/loopstack/bic/sdk/thread/BicDataCachePool.java +++ /dev/null @@ -1,10 +0,0 @@ -package cn.icanci.loopstack.bic.sdk.thread; - -/** - * Bic 数据缓存池 - * - * @author icanci - * @since 1.0 Created in 2023/08/21 15:49 - */ -public class BicDataCachePool { -} diff --git a/sdk/src/main/java/cn/icanci/loopstack/bic/sdk/thread/BicEscalationServiceImpl.java b/sdk/src/main/java/cn/icanci/loopstack/bic/sdk/thread/BicEscalationServiceImpl.java deleted file mode 100644 index a7f7460abf22c6d76fe1a9e9e769e1a6e1df2664..0000000000000000000000000000000000000000 --- a/sdk/src/main/java/cn/icanci/loopstack/bic/sdk/thread/BicEscalationServiceImpl.java +++ /dev/null @@ -1,18 +0,0 @@ -package cn.icanci.loopstack.bic.sdk.thread; - -import org.springframework.stereotype.Service; - -/** - * 数据上报服务 - * - * @author icanci - * @since 1.0 Created in 2023/08/19 12:21 - */ -@Service("bicEscalationService") -public class BicEscalationServiceImpl implements BicEscalationService { - - @Override - public void escalation() { - - } -} diff --git a/sdk/src/main/java/cn/icanci/loopstack/bic/sdk/utils/BicUtils.java b/sdk/src/main/java/cn/icanci/loopstack/bic/sdk/utils/BicUtils.java deleted file mode 100644 index 84f34da1b49585b253ae92b4a7f7f40b14e726e8..0000000000000000000000000000000000000000 --- a/sdk/src/main/java/cn/icanci/loopstack/bic/sdk/utils/BicUtils.java +++ /dev/null @@ -1,46 +0,0 @@ -package cn.icanci.loopstack.bic.sdk.utils; - -/** - * 写数据操作 - * - 1. 异步 or 同步 - * - 2. 业务号 - * - 3. 系统标识 可以从配置中取值 - * - 4. 模块 - * - * TODO TRACE < DEBUG < INFO < WARN < ERROR < FATAL - * - * @author icanci - * @since 1.0 Created in 2023/08/19 11:54 - */ -public class BicUtils { - - private BicUtils() { - - } - - /** - * 写日志 - * - * @param traceId 跟踪ID - * @param businessNo 业务号 - * @param module 模块 - * @param message 消息 - */ - public static void write(String unionId, String traceId, String businessNo, String useCase, String module, String message) { - - } - - /** - * 写日志 - * - * @param traceId 跟踪ID - * @param businessNo 业务号 - * @param systemKey 系统标识 - * @param module 模块 - * @param message 消息 - */ - public static void write(String unionId, String traceId, String businessNo, String systemKey, String module, String useCase, String message) { - - } - -} diff --git a/sdk/src/main/resources/META-INF/spring.factories b/sdk/src/main/resources/META-INF/spring.factories index 096715b2dfe965a45dcef39be3808e8c6a225c71..5d22a0022088ee941d22525a421f346840dfaacf 100644 --- a/sdk/src/main/resources/META-INF/spring.factories +++ b/sdk/src/main/resources/META-INF/spring.factories @@ -1 +1 @@ -org.springframework.boot.autoconfigure.EnableAutoConfiguration=cn.icanci.loopstack.bic.sdk.BicAutoConfiguration \ No newline at end of file +org.springframework.boot.autoconfigure.EnableAutoConfiguration=cn.icanci.loopstack.bic.burying.BicAutoConfiguration \ No newline at end of file