diff --git a/mall-ebtp-cloud-jpa-starter/pom.xml b/mall-ebtp-cloud-jpa-starter/pom.xml
index c33e1ac..baa84d1 100644
--- a/mall-ebtp-cloud-jpa-starter/pom.xml
+++ b/mall-ebtp-cloud-jpa-starter/pom.xml
@@ -7,13 +7,13 @@
+ * 拒绝异常处理 - 在调用线程中执行(当线程池中线程都已被占用且queue已满,则拒绝继续提交task, + * 默认为ThreakPoolExecutor.AbortPolicy抛出异常到上层应用 - 导致异步死掉,无法再处理新任务, + * 此处实现照搬ThreadPoolExecutor.CallerRunsPolicy且添加日志记录, + * CallerRunsPolicy:不在新线程中执行任务,而是用调用者所在的线程来执行) + */ + @Override + public Executor getAsyncExecutor() { + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + executor.setCorePoolSize(asyncProperties.getCoreSize()); + executor.setMaxPoolSize(asyncProperties.getMaxSize()); + executor.setQueueCapacity(asyncProperties.getQueueCapacity()); + executor.setKeepAliveSeconds(asyncProperties.getKeepAlive()); + executor.setThreadNamePrefix(asyncProperties.getThreadNamePrefix()); + // new ThreadPoolExecutor.CallerRunsPolicy(); + executor.setRejectedExecutionHandler((r, e) -> { + log.error("Async thread pool over load - caller run - queue size:{}", e.getQueue().size()); + if (!e.isShutdown()) { + r.run(); + } + }); + // 等待所有任务结束后再关闭线程池 + executor.setWaitForTasksToCompleteOnShutdown(true); + executor.initialize(); + return executor; + } + + /** + * 异步线程池 - 全局异常处理 + * + * @return + */ + @Override + public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() { + return (ex, method, params) -> { + log.info("Async method:{} has uncaught exception,params: {}", method, JsonUtils.objectToJson(params), ex); + }; + } +} diff --git a/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/config/AsyncProperties.java b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/config/AsyncProperties.java new file mode 100644 index 0000000..c164435 --- /dev/null +++ b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/config/AsyncProperties.java @@ -0,0 +1,39 @@ +package com.chinaunicom.mall.ebtp.common.config; + + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; + +/** + * 异步线程池属性 + * + * @author f + * @date 2021-11-12 + */ +@ConfigurationProperties(prefix = "async.thead.pool") +@Data +public class AsyncProperties { + + /** + * 核心线程池大小 + */ + private Integer coreSize; + /** + * 最大线程池大小 + */ + private Integer maxSize; + /** + * 线程池队列容量(默认Integer.MAX_VALUE) + */ + private Integer queueCapacity; + /** + * 线程池空闲时间 + */ + private Integer keepAlive; + /** + * 线程池名称前缀 + */ + private String threadNamePrefix; + + +} diff --git a/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/constant/CommonConstants.java b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/constant/CommonConstants.java index b3eec25..5540f09 100644 --- a/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/constant/CommonConstants.java +++ b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/constant/CommonConstants.java @@ -26,4 +26,14 @@ public interface CommonConstants { * 候审 */ Integer ROOM_TYPE_2 = 2; + + /** + * seata transactionId + */ + String TRANSACTION_ID = "PtxId"; + + /** + * seata spanId + */ + String P_SPAN_ID = "PspanId"; } diff --git a/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/log/OperationLogDetail.java b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/log/OperationLogDetail.java index a575b3d..7e8e82f 100644 --- a/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/log/OperationLogDetail.java +++ b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/log/OperationLogDetail.java @@ -1,7 +1,8 @@ package com.chinaunicom.mall.ebtp.common.log; -import com.chinaunicom.mall.ebtp.common.log.enums.OperationType; +import com.chinaunicom.mall.ebtp.common.log.enums.EbtpLogBusinessModule; +import com.chinaunicom.mall.ebtp.common.log.enums.EbtpLogType; import java.lang.annotation.*; @@ -21,22 +22,18 @@ public @interface OperationLogDetail { /** - * 方法执行模块名称 + * 所属模块 */ - String operationModel() default ""; + EbtpLogBusinessModule businessModule(); + + + /** + * 操作类型(enum):主要是select,insert,update,delete + */ + EbtpLogType operationType(); /** * 方法描述,可使用占位符获取参数:{{tel}} */ String detail() default ""; - - /** - * 操作类型(enum):主要是select,insert,update,delete - */ - OperationType operationType() default OperationType.UNKNOWN; - - /** - * 日志等级:自己定义 - */ - int level() default 2; } diff --git a/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/log/aop/LogAspect.java b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/log/aop/LogAspect.java index ba74ed9..3ef34e8 100644 --- a/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/log/aop/LogAspect.java +++ b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/log/aop/LogAspect.java @@ -1,5 +1,6 @@ package com.chinaunicom.mall.ebtp.common.log.aop; +import cn.hutool.core.exceptions.ExceptionUtil; import com.chinaunicom.mall.ebtp.common.log.OperationLogDetail; import com.chinaunicom.mall.ebtp.common.log.entity.OperationLog; import com.chinaunicom.mall.ebtp.common.log.service.OperationLogService; @@ -13,6 +14,8 @@ import org.aspectj.lang.reflect.MethodSignature; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import java.text.SimpleDateFormat; +import java.util.Date; import java.util.HashMap; import java.util.Map; @@ -31,6 +34,8 @@ import java.util.Map; @Component public class LogAspect { + private final static String CONTENT = "{\"args\":%s,\"returnVal\":%s}"; + @Autowired private OperationLogService operationLogService; @@ -44,22 +49,17 @@ public class LogAspect { */ @Around("operationLog()") public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable { - Object res = null; - long time = System.currentTimeMillis(); + Object res = joinPoint.proceed(); + try { - res = joinPoint.proceed(); - time = System.currentTimeMillis() - time; - return res; - } finally { - try { - //方法执行完成后增加日志 - addOperationLog(joinPoint, res, time); - } catch (Exception e) { - e.printStackTrace(); - log.error("LogAspect 操作失败:" + e.getMessage()); - } + //方法执行完成后增加日志 + addOperationLog(joinPoint, res, time, true); + } catch (Exception e) { + e.printStackTrace(); + log.error("LogAspect 操作失败:" + e.getMessage()); } + return res; } /** @@ -69,23 +69,26 @@ public class LogAspect { * @param res 方法参数 * @param time 执行时间 */ - private void addOperationLog(JoinPoint joinPoint, Object res, long time) { + private void addOperationLog(JoinPoint joinPoint, Object res, long time, boolean result) { ObjectMapper mapper = new ObjectMapper(); MethodSignature signature = (MethodSignature) joinPoint.getSignature(); OperationLog operationLog = new OperationLog(); try { - operationLog.setRunTime(time); - operationLog.setReturnValue(mapper.writeValueAsString(res)); - operationLog.setArgs(mapper.writeValueAsString(joinPoint.getArgs())); - operationLog.setMethod(signature.getDeclaringTypeName() + "." + signature.getName()); + operationLog.setCreateTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(time))); + operationLog.setRunTime(System.currentTimeMillis() - time); + operationLog.setContent(String.format(CONTENT, mapper.writeValueAsString(joinPoint.getArgs()), mapper.writeValueAsString(res))); + operationLog.setResult(result); + operationLog.setPackageName(signature.getDeclaringTypeName()); + operationLog.setMethod(signature.getName()); + OperationLogDetail annotation = signature.getMethod().getAnnotation(OperationLogDetail.class); if (annotation != null) { - operationLog.setLevel(annotation.level()); + operationLog.setLevel("aop"); operationLog.setDescribe(getDetail(((MethodSignature) joinPoint.getSignature()).getParameterNames(), joinPoint.getArgs(), annotation)); operationLog.setOperationType(annotation.operationType().getValue()); - operationLog.setOperationModel(annotation.operationModel()); + operationLog.setBusinessModule(annotation.businessModule().getValue()); } operationLogService.addOperationLog(operationLog); } catch (JsonProcessingException e) { @@ -126,15 +129,22 @@ public class LogAspect { @Before("operationLog()") public void doBeforeAdvice(JoinPoint joinPoint) { - } /** * 后置异常通知 */ - @AfterThrowing("operationLog()") - public void throwss(JoinPoint jp) { + @AfterThrowing(pointcut = "operationLog()", throwing = "ex") + public void throwss(JoinPoint jp, Exception ex) { + //方法执行完成后增加日志 + addOperationLog(jp, ExceptionUtil.stacktraceToString(ex, 500), System.currentTimeMillis(), false); + } + /** + * 后置异常通知 + */ + @After("operationLog()") + public void After(JoinPoint jp) { } } diff --git a/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/log/dao/OperationLogDao.java b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/log/dao/OperationLogDao.java deleted file mode 100644 index 07313e2..0000000 --- a/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/log/dao/OperationLogDao.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.chinaunicom.mall.ebtp.common.log.dao; - -import com.chinaunicom.mall.ebtp.common.log.entity.OperationLog; - -/** - * 保存日志 - * - * @author f - */ -public interface OperationLogDao { - - /** - * 保存日志 - * - * @param operationLog - */ - void save(OperationLog operationLog); -} diff --git a/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/log/dao/impl/OperationLogDaoImpl.java b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/log/dao/impl/OperationLogDaoImpl.java deleted file mode 100644 index 288dd6f..0000000 --- a/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/log/dao/impl/OperationLogDaoImpl.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.chinaunicom.mall.ebtp.common.log.dao.impl; - -import com.chinaunicom.mall.ebtp.common.log.dao.OperationLogDao; -import com.chinaunicom.mall.ebtp.common.log.entity.OperationLog; -import org.springframework.data.mongodb.core.MongoTemplate; -import org.springframework.stereotype.Repository; - -import javax.annotation.Resource; - -/** - * 保存日志 - * - * @author f - */ -@Repository -public class OperationLogDaoImpl implements OperationLogDao { - - @Resource - private MongoTemplate mongoTemplate; - - - /** - * 保存日志 - * - * @param operationLog - */ - @Override - public void save(OperationLog operationLog) { - mongoTemplate.save(operationLog); - } -} diff --git a/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/log/entity/OperationLog.java b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/log/entity/OperationLog.java index a352dff..74c977a 100644 --- a/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/log/entity/OperationLog.java +++ b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/log/entity/OperationLog.java @@ -1,8 +1,9 @@ package com.chinaunicom.mall.ebtp.common.log.entity; +import com.chinaunicom.mall.ebtp.common.base.entity.BaseCacheUser; import lombok.Data; +import lombok.experimental.Accessors; import org.springframework.data.annotation.Id; -import org.springframework.data.mongodb.core.mapping.Document; import java.io.Serializable; @@ -14,8 +15,8 @@ import java.io.Serializable; * @author daixc * @date 2020-09-07 */ -@Document(collection = "ebtp_log") @Data +@Accessors(chain = true) public class OperationLog implements Serializable { /** @@ -29,81 +30,73 @@ public class OperationLog implements Serializable { */ private String transactionId; + /** + * 内容 + */ + private String content; + + /** + * 内容 + */ + private boolean result; + /** * 创建时间 */ private String createTime; /** - * 日志等级 + * 操作人token */ - private Integer level; - - /** - * 服务名 - */ - private String serviceName; - - /** - * 被操作的模块 - */ - private String operationModel; - - /** - * 方法名 - */ - private String method; - - /** - * 参数 - */ - private String args; - - /** - * 操作人id - */ - private String userId; + private String token; /** * 操作人 */ - private String userName; - - /** - * 日志描述 - */ - private String describe; + private BaseCacheUser user; /** * 操作类型 */ private String operationType; + /** + * 服务名 + */ + private String serviceName; + + /** + * 业务所属模块 + */ + private String businessModule; + + /** + * 包名 + */ + private String packageName; + + /** + * 方法名 + */ + private String method; + + /** + * url + */ + private String url; + + /** + * 日志描述 + */ + private String describe; + /** * 方法运行时间 */ private Long runTime; /** - * 方法返回值 + * 日志等级 */ - private String returnValue; - - @Override - public String toString() { - return "OperationLog{" + - "id='" + id + '\'' + - ", createTime=" + createTime + - ", level=" + level + - ", operationModel='" + operationModel + '\'' + - ", method='" + method + '\'' + - ", args='" + args + '\'' + - ", userId='" + userId + '\'' + - ", userName='" + userName + '\'' + - ", describe='" + describe + '\'' + - ", operationType='" + operationType + '\'' + - ", runTime=" + runTime + - ", returnValue='" + returnValue + '\'' + - '}'; - } + private String level; } diff --git a/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/log/enums/EbtpLogBusinessModule.java b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/log/enums/EbtpLogBusinessModule.java new file mode 100644 index 0000000..55c0253 --- /dev/null +++ b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/log/enums/EbtpLogBusinessModule.java @@ -0,0 +1,53 @@ +package com.chinaunicom.mall.ebtp.common.log.enums; + +/** + *
+ * 日志级别枚举类 + * + *
+ * + * @author daixc + * @date 2020-09-07 + */ +public enum EbtpLogBusinessModule { + + /** + * 系统日志 + */ + SYSTEM("system"), + + /** + * 应用程序日志 + */ + APPLICATION("application"), + + /** + * 拦截器日志 + */ + AOP("aop"), + + /** + * 业务日志 + */ + BUSINESS("business"), + + /** + * 垃圾收集器日志 + */ + GC("gc"), + + /** + * 其他 + */ + OTHER("other"); + + private final String value; + + public String getValue() { + return value; + } + + EbtpLogBusinessModule(String s) { + this.value = s; + } +} diff --git a/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/log/enums/OperationType.java b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/log/enums/EbtpLogType.java similarity index 90% rename from uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/log/enums/OperationType.java rename to uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/log/enums/EbtpLogType.java index 7af98a4..44ed776 100644 --- a/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/log/enums/OperationType.java +++ b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/log/enums/EbtpLogType.java @@ -9,7 +9,7 @@ package com.chinaunicom.mall.ebtp.common.log.enums; * @author daixc * @date 2020-09-07 */ -public enum OperationType { +public enum EbtpLogType { /** * 操作类型 @@ -30,7 +30,7 @@ public enum OperationType { this.value = value; } - OperationType(String s) { + EbtpLogType(String s) { this.value = s; } } diff --git a/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/log/producer/OperationLogKafkaProducer.java b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/log/producer/OperationLogKafkaProducer.java new file mode 100644 index 0000000..3290457 --- /dev/null +++ b/uboot-common/src/main/java/com/chinaunicom/mall/ebtp/common/log/producer/OperationLogKafkaProducer.java @@ -0,0 +1,30 @@ +package com.chinaunicom.mall.ebtp.common.log.producer; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.kafka.core.KafkaTemplate; +import org.springframework.stereotype.Component; + +/** + * @author Administrator + */ +@Component +@Slf4j +public class OperationLogKafkaProducer { + + /** + * log topic + */ + public static final String TOPIC = "jl_ebtp_log"; + + @Autowired + private KafkaTemplate