From 9cd2d0f62e54a555314ef199bffd4c606fe1adc2 Mon Sep 17 00:00:00 2001 From: byteblogs168 <598092184@qq.com> Date: Thu, 21 Mar 2024 18:34:29 +0800 Subject: [PATCH] =?UTF-8?q?fix:=203.2.0=20=E9=87=8D=E8=AF=95=E6=A8=A1?= =?UTF-8?q?=E5=9D=97=E6=8E=A5=E5=85=A5=E5=AE=9E=E6=97=B6=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/sql/easy_retry_mysql.sql | 2 + .../appender/EasyRetryLog4j2Appender.java | 4 +- .../appender/EasyRetryLog4jAppender.java | 4 +- .../appender/EasyRetryLogbackAppender.java | 4 +- .../common/report/AbstractLogReport.java | 28 +++- .../client/common/report/AsyncReportLog.java | 45 +++--- .../retry/client/common/report/LogMeta.java | 21 +++ .../retry/client/common/report/LogReport.java | 2 + .../common/report/LogReportFactory.java | 31 ++++ .../common/util/ThreadLocalLogUtil.java | 37 ++++- .../client/core/client/RetryEndPoint.java | 63 +++++--- .../core/executor/AbstractRetryExecutor.java | 4 +- .../core/executor/GuavaRetryExecutor.java | 2 +- .../retry/client/core/log/RetryLogMeta.java | 18 +++ .../retry/client/core/log/RetryLogReport.java | 31 ++-- .../core/strategy/RemoteRetryStrategies.java | 4 +- .../client/job/core/client/JobEndPoint.java | 15 +- .../core/executor/AbstractJobExecutor.java | 14 +- .../executor/JobExecutorFutureCallback.java | 17 ++- .../retry/client/job/core/log/JobLogMeta.java | 30 ++++ .../client/job/core/log/JobLogReport.java | 22 ++- .../retry/client/model/DispatchRetryDTO.java | 4 + .../retry/client/model/RetryCallbackDTO.java | 2 + .../retry/common/log/enums/LogTypeEnum.java | 12 ++ .../retry/server/model/dto/LogTaskDTO.java | 23 +-- .../server/model/dto/RetryLogTaskDTO.java | 3 + .../mapper/RetryTaskLogMessageMapper.java | 6 + .../persistence/po/RetryTaskLogMessage.java | 11 ++ .../mapper/RetryTaskLogMessageMapper.xml | 50 +++++++ .../server/common/akka/ActorGenerator.java | 2 +- .../task/support/dispatch/JobLogActor.java | 64 ++++++-- .../request/ReportLogHttpRequestHandler.java | 81 ---------- .../server/retry/task/dto/LogMetaDTO.java | 40 +++++ .../task/support/RetryTaskConverter.java | 8 + .../EasyRetryServerLogbackAppender.java | 141 ++++++++++++++++++ .../actor/exec/ExecCallbackUnitActor.java | 25 ++-- .../dispatch/actor/exec/ExecUnitActor.java | 36 +++-- .../support/dispatch/actor/log/LogActor.java | 80 ---------- .../dispatch/actor/log/RetryLogActor.java | 100 +++++++++++++ .../dispatch/actor/log/RetryTaskLogDTO.java | 5 + .../dispatch/actor/result/FailureActor.java | 25 ++-- .../dispatch/actor/result/FinishActor.java | 20 ++- .../dispatch/task/AbstractTaskExecutor.java | 24 ++- .../starter/server/RequestHandlerActor.java | 1 - .../handler/BeatHttpRequestHandler.java | 2 +- .../handler/ReportLogHttpRequestHandler.java | 102 +++++++++++++ .../src/main/resources/logback-boot.xml | 3 + 47 files changed, 941 insertions(+), 327 deletions(-) create mode 100644 easy-retry-client/easy-retry-client-common/src/main/java/com/aizuda/easy/retry/client/common/report/LogMeta.java create mode 100644 easy-retry-client/easy-retry-client-common/src/main/java/com/aizuda/easy/retry/client/common/report/LogReportFactory.java create mode 100644 easy-retry-client/easy-retry-client-core/src/main/java/com/aizuda/easy/retry/client/core/log/RetryLogMeta.java create mode 100644 easy-retry-client/easy-retry-client-job-core/src/main/java/com/aizuda/easy/retry/client/job/core/log/JobLogMeta.java create mode 100644 easy-retry-common/easy-retry-common-log/src/main/java/com/aizuda/easy/retry/common/log/enums/LogTypeEnum.java create mode 100644 easy-retry-datasource/easy-retry-mysql-datasource/src/main/resources/mysql/mapper/RetryTaskLogMessageMapper.xml delete mode 100644 easy-retry-server/easy-retry-server-job-task/src/main/java/com/aizuda/easy/retry/server/job/task/support/request/ReportLogHttpRequestHandler.java create mode 100644 easy-retry-server/easy-retry-server-retry-task/src/main/java/com/aizuda/easy/retry/server/retry/task/dto/LogMetaDTO.java create mode 100644 easy-retry-server/easy-retry-server-retry-task/src/main/java/com/aizuda/easy/retry/server/retry/task/support/appender/EasyRetryServerLogbackAppender.java delete mode 100644 easy-retry-server/easy-retry-server-retry-task/src/main/java/com/aizuda/easy/retry/server/retry/task/support/dispatch/actor/log/LogActor.java create mode 100644 easy-retry-server/easy-retry-server-retry-task/src/main/java/com/aizuda/easy/retry/server/retry/task/support/dispatch/actor/log/RetryLogActor.java create mode 100644 easy-retry-server/easy-retry-server-starter/src/main/java/com/aizuda/easy/retry/server/starter/server/handler/ReportLogHttpRequestHandler.java diff --git a/doc/sql/easy_retry_mysql.sql b/doc/sql/easy_retry_mysql.sql index 7dab07f1..4bbd8ce3 100644 --- a/doc/sql/easy_retry_mysql.sql +++ b/doc/sql/easy_retry_mysql.sql @@ -158,6 +158,8 @@ CREATE TABLE `retry_task_log_message` `unique_id` varchar(64) NOT NULL COMMENT '同组下id唯一', `create_dt` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `message` text NOT NULL COMMENT '异常信息', + `log_num` int(11) NOT NULL DEFAULT 1 COMMENT '日志数量', + `real_time` bigint(13) NOT NULL DEFAULT 0 COMMENT '上报时间', `client_info` varchar(128) DEFAULT NULL COMMENT '客户端地址 clientId#ip:port', PRIMARY KEY (`id`), KEY `idx_namespace_id_group_name_scene_name` (`namespace_id`, `group_name`, `unique_id`), diff --git a/easy-retry-client/easy-retry-client-common/src/main/java/com/aizuda/easy/retry/client/common/appender/EasyRetryLog4j2Appender.java b/easy-retry-client/easy-retry-client-common/src/main/java/com/aizuda/easy/retry/client/common/appender/EasyRetryLog4j2Appender.java index 4f556734..4ffd48dc 100644 --- a/easy-retry-client/easy-retry-client-common/src/main/java/com/aizuda/easy/retry/client/common/appender/EasyRetryLog4j2Appender.java +++ b/easy-retry-client/easy-retry-client-common/src/main/java/com/aizuda/easy/retry/client/common/appender/EasyRetryLog4j2Appender.java @@ -1,6 +1,7 @@ package com.aizuda.easy.retry.client.common.appender; import com.aizuda.easy.retry.client.common.report.AsyncReportLog; +import com.aizuda.easy.retry.client.common.report.LogReportFactory; import com.aizuda.easy.retry.client.common.util.ThreadLocalLogUtil; import com.aizuda.easy.retry.common.log.dto.LogContentDTO; import com.aizuda.easy.retry.common.log.constant.LogFieldConstants; @@ -19,6 +20,7 @@ import org.apache.logging.log4j.core.util.Throwables; import java.io.Serializable; import java.util.Objects; +import java.util.Optional; /** * @author wodeyangzipingpingwuqi @@ -46,7 +48,7 @@ public class EasyRetryLog4j2Appender extends AbstractAppender { logContentDTO.addMessageField(event.getMessage().getFormattedMessage()); // slidingWindow syncReportLog - SpringContext.getBeanByType(AsyncReportLog.class).syncReportLog(logContentDTO); + Optional.ofNullable(LogReportFactory.get()).ifPresent(logReport -> logReport.report(logContentDTO)); } protected EasyRetryLog4j2Appender(String name, Filter filter, Layout layout, boolean ignoreExceptions) { diff --git a/easy-retry-client/easy-retry-client-common/src/main/java/com/aizuda/easy/retry/client/common/appender/EasyRetryLog4jAppender.java b/easy-retry-client/easy-retry-client-common/src/main/java/com/aizuda/easy/retry/client/common/appender/EasyRetryLog4jAppender.java index 034cc004..8988c356 100644 --- a/easy-retry-client/easy-retry-client-common/src/main/java/com/aizuda/easy/retry/client/common/appender/EasyRetryLog4jAppender.java +++ b/easy-retry-client/easy-retry-client-common/src/main/java/com/aizuda/easy/retry/client/common/appender/EasyRetryLog4jAppender.java @@ -1,6 +1,7 @@ package com.aizuda.easy.retry.client.common.appender; import com.aizuda.easy.retry.client.common.report.AsyncReportLog; +import com.aizuda.easy.retry.client.common.report.LogReportFactory; import com.aizuda.easy.retry.client.common.util.ThreadLocalLogUtil; import com.aizuda.easy.retry.common.log.dto.LogContentDTO; import com.aizuda.easy.retry.common.log.constant.LogFieldConstants; @@ -11,6 +12,7 @@ import org.apache.log4j.spi.LoggingEvent; import org.apache.log4j.spi.ThrowableInformation; import java.util.Objects; +import java.util.Optional; /** * @author wodeyangzipingpingwuqi @@ -42,7 +44,7 @@ public class EasyRetryLog4jAppender extends AppenderSkeleton { logContentDTO.addThrowableField(getThrowableField(event)); // slidingWindow syncReportLog - SpringContext.getBeanByType(AsyncReportLog.class).syncReportLog(logContentDTO); + Optional.ofNullable(LogReportFactory.get()).ifPresent(logReport -> logReport.report(logContentDTO)); } @Override diff --git a/easy-retry-client/easy-retry-client-common/src/main/java/com/aizuda/easy/retry/client/common/appender/EasyRetryLogbackAppender.java b/easy-retry-client/easy-retry-client-common/src/main/java/com/aizuda/easy/retry/client/common/appender/EasyRetryLogbackAppender.java index c594ddd1..bb7b5e80 100644 --- a/easy-retry-client/easy-retry-client-common/src/main/java/com/aizuda/easy/retry/client/common/appender/EasyRetryLogbackAppender.java +++ b/easy-retry-client/easy-retry-client-common/src/main/java/com/aizuda/easy/retry/client/common/appender/EasyRetryLogbackAppender.java @@ -7,6 +7,7 @@ import ch.qos.logback.classic.spi.ThrowableProxyUtil; import ch.qos.logback.core.CoreConstants; import ch.qos.logback.core.UnsynchronizedAppenderBase; import com.aizuda.easy.retry.client.common.report.AsyncReportLog; +import com.aizuda.easy.retry.client.common.report.LogReportFactory; import com.aizuda.easy.retry.client.common.util.ThreadLocalLogUtil; import com.aizuda.easy.retry.common.log.dto.LogContentDTO; import com.aizuda.easy.retry.common.log.constant.LogFieldConstants; @@ -14,6 +15,7 @@ import com.aizuda.easy.retry.common.core.context.SpringContext; import org.slf4j.MDC; import java.util.Objects; +import java.util.Optional; /** * @author wodeyangzipingpingwuqi @@ -52,7 +54,7 @@ public class EasyRetryLogbackAppender extends UnsynchronizedAppenderBase { logContentDTO.addThrowableField(getThrowableField(event)); // slidingWindow syncReportLog - SpringContext.getBeanByType(AsyncReportLog.class).syncReportLog(logContentDTO); + Optional.ofNullable(LogReportFactory.get()).ifPresent(logReport -> logReport.report(logContentDTO)); } private String getThrowableField(LoggingEvent event) { diff --git a/easy-retry-client/easy-retry-client-common/src/main/java/com/aizuda/easy/retry/client/common/report/AbstractLogReport.java b/easy-retry-client/easy-retry-client-common/src/main/java/com/aizuda/easy/retry/client/common/report/AbstractLogReport.java index 79538385..9e406904 100644 --- a/easy-retry-client/easy-retry-client-common/src/main/java/com/aizuda/easy/retry/client/common/report/AbstractLogReport.java +++ b/easy-retry-client/easy-retry-client-common/src/main/java/com/aizuda/easy/retry/client/common/report/AbstractLogReport.java @@ -3,9 +3,11 @@ package com.aizuda.easy.retry.client.common.report; import com.aizuda.easy.retry.client.common.Lifecycle; import com.aizuda.easy.retry.client.common.config.EasyRetryProperties; import com.aizuda.easy.retry.client.common.window.SlidingWindow; +import com.aizuda.easy.retry.common.core.window.Listener; import com.aizuda.easy.retry.common.log.EasyRetryLog; import com.aizuda.easy.retry.common.log.dto.LogContentDTO; import com.aizuda.easy.retry.server.model.dto.LogTaskDTO; +import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; import java.util.Objects; @@ -15,29 +17,34 @@ import java.util.Objects; * @date 2024-03-20 22:56:53 * @since 3.2.0 */ -public abstract class AbstractLogReport implements Lifecycle, LogReport { +public abstract class AbstractLogReport implements Lifecycle, InitializingBean, LogReport { + @Autowired private EasyRetryProperties easyRetryProperties; - private SlidingWindow slidingWindow; + private SlidingWindow slidingWindow; @Override public void report(LogContentDTO logContentDTO) { slidingWindow.add(buildLogTaskDTO(logContentDTO)); } - protected abstract LogTaskDTO buildLogTaskDTO(LogContentDTO logContentDTO); + protected abstract T buildLogTaskDTO(LogContentDTO logContentDTO); @Override public void start() { + if (Objects.nonNull(slidingWindow)) { + return; + } EasyRetryProperties.LogSlidingWindowConfig logSlidingWindow = easyRetryProperties.getLogSlidingWindow(); + Listener reportLogListener = new ReportLogListener(); slidingWindow = SlidingWindow .Builder .newBuilder() .withTotalThreshold(logSlidingWindow.getTotalThreshold()) .withWindowTotalThreshold(logSlidingWindow.getWindowTotalThreshold()) .withDuration(logSlidingWindow.getDuration(), logSlidingWindow.getChronoUnit()) - .withListener(new ReportLogListener()) + .withListener(reportLogListener) .build(); slidingWindow.start(); @@ -45,10 +52,17 @@ public abstract class AbstractLogReport implements Lifecycle, LogReport { @Override public void close() { - EasyRetryLog.LOCAL.info("AsyncReport Log about to shutdown"); - if (Objects.nonNull(slidingWindow)) { - slidingWindow.end(); + if (Objects.isNull(slidingWindow)) { + return; } + + EasyRetryLog.LOCAL.info("AsyncReport Log about to shutdown"); + slidingWindow.end(); EasyRetryLog.LOCAL.info("AsyncReport Log has been shutdown"); } + + @Override + public void afterPropertiesSet() throws Exception { + LogReportFactory.add(this); + } } diff --git a/easy-retry-client/easy-retry-client-common/src/main/java/com/aizuda/easy/retry/client/common/report/AsyncReportLog.java b/easy-retry-client/easy-retry-client-common/src/main/java/com/aizuda/easy/retry/client/common/report/AsyncReportLog.java index fbddc21d..bea13790 100644 --- a/easy-retry-client/easy-retry-client-common/src/main/java/com/aizuda/easy/retry/client/common/report/AsyncReportLog.java +++ b/easy-retry-client/easy-retry-client-common/src/main/java/com/aizuda/easy/retry/client/common/report/AsyncReportLog.java @@ -1,11 +1,9 @@ package com.aizuda.easy.retry.client.common.report; import com.aizuda.easy.retry.client.common.Lifecycle; -import com.aizuda.easy.retry.client.common.Report; import com.aizuda.easy.retry.client.common.config.EasyRetryProperties; import com.aizuda.easy.retry.client.common.util.ThreadLocalLogUtil; import com.aizuda.easy.retry.client.common.window.SlidingWindow; -import com.aizuda.easy.retry.common.core.model.JobContext; import com.aizuda.easy.retry.common.log.EasyRetryLog; import com.aizuda.easy.retry.common.log.dto.LogContentDTO; import com.aizuda.easy.retry.server.model.dto.LogTaskDTO; @@ -22,8 +20,9 @@ import java.util.Objects; * @date 2023-12-27 * @since 2.6.0 */ -@Component +//@Component @Slf4j +@Deprecated public class AsyncReportLog implements Lifecycle { @Autowired @@ -36,8 +35,8 @@ public class AsyncReportLog implements Lifecycle { */ public Boolean syncReportLog(LogContentDTO logContent) { - LogTaskDTO logTaskDTO = buildLogTaskDTO(logContent); - slidingWindow.add(logTaskDTO); +// LogTaskDTO logTaskDTO = buildLogTaskDTO(logContent); +// slidingWindow.add(logTaskDTO); return Boolean.TRUE; } @@ -67,22 +66,22 @@ public class AsyncReportLog implements Lifecycle { EasyRetryLog.LOCAL.info("AsyncReport Log has been shutdown"); } - /** - * 构建上报任务对象 - * - * @return logContent 上报服务端对象 - */ - protected LogTaskDTO buildLogTaskDTO(LogContentDTO logContentDTO) { - JobContext context = ThreadLocalLogUtil.getContext(); - - LogTaskDTO logTaskDTO = new LogTaskDTO(); - logTaskDTO.setJobId(context.getJobId()); - logTaskDTO.setTaskId(context.getTaskId()); - logTaskDTO.setTaskBatchId(context.getTaskBatchId()); - logTaskDTO.setRealTime(logContentDTO.getTimeStamp()); - logTaskDTO.setNamespaceId(context.getNamespaceId()); - logTaskDTO.setGroupName(context.getGroupName()); - logTaskDTO.setFieldList(logContentDTO.getFieldList()); - return logTaskDTO; - } +// /** +// * 构建上报任务对象 +// * +// * @return logContent 上报服务端对象 +// */ +// protected LogTaskDTO buildLogTaskDTO(LogContentDTO logContentDTO) { +// LogMeta context = ThreadLocalLogUtil.getContext(); +// +// LogTaskDTO logTaskDTO = new LogTaskDTO(); +// logTaskDTO.setJobId(context.getJobId()); +// logTaskDTO.setTaskId(context.getTaskId()); +// logTaskDTO.setTaskBatchId(context.getTaskBatchId()); +// logTaskDTO.setRealTime(logContentDTO.getTimeStamp()); +// logTaskDTO.setNamespaceId(context.getNamespaceId()); +// logTaskDTO.setGroupName(context.getGroupName()); +// logTaskDTO.setFieldList(logContentDTO.getFieldList()); +// return logTaskDTO; +// } } diff --git a/easy-retry-client/easy-retry-client-common/src/main/java/com/aizuda/easy/retry/client/common/report/LogMeta.java b/easy-retry-client/easy-retry-client-common/src/main/java/com/aizuda/easy/retry/client/common/report/LogMeta.java new file mode 100644 index 00000000..a9b6227f --- /dev/null +++ b/easy-retry-client/easy-retry-client-common/src/main/java/com/aizuda/easy/retry/client/common/report/LogMeta.java @@ -0,0 +1,21 @@ +package com.aizuda.easy.retry.client.common.report; + +import lombok.Data; + +/** + * @author: xiaowoniu + * @date : 2024-03-21 + * @since : 3.2.0 + */ +@Data +public class LogMeta { + /** + * 命名空间 + */ + private String namespaceId; + + /** + * 组名称 + */ + private String groupName; +} diff --git a/easy-retry-client/easy-retry-client-common/src/main/java/com/aizuda/easy/retry/client/common/report/LogReport.java b/easy-retry-client/easy-retry-client-common/src/main/java/com/aizuda/easy/retry/client/common/report/LogReport.java index 83fcfc31..4da6aa5d 100644 --- a/easy-retry-client/easy-retry-client-common/src/main/java/com/aizuda/easy/retry/client/common/report/LogReport.java +++ b/easy-retry-client/easy-retry-client-common/src/main/java/com/aizuda/easy/retry/client/common/report/LogReport.java @@ -9,5 +9,7 @@ import com.aizuda.easy.retry.common.log.dto.LogContentDTO; */ public interface LogReport { + boolean supports(); + void report(LogContentDTO logContentDTO); } diff --git a/easy-retry-client/easy-retry-client-common/src/main/java/com/aizuda/easy/retry/client/common/report/LogReportFactory.java b/easy-retry-client/easy-retry-client-common/src/main/java/com/aizuda/easy/retry/client/common/report/LogReportFactory.java new file mode 100644 index 00000000..01ca05db --- /dev/null +++ b/easy-retry-client/easy-retry-client-common/src/main/java/com/aizuda/easy/retry/client/common/report/LogReportFactory.java @@ -0,0 +1,31 @@ +package com.aizuda.easy.retry.client.common.report; + +import com.google.common.collect.Lists; + +import java.util.List; + +/** + * @author: xiaowoniu + * @date : 2024-03-21 + * @since : 3.2.0 + */ +public final class LogReportFactory { + + private static final List reports = Lists.newArrayList(); + + static void add(LogReport logReport) { + reports.add(logReport); + } + + public static LogReport get() { + + for (final LogReport report : reports) { + if (report.supports()) { + return report; + } + } + + return null; + } + +} diff --git a/easy-retry-client/easy-retry-client-common/src/main/java/com/aizuda/easy/retry/client/common/util/ThreadLocalLogUtil.java b/easy-retry-client/easy-retry-client-common/src/main/java/com/aizuda/easy/retry/client/common/util/ThreadLocalLogUtil.java index c6ea040c..93a17e70 100644 --- a/easy-retry-client/easy-retry-client-common/src/main/java/com/aizuda/easy/retry/client/common/util/ThreadLocalLogUtil.java +++ b/easy-retry-client/easy-retry-client-common/src/main/java/com/aizuda/easy/retry/client/common/util/ThreadLocalLogUtil.java @@ -1,7 +1,8 @@ package com.aizuda.easy.retry.client.common.util; -import com.aizuda.easy.retry.common.core.model.JobContext; +import com.aizuda.easy.retry.client.common.report.LogMeta; +import com.aizuda.easy.retry.common.log.enums.LogTypeEnum; /** * @author wodeyangzipingpingwuqi· @@ -9,18 +10,42 @@ import com.aizuda.easy.retry.common.core.model.JobContext; * @since 1.0.0 */ public class ThreadLocalLogUtil { + private static final ThreadLocal LOG_TYPE = new ThreadLocal<>(); + private static final ThreadLocal JOB_CONTEXT_LOCAL = new ThreadLocal<>(); - private static final ThreadLocal JOB_CONTEXT_LOCAL = new ThreadLocal<>(); - - public static void setContext(JobContext jobContext) { - JOB_CONTEXT_LOCAL.set(jobContext); + public static void initLogInfo(LogMeta logMeta, LogTypeEnum logType) { + setContext(logMeta); + setLogType(logType); } - public static JobContext getContext() { + public static void setContext(LogMeta logMeta) { + JOB_CONTEXT_LOCAL.set(logMeta); + } + + public static LogMeta getContext() { return JOB_CONTEXT_LOCAL.get(); } public static void removeContext() { JOB_CONTEXT_LOCAL.remove(); } + + public static void removeAll() { + JOB_CONTEXT_LOCAL.remove(); + LOG_TYPE.remove(); + } + + public static void setLogType (LogTypeEnum logType) { + LOG_TYPE.set(logType); + } + + public static LogTypeEnum getLogType () { + return LOG_TYPE.get(); + } + + public static void removeLogType () { + LOG_TYPE.remove(); + } + + } diff --git a/easy-retry-client/easy-retry-client-core/src/main/java/com/aizuda/easy/retry/client/core/client/RetryEndPoint.java b/easy-retry-client/easy-retry-client-core/src/main/java/com/aizuda/easy/retry/client/core/client/RetryEndPoint.java index 8831ec2c..05d2956a 100644 --- a/easy-retry-client/easy-retry-client-core/src/main/java/com/aizuda/easy/retry/client/core/client/RetryEndPoint.java +++ b/easy-retry-client/easy-retry-client-core/src/main/java/com/aizuda/easy/retry/client/core/client/RetryEndPoint.java @@ -1,6 +1,7 @@ package com.aizuda.easy.retry.client.core.client; import cn.hutool.core.lang.Assert; +import com.aizuda.easy.retry.client.common.util.ThreadLocalLogUtil; import com.aizuda.easy.retry.client.core.IdempotentIdGenerate; import com.aizuda.easy.retry.client.core.RetryArgSerializer; import com.aizuda.easy.retry.client.common.cache.GroupVersionCache; @@ -9,6 +10,7 @@ import com.aizuda.easy.retry.client.core.callback.RetryCompleteCallback; import com.aizuda.easy.retry.client.core.exception.EasyRetryClientException; import com.aizuda.easy.retry.client.core.intercepter.RetrySiteSnapshot; import com.aizuda.easy.retry.client.core.loader.EasyRetrySpiLoader; +import com.aizuda.easy.retry.client.core.log.RetryLogMeta; import com.aizuda.easy.retry.client.core.retryer.RetryerInfo; import com.aizuda.easy.retry.client.core.retryer.RetryerResultContext; import com.aizuda.easy.retry.client.core.serializer.JacksonSerializer; @@ -24,6 +26,7 @@ import com.aizuda.easy.retry.common.log.EasyRetryLog; import com.aizuda.easy.retry.common.core.model.IdempotentIdContext; import com.aizuda.easy.retry.common.core.model.Result; import com.aizuda.easy.retry.common.core.util.JsonUtil; +import com.aizuda.easy.retry.common.log.enums.LogTypeEnum; import com.aizuda.easy.retry.server.model.dto.ConfigDTO; import com.fasterxml.jackson.core.JsonProcessingException; import lombok.extern.slf4j.Slf4j; @@ -64,7 +67,8 @@ public class RetryEndPoint { RetryerInfo retryerInfo = RetryerInfoCache.get(executeReqDto.getScene(), executeReqDto.getExecutorName()); if (Objects.isNull(retryerInfo)) { EasyRetryLog.REMOTE.error("场景:[{}]配置不存在, 请检查您的场景和执行器是否存在", executeReqDto.getScene()); - throw new EasyRetryClientException("场景:[{}]配置不存在, 请检查您的场景和执行器是否存在", executeReqDto.getScene()); + throw new EasyRetryClientException("场景:[{}]配置不存在, 请检查您的场景和执行器是否存在", + executeReqDto.getScene()); } RetryArgSerializer retryArgSerializer = EasyRetrySpiLoader.loadRetryArgSerializer(); @@ -83,6 +87,13 @@ public class RetryEndPoint { try { RetrySiteSnapshot.setAttemptNumber(executeReqDto.getRetryCount()); + // 初始化实时日志上下文 + RetryLogMeta retryLogMeta = new RetryLogMeta(); + retryLogMeta.setGroupName(executeReqDto.getGroupName()); + retryLogMeta.setNamespaceId(executeReqDto.getNamespaceId()); + retryLogMeta.setUniqueId(executeReqDto.getUniqueId()); + ThreadLocalLogUtil.initLogInfo(retryLogMeta, LogTypeEnum.RETRY); + RetryerResultContext retryerResultContext = retryStrategy.openRetry(executeReqDto.getScene(), executeReqDto.getExecutorName(), deSerialize); @@ -101,15 +112,20 @@ public class RetryEndPoint { } if (Objects.equals(RetryResultStatusEnum.SUCCESS.getStatus(), executeRespDto.getStatusCode())) { - EasyRetryLog.REMOTE.info("remote retry complete. count:[{}] result:[{}]", executeReqDto.getRetryCount(), executeRespDto.getResultJson()); - } if (Objects.equals(RetryResultStatusEnum.STOP.getStatus(), executeRespDto.getStatusCode())) { - EasyRetryLog.REMOTE.info("remote retry complete. count:[{}] exceptionMsg:[{}]", executeReqDto.getRetryCount(), executeRespDto.getExceptionMsg()); + EasyRetryLog.REMOTE.info("remote retry complete. count:[{}] result:[{}]", executeReqDto.getRetryCount(), + executeRespDto.getResultJson()); + } + if (Objects.equals(RetryResultStatusEnum.STOP.getStatus(), executeRespDto.getStatusCode())) { + EasyRetryLog.REMOTE.warn("remote retry complete. count:[{}] exceptionMsg:[{}]", + executeReqDto.getRetryCount(), executeRespDto.getExceptionMsg()); } else { - EasyRetryLog.REMOTE.info("remote retry complete. count:[{}] ", executeReqDto.getRetryCount(), retryerResultContext.getThrowable()); + EasyRetryLog.REMOTE.error("remote retry complete. count:[{}] ", executeReqDto.getRetryCount(), + retryerResultContext.getThrowable()); } } finally { RetrySiteSnapshot.removeAll(); + ThreadLocalLogUtil.removeAll(); } return new Result<>(executeRespDto); @@ -126,27 +142,39 @@ public class RetryEndPoint { @PostMapping("/callback/v1") public Result callback(@RequestBody @Validated RetryCallbackDTO callbackDTO) { - RetryerInfo retryerInfo = RetryerInfoCache.get(callbackDTO.getScene(), callbackDTO.getExecutorName()); - if (Objects.isNull(retryerInfo)) { - throw new EasyRetryClientException("场景:[{}]配置不存在, 请检查您的场景和执行器是否存在", callbackDTO.getScene()); - } - RetryArgSerializer retryArgSerializer = EasyRetrySpiLoader.loadRetryArgSerializer(); - - Object[] deSerialize; + RetryerInfo retryerInfo = null; + Object[] deSerialize = null; try { + + // 初始化实时日志上下文 + RetryLogMeta retryLogMeta = new RetryLogMeta(); + retryLogMeta.setGroupName(callbackDTO.getGroup()); + retryLogMeta.setNamespaceId(callbackDTO.getNamespaceId()); + retryLogMeta.setUniqueId(callbackDTO.getUniqueId()); + ThreadLocalLogUtil.initLogInfo(retryLogMeta, LogTypeEnum.RETRY); + + retryerInfo = RetryerInfoCache.get(callbackDTO.getScene(), callbackDTO.getExecutorName()); + if (Objects.isNull(retryerInfo)) { + EasyRetryLog.REMOTE.error("场景:[{}]配置不存在, 请检查您的场景和执行器是否存在", callbackDTO.getScene()); + return new Result(0, "回调失败"); + } + + RetryArgSerializer retryArgSerializer = EasyRetrySpiLoader.loadRetryArgSerializer(); + deSerialize = (Object[]) retryArgSerializer.deSerialize(callbackDTO.getArgsStr(), retryerInfo.getExecutor().getClass(), retryerInfo.getMethod()); - } catch (JsonProcessingException e) { - throw new EasyRetryClientException("参数解析异常", e); - } - try { // 以Spring Bean模式回调 return doCallbackForSpringBean(callbackDTO, retryerInfo, deSerialize); + } catch (JsonProcessingException e) { + EasyRetryLog.REMOTE.error("参数解析异常", e); + return new Result(0, "回调失败"); } catch (NoSuchBeanDefinitionException e) { // 若不是SpringBean 则直接反射以普通类调用 return doCallbackForOrdinaryClass(callbackDTO, retryerInfo, deSerialize); + } finally { + ThreadLocalLogUtil.removeAll(); } } @@ -196,7 +224,8 @@ public class RetryEndPoint { * @param deSerialize 参数信息 * @return Result */ - private Result doCallbackForSpringBean(RetryCallbackDTO callbackDTO, RetryerInfo retryerInfo, Object[] deSerialize) { + private Result doCallbackForSpringBean(RetryCallbackDTO callbackDTO, RetryerInfo retryerInfo, + Object[] deSerialize) { Class retryCompleteCallbackClazz = retryerInfo.getRetryCompleteCallback(); RetryCompleteCallback retryCompleteCallback = SpringContext.getBeanByType(retryCompleteCallbackClazz); diff --git a/easy-retry-client/easy-retry-client-core/src/main/java/com/aizuda/easy/retry/client/core/executor/AbstractRetryExecutor.java b/easy-retry-client/easy-retry-client-core/src/main/java/com/aizuda/easy/retry/client/core/executor/AbstractRetryExecutor.java index c129c2fa..ba7c1461 100644 --- a/easy-retry-client/easy-retry-client-core/src/main/java/com/aizuda/easy/retry/client/core/executor/AbstractRetryExecutor.java +++ b/easy-retry-client/easy-retry-client-core/src/main/java/com/aizuda/easy/retry/client/core/executor/AbstractRetryExecutor.java @@ -27,11 +27,11 @@ public abstract class AbstractRetryExecutor implements RetryExecutor retryMethodClass = retryerInfo.getExecutorMethod(); if (retryMethodClass.isAssignableFrom(ExecutorAnnotationMethod.class)) { - EasyRetryLog.LOCAL.info("执行注解重试方法:{},参数为:{}", retryMethodClass.getName(), JsonUtil.toJsonString(params)); + EasyRetryLog.LOCAL.debug("执行注解重试方法:{},参数为:{}", retryMethodClass.getName(), JsonUtil.toJsonString(params)); ExecutorAnnotationMethod retryAnnotationMethod = new ExecutorAnnotationMethod(retryerInfo); return retryAnnotationMethod.doExecute(params); } else { - EasyRetryLog.LOCAL.info("执行自定义重试方法:{},参数为:{}", retryMethodClass.getName(), JsonUtil.toJsonString(params)); + EasyRetryLog.LOCAL.debug("执行自定义重试方法:{},参数为:{}", retryMethodClass.getName(), JsonUtil.toJsonString(params)); ExecutorMethod executorMethod = SpringContext.getBeanByType(retryMethodClass); return executorMethod.doExecute(params); } diff --git a/easy-retry-client/easy-retry-client-core/src/main/java/com/aizuda/easy/retry/client/core/executor/GuavaRetryExecutor.java b/easy-retry-client/easy-retry-client-core/src/main/java/com/aizuda/easy/retry/client/core/executor/GuavaRetryExecutor.java index 8612fc78..f229535a 100644 --- a/easy-retry-client/easy-retry-client-core/src/main/java/com/aizuda/easy/retry/client/core/executor/GuavaRetryExecutor.java +++ b/easy-retry-client/easy-retry-client-core/src/main/java/com/aizuda/easy/retry/client/core/executor/GuavaRetryExecutor.java @@ -57,7 +57,7 @@ public class GuavaRetryExecutor extends AbstractRetryExecutor { @Override - protected LogTaskDTO buildLogTaskDTO(LogContentDTO logContentDTO) { -// JobContext context = ThreadLocalLogUtil.getContext(); - - LogTaskDTO logTaskDTO = new LogTaskDTO(); -// logTaskDTO.setJobId(context.getJobId()); -// logTaskDTO.setTaskId(context.getTaskId()); -// logTaskDTO.setTaskBatchId(context.getTaskBatchId()); -// logTaskDTO.setRealTime(logContentDTO.getTimeStamp()); -// logTaskDTO.setNamespaceId(context.getNamespaceId()); -// logTaskDTO.setGroupName(context.getGroupName()); + protected RetryLogTaskDTO buildLogTaskDTO(LogContentDTO logContentDTO) { + RetryLogMeta context = (RetryLogMeta) ThreadLocalLogUtil.getContext(); + RetryLogTaskDTO logTaskDTO = new RetryLogTaskDTO(); + logTaskDTO.setLogType(LogTypeEnum.RETRY.name()); + logTaskDTO.setUniqueId(context.getUniqueId()); + logTaskDTO.setRealTime(logContentDTO.getTimeStamp()); + logTaskDTO.setNamespaceId(context.getNamespaceId()); + logTaskDTO.setGroupName(context.getGroupName()); logTaskDTO.setFieldList(logContentDTO.getFieldList()); return logTaskDTO; } + + @Override + public boolean supports() { + return LogTypeEnum.RETRY == ThreadLocalLogUtil.getLogType(); + } } diff --git a/easy-retry-client/easy-retry-client-core/src/main/java/com/aizuda/easy/retry/client/core/strategy/RemoteRetryStrategies.java b/easy-retry-client/easy-retry-client-core/src/main/java/com/aizuda/easy/retry/client/core/strategy/RemoteRetryStrategies.java index 27a08cda..c18f4b89 100644 --- a/easy-retry-client/easy-retry-client-core/src/main/java/com/aizuda/easy/retry/client/core/strategy/RemoteRetryStrategies.java +++ b/easy-retry-client/easy-retry-client-core/src/main/java/com/aizuda/easy/retry/client/core/strategy/RemoteRetryStrategies.java @@ -108,9 +108,7 @@ public class RemoteRetryStrategies extends AbstractRetryStrategies { return Collections.singletonList(new RetryListener() { @Override public void onRetry(Attempt attempt) { - ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); - HttpServletRequest request = Objects.requireNonNull(attributes).getRequest(); - Integer attemptNumber = (Integer) request.getAttribute("attemptNumber"); + Integer attemptNumber = RetrySiteSnapshot.getAttemptNumber(); if (attempt.hasResult()) { EasyRetryLog.LOCAL.info("easy-retry 远程重试成功,第[{}]次调度", attemptNumber); } diff --git a/easy-retry-client/easy-retry-client-job-core/src/main/java/com/aizuda/easy/retry/client/job/core/client/JobEndPoint.java b/easy-retry-client/easy-retry-client-job-core/src/main/java/com/aizuda/easy/retry/client/job/core/client/JobEndPoint.java index 7c379604..30f02b14 100644 --- a/easy-retry-client/easy-retry-client-job-core/src/main/java/com/aizuda/easy/retry/client/job/core/client/JobEndPoint.java +++ b/easy-retry-client/easy-retry-client-job-core/src/main/java/com/aizuda/easy/retry/client/job/core/client/JobEndPoint.java @@ -7,12 +7,14 @@ import com.aizuda.easy.retry.client.job.core.cache.ThreadPoolCache; import com.aizuda.easy.retry.client.job.core.dto.JobExecutorInfo; import com.aizuda.easy.retry.client.job.core.executor.AbstractJobExecutor; import com.aizuda.easy.retry.client.job.core.executor.AnnotationJobExecutor; +import com.aizuda.easy.retry.client.job.core.log.JobLogMeta; import com.aizuda.easy.retry.client.model.StopJobDTO; import com.aizuda.easy.retry.client.model.request.DispatchJobRequest; import com.aizuda.easy.retry.common.core.context.SpringContext; import com.aizuda.easy.retry.common.core.model.JobContext; import com.aizuda.easy.retry.common.core.model.Result; import com.aizuda.easy.retry.common.log.EasyRetryLog; +import com.aizuda.easy.retry.common.log.enums.LogTypeEnum; import lombok.extern.slf4j.Slf4j; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.PostMapping; @@ -39,7 +41,7 @@ public class JobEndPoint { JobContext jobContext = buildJobContext(dispatchJob); // 初始化调度信息(日志上报LogUtil) - ThreadLocalLogUtil.setContext(jobContext); + initLogContext(jobContext); if (Objects.nonNull(dispatchJob.getRetryCount()) && dispatchJob.getRetryCount() > 0) { EasyRetryLog.REMOTE.info("任务执行/调度失败执行重试. 重试次数:[{}]", @@ -75,6 +77,17 @@ public class JobEndPoint { return new Result<>(Boolean.TRUE); } + private void initLogContext(JobContext jobContext) { + JobLogMeta logMeta = new JobLogMeta(); + logMeta.setNamespaceId(jobContext.getNamespaceId()); + logMeta.setTaskId(jobContext.getTaskId()); + logMeta.setGroupName(jobContext.getGroupName()); + logMeta.setJobId(jobContext.getJobId()); + logMeta.setTaskBatchId(jobContext.getTaskBatchId()); + ThreadLocalLogUtil.initLogInfo(logMeta, LogTypeEnum.JOB); + } + + private static JobContext buildJobContext(DispatchJobRequest dispatchJob) { JobContext jobContext = new JobContext(); jobContext.setJobId(dispatchJob.getJobId()); diff --git a/easy-retry-client/easy-retry-client-job-core/src/main/java/com/aizuda/easy/retry/client/job/core/executor/AbstractJobExecutor.java b/easy-retry-client/easy-retry-client-job-core/src/main/java/com/aizuda/easy/retry/client/job/core/executor/AbstractJobExecutor.java index 9fba5f8a..78f9f8fb 100644 --- a/easy-retry-client/easy-retry-client-job-core/src/main/java/com/aizuda/easy/retry/client/job/core/executor/AbstractJobExecutor.java +++ b/easy-retry-client/easy-retry-client-job-core/src/main/java/com/aizuda/easy/retry/client/job/core/executor/AbstractJobExecutor.java @@ -6,11 +6,13 @@ import com.aizuda.easy.retry.client.job.core.cache.FutureCache; import com.aizuda.easy.retry.client.job.core.cache.ThreadPoolCache; import com.aizuda.easy.retry.client.job.core.dto.JobArgs; import com.aizuda.easy.retry.client.job.core.dto.ShardingJobArgs; +import com.aizuda.easy.retry.client.job.core.log.JobLogMeta; import com.aizuda.easy.retry.client.job.core.timer.StopTaskTimerTask; import com.aizuda.easy.retry.client.job.core.timer.TimerManager; import com.aizuda.easy.retry.client.model.ExecuteResult; import com.aizuda.easy.retry.common.core.enums.JobTaskTypeEnum; import com.aizuda.easy.retry.common.core.model.JobContext; +import com.aizuda.easy.retry.common.log.enums.LogTypeEnum; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListeningExecutorService; @@ -51,7 +53,7 @@ public abstract class AbstractJobExecutor implements IJobExecutor { try { // 初始化调度信息(日志上报LogUtil) - ThreadLocalLogUtil.setContext(jobContext); + initLogContext(jobContext); return doJobExecute(jobArgs); } finally { ThreadLocalLogUtil.removeContext(); @@ -63,6 +65,16 @@ public abstract class AbstractJobExecutor implements IJobExecutor { Futures.addCallback(submit, new JobExecutorFutureCallback(jobContext), decorator); } + private void initLogContext(JobContext jobContext) { + JobLogMeta logMeta = new JobLogMeta(); + logMeta.setNamespaceId(jobContext.getNamespaceId()); + logMeta.setTaskId(jobContext.getTaskId()); + logMeta.setGroupName(jobContext.getGroupName()); + logMeta.setJobId(jobContext.getJobId()); + logMeta.setTaskBatchId(jobContext.getTaskBatchId()); + ThreadLocalLogUtil.initLogInfo(logMeta, LogTypeEnum.JOB); + } + private static JobArgs buildJobArgs(JobContext jobContext) { JobArgs jobArgs = new JobArgs(); jobArgs.setArgsStr(jobContext.getArgsStr()); diff --git a/easy-retry-client/easy-retry-client-job-core/src/main/java/com/aizuda/easy/retry/client/job/core/executor/JobExecutorFutureCallback.java b/easy-retry-client/easy-retry-client-job-core/src/main/java/com/aizuda/easy/retry/client/job/core/executor/JobExecutorFutureCallback.java index 12bdd461..6c809a27 100644 --- a/easy-retry-client/easy-retry-client-job-core/src/main/java/com/aizuda/easy/retry/client/job/core/executor/JobExecutorFutureCallback.java +++ b/easy-retry-client/easy-retry-client-job-core/src/main/java/com/aizuda/easy/retry/client/job/core/executor/JobExecutorFutureCallback.java @@ -4,6 +4,7 @@ import com.aizuda.easy.retry.client.common.proxy.RequestBuilder; import com.aizuda.easy.retry.client.common.util.ThreadLocalLogUtil; import com.aizuda.easy.retry.client.job.core.cache.ThreadPoolCache; import com.aizuda.easy.retry.client.job.core.client.JobNettyClient; +import com.aizuda.easy.retry.client.job.core.log.JobLogMeta; import com.aizuda.easy.retry.client.model.ExecuteResult; import com.aizuda.easy.retry.client.model.request.DispatchJobResultRequest; import com.aizuda.easy.retry.common.core.enums.JobTaskStatusEnum; @@ -13,7 +14,7 @@ import com.aizuda.easy.retry.common.log.EasyRetryLog; import com.aizuda.easy.retry.common.core.model.JobContext; import com.aizuda.easy.retry.common.core.model.NettyResult; import com.aizuda.easy.retry.common.core.util.JsonUtil; -import com.aizuda.easy.retry.common.log.EasyRetryLog; +import com.aizuda.easy.retry.common.log.enums.LogTypeEnum; import com.google.common.util.concurrent.FutureCallback; import lombok.extern.slf4j.Slf4j; @@ -43,7 +44,7 @@ public class JobExecutorFutureCallback implements FutureCallback try { // 初始化调度信息(日志上报LogUtil) - ThreadLocalLogUtil.setContext(jobContext); + initLogContext(); // 上报执行成功 EasyRetryLog.REMOTE.info("任务执行成功 taskBatchId:[{}] [{}]", jobContext.getTaskBatchId(), @@ -74,7 +75,7 @@ public class JobExecutorFutureCallback implements FutureCallback try { // 初始化调度信息(日志上报LogUtil) - ThreadLocalLogUtil.setContext(jobContext); + initLogContext(); // 上报执行失败 EasyRetryLog.REMOTE.error("任务执行失败 taskBatchId:[{}]", jobContext.getTaskBatchId(), t); @@ -97,6 +98,16 @@ public class JobExecutorFutureCallback implements FutureCallback } } + private void initLogContext() { + JobLogMeta logMeta = new JobLogMeta(); + logMeta.setNamespaceId(jobContext.getNamespaceId()); + logMeta.setTaskId(jobContext.getTaskId()); + logMeta.setGroupName(jobContext.getGroupName()); + logMeta.setJobId(jobContext.getJobId()); + logMeta.setTaskBatchId(jobContext.getTaskBatchId()); + ThreadLocalLogUtil.initLogInfo(logMeta, LogTypeEnum.JOB); + } + private void stopThreadPool() { if (jobContext.getTaskType() == JobTaskTypeEnum.CLUSTER.getType()) { ThreadPoolCache.stopThreadPool(jobContext.getTaskBatchId()); diff --git a/easy-retry-client/easy-retry-client-job-core/src/main/java/com/aizuda/easy/retry/client/job/core/log/JobLogMeta.java b/easy-retry-client/easy-retry-client-job-core/src/main/java/com/aizuda/easy/retry/client/job/core/log/JobLogMeta.java new file mode 100644 index 00000000..715fcb85 --- /dev/null +++ b/easy-retry-client/easy-retry-client-job-core/src/main/java/com/aizuda/easy/retry/client/job/core/log/JobLogMeta.java @@ -0,0 +1,30 @@ +package com.aizuda.easy.retry.client.job.core.log; + +import com.aizuda.easy.retry.client.common.report.LogMeta; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * @author: xiaowoniu + * @date : 2024-03-21 + * @since : 3.2.0 + */ +@EqualsAndHashCode(callSuper = true) +@Data +public class JobLogMeta extends LogMeta { + + /** + * 任务信息id + */ + private Long jobId; + + /** + * 任务实例id + */ + private Long taskBatchId; + + /** + * 调度任务id + */ + private Long taskId; +} diff --git a/easy-retry-client/easy-retry-client-job-core/src/main/java/com/aizuda/easy/retry/client/job/core/log/JobLogReport.java b/easy-retry-client/easy-retry-client-job-core/src/main/java/com/aizuda/easy/retry/client/job/core/log/JobLogReport.java index 5828428b..22214c44 100644 --- a/easy-retry-client/easy-retry-client-job-core/src/main/java/com/aizuda/easy/retry/client/job/core/log/JobLogReport.java +++ b/easy-retry-client/easy-retry-client-job-core/src/main/java/com/aizuda/easy/retry/client/job/core/log/JobLogReport.java @@ -2,9 +2,9 @@ package com.aizuda.easy.retry.client.job.core.log; import com.aizuda.easy.retry.client.common.report.AbstractLogReport; import com.aizuda.easy.retry.client.common.util.ThreadLocalLogUtil; -import com.aizuda.easy.retry.common.core.model.JobContext; import com.aizuda.easy.retry.common.log.dto.LogContentDTO; -import com.aizuda.easy.retry.server.model.dto.LogTaskDTO; +import com.aizuda.easy.retry.common.log.enums.LogTypeEnum; +import com.aizuda.easy.retry.server.model.dto.JobLogTaskDTO; import org.springframework.stereotype.Component; /** @@ -12,14 +12,20 @@ import org.springframework.stereotype.Component; * @date 2024-03-20 23:25:24 * @since 3.2.0 */ -//@Component -public class JobLogReport extends AbstractLogReport { - @Override - protected LogTaskDTO buildLogTaskDTO(LogContentDTO logContentDTO) { - JobContext context = ThreadLocalLogUtil.getContext(); +@Component +public class JobLogReport extends AbstractLogReport { - LogTaskDTO logTaskDTO = new LogTaskDTO(); + @Override + public boolean supports () { + return LogTypeEnum.JOB == ThreadLocalLogUtil.getLogType(); + } + + @Override + protected JobLogTaskDTO buildLogTaskDTO(LogContentDTO logContentDTO) { + JobLogMeta context = (JobLogMeta) ThreadLocalLogUtil.getContext(); + JobLogTaskDTO logTaskDTO = new JobLogTaskDTO(); logTaskDTO.setJobId(context.getJobId()); + logTaskDTO.setLogType(LogTypeEnum.JOB.name()); logTaskDTO.setTaskId(context.getTaskId()); logTaskDTO.setTaskBatchId(context.getTaskBatchId()); logTaskDTO.setRealTime(logContentDTO.getTimeStamp()); diff --git a/easy-retry-common/easy-retry-common-client-api/src/main/java/com/aizuda/easy/retry/client/model/DispatchRetryDTO.java b/easy-retry-common/easy-retry-common-client-api/src/main/java/com/aizuda/easy/retry/client/model/DispatchRetryDTO.java index 0221b38c..7516d6e8 100644 --- a/easy-retry-common/easy-retry-common-client-api/src/main/java/com/aizuda/easy/retry/client/model/DispatchRetryDTO.java +++ b/easy-retry-common/easy-retry-common-client-api/src/main/java/com/aizuda/easy/retry/client/model/DispatchRetryDTO.java @@ -13,6 +13,10 @@ import lombok.Data; */ @Data public class DispatchRetryDTO { + @NotBlank(message = "namespaceId 不能为空") + private String namespaceId; + @NotBlank(message = "group 不能为空") + private String groupName; @NotBlank(message = "scene 不能为空") private String scene; @NotBlank(message = "参数 不能为空") diff --git a/easy-retry-common/easy-retry-common-client-api/src/main/java/com/aizuda/easy/retry/client/model/RetryCallbackDTO.java b/easy-retry-common/easy-retry-common-client-api/src/main/java/com/aizuda/easy/retry/client/model/RetryCallbackDTO.java index b9593219..42d2add8 100644 --- a/easy-retry-common/easy-retry-common-client-api/src/main/java/com/aizuda/easy/retry/client/model/RetryCallbackDTO.java +++ b/easy-retry-common/easy-retry-common-client-api/src/main/java/com/aizuda/easy/retry/client/model/RetryCallbackDTO.java @@ -27,4 +27,6 @@ public class RetryCallbackDTO { private Integer retryStatus; @NotBlank(message = "uniqueId 不能为空") private String uniqueId; + @NotBlank(message = "namespaceId 不能为空") + private String namespaceId; } diff --git a/easy-retry-common/easy-retry-common-log/src/main/java/com/aizuda/easy/retry/common/log/enums/LogTypeEnum.java b/easy-retry-common/easy-retry-common-log/src/main/java/com/aizuda/easy/retry/common/log/enums/LogTypeEnum.java new file mode 100644 index 00000000..2cc45cd9 --- /dev/null +++ b/easy-retry-common/easy-retry-common-log/src/main/java/com/aizuda/easy/retry/common/log/enums/LogTypeEnum.java @@ -0,0 +1,12 @@ +package com.aizuda.easy.retry.common.log.enums; + +/** + * @author: xiaowoniu + * @date : 2024-03-21 + * @since : 3.2.0 + */ +public enum LogTypeEnum { + + RETRY, + JOB +} diff --git a/easy-retry-common/easy-retry-common-server-api/src/main/java/com/aizuda/easy/retry/server/model/dto/LogTaskDTO.java b/easy-retry-common/easy-retry-common-server-api/src/main/java/com/aizuda/easy/retry/server/model/dto/LogTaskDTO.java index a8cf5ab6..2826deb9 100644 --- a/easy-retry-common/easy-retry-common-server-api/src/main/java/com/aizuda/easy/retry/server/model/dto/LogTaskDTO.java +++ b/easy-retry-common/easy-retry-common-server-api/src/main/java/com/aizuda/easy/retry/server/model/dto/LogTaskDTO.java @@ -16,6 +16,11 @@ import java.util.List; @Data public class LogTaskDTO implements Serializable { + /** + * 日志类型 + */ + private String logType; + /** * 命名空间 */ @@ -44,15 +49,15 @@ public class LogTaskDTO implements Serializable { @Deprecated private Long taskId; - /** - * 创建时间 - */ - private LocalDateTime createDt; - - /** - * 调度信息 - */ - private String message; +// /** +// * 创建时间 +// */ +// private LocalDateTime createDt; +// +// /** +// * 调度信息 +// */ +// private String message; /** * 上报时间 diff --git a/easy-retry-common/easy-retry-common-server-api/src/main/java/com/aizuda/easy/retry/server/model/dto/RetryLogTaskDTO.java b/easy-retry-common/easy-retry-common-server-api/src/main/java/com/aizuda/easy/retry/server/model/dto/RetryLogTaskDTO.java index a6d58d50..250f3998 100644 --- a/easy-retry-common/easy-retry-common-server-api/src/main/java/com/aizuda/easy/retry/server/model/dto/RetryLogTaskDTO.java +++ b/easy-retry-common/easy-retry-common-server-api/src/main/java/com/aizuda/easy/retry/server/model/dto/RetryLogTaskDTO.java @@ -12,4 +12,7 @@ import lombok.EqualsAndHashCode; @Data public class RetryLogTaskDTO extends LogTaskDTO { + private String uniqueId; + + private String clientInfo; } diff --git a/easy-retry-datasource/easy-retry-datasource-template/src/main/java/com/aizuda/easy/retry/template/datasource/persistence/mapper/RetryTaskLogMessageMapper.java b/easy-retry-datasource/easy-retry-datasource-template/src/main/java/com/aizuda/easy/retry/template/datasource/persistence/mapper/RetryTaskLogMessageMapper.java index a71fb606..e79cc2d2 100644 --- a/easy-retry-datasource/easy-retry-datasource-template/src/main/java/com/aizuda/easy/retry/template/datasource/persistence/mapper/RetryTaskLogMessageMapper.java +++ b/easy-retry-datasource/easy-retry-datasource-template/src/main/java/com/aizuda/easy/retry/template/datasource/persistence/mapper/RetryTaskLogMessageMapper.java @@ -1,9 +1,12 @@ package com.aizuda.easy.retry.template.datasource.persistence.mapper; +import com.aizuda.easy.retry.template.datasource.persistence.po.JobLogMessage; import com.aizuda.easy.retry.template.datasource.persistence.po.RetryTaskLogMessage; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import org.apache.ibatis.annotations.Mapper; +import java.util.List; + /** *

* 重试日志异常信息记录表 Mapper 接口 @@ -15,4 +18,7 @@ import org.apache.ibatis.annotations.Mapper; @Mapper public interface RetryTaskLogMessageMapper extends BaseMapper { + int batchInsert(List list); + + int batchUpdate(List list); } diff --git a/easy-retry-datasource/easy-retry-datasource-template/src/main/java/com/aizuda/easy/retry/template/datasource/persistence/po/RetryTaskLogMessage.java b/easy-retry-datasource/easy-retry-datasource-template/src/main/java/com/aizuda/easy/retry/template/datasource/persistence/po/RetryTaskLogMessage.java index d15ea745..2de78316 100644 --- a/easy-retry-datasource/easy-retry-datasource-template/src/main/java/com/aizuda/easy/retry/template/datasource/persistence/po/RetryTaskLogMessage.java +++ b/easy-retry-datasource/easy-retry-datasource-template/src/main/java/com/aizuda/easy/retry/template/datasource/persistence/po/RetryTaskLogMessage.java @@ -59,4 +59,15 @@ public class RetryTaskLogMessage implements Serializable { * 异常信息 */ private String message; + + /** + * 日志数量 + */ + private Integer logNum; + + + /** + * 真实上报时间 + */ + private Long realTime; } diff --git a/easy-retry-datasource/easy-retry-mysql-datasource/src/main/resources/mysql/mapper/RetryTaskLogMessageMapper.xml b/easy-retry-datasource/easy-retry-mysql-datasource/src/main/resources/mysql/mapper/RetryTaskLogMessageMapper.xml new file mode 100644 index 00000000..fe3f1473 --- /dev/null +++ b/easy-retry-datasource/easy-retry-mysql-datasource/src/main/resources/mysql/mapper/RetryTaskLogMessageMapper.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + INSERT INTO retry_task_log_message (namespace_id, group_name, unique_id, log_num, message, + create_dt, real_time, client_info) + VALUES + + ( + #{item.namespaceId}, + #{item.groupName}, + #{item.uniqueId}, + #{item.logNum}, + #{item.message}, + #{item.createDt}, + #{item.realTime}, + #{item.clientInfo} + ) + + + + + UPDATE retry_task_log_message jlm, + ( + + SELECT + #{item.message} AS message, + #{item.logNum} AS log_num, + #{item.id} AS id + + ) tt + SET + jlm.message = tt.message, jlm.log_num = tt.log_num + WHERE jlm.id = tt.id + + + diff --git a/easy-retry-server/easy-retry-server-common/src/main/java/com/aizuda/easy/retry/server/common/akka/ActorGenerator.java b/easy-retry-server/easy-retry-server-common/src/main/java/com/aizuda/easy/retry/server/common/akka/ActorGenerator.java index b82c8fd3..f6408305 100644 --- a/easy-retry-server/easy-retry-server-common/src/main/java/com/aizuda/easy/retry/server/common/akka/ActorGenerator.java +++ b/easy-retry-server/easy-retry-server-common/src/main/java/com/aizuda/easy/retry/server/common/akka/ActorGenerator.java @@ -31,7 +31,7 @@ public class ActorGenerator { public static final String NO_RETRY_ACTOR = "NoRetryActor"; public static final String EXEC_CALLBACK_UNIT_ACTOR = "ExecCallbackUnitActor"; public static final String EXEC_UNIT_ACTOR = "ExecUnitActor"; - public static final String LOG_ACTOR = "LogActor"; + public static final String LOG_ACTOR = "RetryLogActor"; private static final String RETRY_TASK_EXECUTOR_DISPATCHER = "akka.actor.retry-task-executor-dispatcher"; private static final String RETRY_TASK_EXECUTOR_RESULT_DISPATCHER = "akka.actor.retry-task-executor-result-dispatcher"; diff --git a/easy-retry-server/easy-retry-server-job-task/src/main/java/com/aizuda/easy/retry/server/job/task/support/dispatch/JobLogActor.java b/easy-retry-server/easy-retry-server-job-task/src/main/java/com/aizuda/easy/retry/server/job/task/support/dispatch/JobLogActor.java index f2d19a86..d3dbe6cd 100644 --- a/easy-retry-server/easy-retry-server-job-task/src/main/java/com/aizuda/easy/retry/server/job/task/support/dispatch/JobLogActor.java +++ b/easy-retry-server/easy-retry-server-job-task/src/main/java/com/aizuda/easy/retry/server/job/task/support/dispatch/JobLogActor.java @@ -2,9 +2,13 @@ package com.aizuda.easy.retry.server.job.task.support.dispatch; import akka.actor.AbstractActor; import cn.hutool.core.util.StrUtil; +import com.aizuda.easy.retry.common.core.util.JsonUtil; +import com.aizuda.easy.retry.common.log.dto.TaskLogFieldDTO; import com.aizuda.easy.retry.server.common.akka.ActorGenerator; import com.aizuda.easy.retry.server.job.task.dto.JobLogDTO; import com.aizuda.easy.retry.server.job.task.support.JobTaskConverter; +import com.aizuda.easy.retry.server.model.dto.JobLogTaskDTO; +import com.aizuda.easy.retry.server.model.dto.LogTaskDTO; import com.aizuda.easy.retry.template.datasource.persistence.mapper.JobLogMessageMapper; import com.aizuda.easy.retry.template.datasource.persistence.po.JobLogMessage; import lombok.extern.slf4j.Slf4j; @@ -12,10 +16,15 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; import java.time.LocalDateTime; +import java.util.ArrayList; import java.util.List; +import java.util.Map; +import java.util.Objects; import java.util.Optional; +import java.util.stream.Collectors; /** * @author www.byteblogs.com @@ -33,24 +42,47 @@ public class JobLogActor extends AbstractActor { @Override public Receive createReceive() { return receiveBuilder() - .match(List.class, (list -> { - try { - jobLogMessageMapper.batchInsert(list); - } catch (Exception e) { - log.error("保存客户端日志异常.", e); - } finally { - getContext().stop(getSelf()); + .match(List.class, (list -> { + try { + if (CollectionUtils.isEmpty(list)) { + return; } - })) - .match(JobLogDTO.class, (jobLogDTO -> { - try { - saveLogMessage(jobLogDTO); - } catch (Exception e) { - log.error("保存日志异常.", e); - } finally { - getContext().stop(getSelf()); + + List jobLogTasks = (List) list; + Map> logTaskDTOMap = jobLogTasks. + stream().collect(Collectors.groupingBy(JobLogTaskDTO::getTaskId, Collectors.toList())); + + List jobLogMessageList = new ArrayList<>(); + for (List logTaskDTOList : logTaskDTOMap.values()) { + JobLogMessage jobLogMessage = JobTaskConverter.INSTANCE.toJobLogMessage(logTaskDTOList.get(0)); + jobLogMessage.setCreateDt(LocalDateTime.now()); + jobLogMessage.setLogNum(logTaskDTOList.size()); + List> messageMapList = logTaskDTOList.stream() + .map(taskDTO -> taskDTO.getFieldList() + .stream().filter(logTaskDTO_ -> !Objects.isNull(logTaskDTO_.getValue())) + .collect(Collectors.toMap(TaskLogFieldDTO::getName, TaskLogFieldDTO::getValue))) + .collect(Collectors.toList()); + jobLogMessage.setMessage(JsonUtil.toJsonString(messageMapList)); + + jobLogMessageList.add(jobLogMessage); } - })).build(); + + jobLogMessageMapper.batchInsert(jobLogMessageList); + } catch (Exception e) { + log.error("保存客户端日志异常.", e); + } finally { + getContext().stop(getSelf()); + } + })) + .match(JobLogDTO.class, (jobLogDTO -> { + try { + saveLogMessage(jobLogDTO); + } catch (Exception e) { + log.error("保存日志异常.", e); + } finally { + getContext().stop(getSelf()); + } + })).build(); } diff --git a/easy-retry-server/easy-retry-server-job-task/src/main/java/com/aizuda/easy/retry/server/job/task/support/request/ReportLogHttpRequestHandler.java b/easy-retry-server/easy-retry-server-job-task/src/main/java/com/aizuda/easy/retry/server/job/task/support/request/ReportLogHttpRequestHandler.java deleted file mode 100644 index b2b3fec1..00000000 --- a/easy-retry-server/easy-retry-server-job-task/src/main/java/com/aizuda/easy/retry/server/job/task/support/request/ReportLogHttpRequestHandler.java +++ /dev/null @@ -1,81 +0,0 @@ -package com.aizuda.easy.retry.server.job.task.support.request; - -import akka.actor.ActorRef; -import cn.hutool.core.lang.Assert; -import cn.hutool.core.net.url.UrlQuery; -import com.aizuda.easy.retry.common.core.enums.StatusEnum; -import com.aizuda.easy.retry.common.log.dto.TaskLogFieldDTO; -import com.aizuda.easy.retry.common.core.model.EasyRetryRequest; -import com.aizuda.easy.retry.common.core.model.NettyResult; -import com.aizuda.easy.retry.common.core.util.JsonUtil; -import com.aizuda.easy.retry.common.log.EasyRetryLog; -import com.aizuda.easy.retry.server.common.akka.ActorGenerator; -import com.aizuda.easy.retry.server.common.exception.EasyRetryServerException; -import com.aizuda.easy.retry.server.common.handler.PostHttpRequestHandler; -import com.aizuda.easy.retry.server.job.task.support.JobTaskConverter; -import com.aizuda.easy.retry.server.model.dto.LogTaskDTO; -import com.aizuda.easy.retry.template.datasource.persistence.po.JobLogMessage; -import io.netty.handler.codec.http.HttpHeaders; -import io.netty.handler.codec.http.HttpMethod; -import org.springframework.stereotype.Component; -import org.springframework.transaction.annotation.Transactional; - -import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.stream.Collectors; - -import static com.aizuda.easy.retry.common.core.constant.SystemConstants.HTTP_PATH.BATCH_LOG_REPORT; - -/** - * 处理日志上报数据 - * - * @author: wodeyangzipingpingwuqi - * @date : 2023-12-26 - * @since 1.0.0 - */ -@Component -public class ReportLogHttpRequestHandler extends PostHttpRequestHandler { - - @Override - public boolean supports(String path) { - return BATCH_LOG_REPORT.equals(path); - } - - @Override - public HttpMethod method() { - return HttpMethod.POST; - } - - @Override - public String doHandler(String content, UrlQuery urlQuery, HttpHeaders headers) { - - EasyRetryLog.LOCAL.info("Begin Handler Log Report Data. [{}]", content); - EasyRetryRequest retryRequest = JsonUtil.parseObject(content, EasyRetryRequest.class); - Object[] args = retryRequest.getArgs(); - - Assert.notEmpty(args, () -> new EasyRetryServerException("日志上报的数据不能为空. ReqId:[{}]", retryRequest.getReqId())); - Map> logTaskDTOMap = JsonUtil.parseList(JsonUtil.toJsonString(args[0]), LogTaskDTO.class).stream().collect(Collectors.groupingBy(i -> i.getTaskId(), Collectors.toList())); - - List jobLogMessageList = new ArrayList<>(); - for (List logTaskDTOList : logTaskDTOMap.values()) { - - JobLogMessage jobLogMessage = JobTaskConverter.INSTANCE.toJobLogMessage(logTaskDTOList.get(0)); - jobLogMessage.setCreateDt(LocalDateTime.now()); - jobLogMessage.setLogNum(logTaskDTOList.size()); - List> messageMapList = logTaskDTOList.stream().map(taskDTO -> taskDTO.getFieldList() - .stream().filter(logTaskDTO_ -> !Objects.isNull(logTaskDTO_.getValue())) - .collect(Collectors.toMap(TaskLogFieldDTO::getName, TaskLogFieldDTO::getValue))).collect(Collectors.toList()); - jobLogMessage.setMessage(JsonUtil.toJsonString(messageMapList)); - - jobLogMessageList.add(jobLogMessage); - } - - // 批量新增日志数据 - ActorRef actorRef = ActorGenerator.jobLogActor(); - actorRef.tell(jobLogMessageList, actorRef); - return JsonUtil.toJsonString(new NettyResult(StatusEnum.YES.getStatus(), "Batch Log Retry Data Upload Processed Successfully", Boolean.TRUE, retryRequest.getReqId())); - } -} diff --git a/easy-retry-server/easy-retry-server-retry-task/src/main/java/com/aizuda/easy/retry/server/retry/task/dto/LogMetaDTO.java b/easy-retry-server/easy-retry-server-retry-task/src/main/java/com/aizuda/easy/retry/server/retry/task/dto/LogMetaDTO.java new file mode 100644 index 00000000..55e5c982 --- /dev/null +++ b/easy-retry-server/easy-retry-server-retry-task/src/main/java/com/aizuda/easy/retry/server/retry/task/dto/LogMetaDTO.java @@ -0,0 +1,40 @@ +package com.aizuda.easy.retry.server.retry.task.dto; + +import com.aizuda.easy.retry.common.core.util.JsonUtil; +import lombok.Builder; +import lombok.Data; + +/** + * @author xiaowoniu + * @date 2024-01-10 22:56:33 + * @since 3.2.0 + */ +@Data +@Builder +public class LogMetaDTO { + + /** + * 命名空间 + */ + private String namespaceId; + + /** + * 组名称 + */ + private String groupName; + + /** + * 组名称 + */ + private String uniqueId; + + /** + * 时间 + */ + private Long timestamp; + + @Override + public String toString() { + return JsonUtil.toJsonString(this); + } +} diff --git a/easy-retry-server/easy-retry-server-retry-task/src/main/java/com/aizuda/easy/retry/server/retry/task/support/RetryTaskConverter.java b/easy-retry-server/easy-retry-server-retry-task/src/main/java/com/aizuda/easy/retry/server/retry/task/support/RetryTaskConverter.java index 1654207b..8db40e77 100644 --- a/easy-retry-server/easy-retry-server-retry-task/src/main/java/com/aizuda/easy/retry/server/retry/task/support/RetryTaskConverter.java +++ b/easy-retry-server/easy-retry-server-retry-task/src/main/java/com/aizuda/easy/retry/server/retry/task/support/RetryTaskConverter.java @@ -1,6 +1,8 @@ package com.aizuda.easy.retry.server.retry.task.support; +import com.aizuda.easy.retry.server.model.dto.RetryLogTaskDTO; import com.aizuda.easy.retry.server.model.dto.RetryTaskDTO; +import com.aizuda.easy.retry.server.retry.task.dto.LogMetaDTO; import com.aizuda.easy.retry.server.retry.task.dto.NotifyConfigPartitionTask; import com.aizuda.easy.retry.server.retry.task.dto.RetryPartitionTask; import com.aizuda.easy.retry.server.retry.task.generator.task.TaskContext; @@ -9,6 +11,7 @@ import com.aizuda.easy.retry.template.datasource.persistence.po.NotifyConfig; import com.aizuda.easy.retry.template.datasource.persistence.po.RetryDeadLetter; import com.aizuda.easy.retry.template.datasource.persistence.po.RetryTask; import com.aizuda.easy.retry.template.datasource.persistence.po.RetryTaskLog; +import com.aizuda.easy.retry.template.datasource.persistence.po.RetryTaskLogMessage; import org.mapstruct.Mapper; import org.mapstruct.Mapping; import org.mapstruct.Mappings; @@ -45,4 +48,9 @@ public interface RetryTaskConverter { RetryTimerContext toRetryTimerContext(RetryPartitionTask retryPartitionTask); List toNotifyConfigPartitionTask(List notifyConfigs); + + RetryTaskLogMessage toRetryTaskLogMessage(RetryLogTaskDTO retryLogTaskDTO); + + LogMetaDTO toLogMetaDTO(RetryTask retryTask); + } diff --git a/easy-retry-server/easy-retry-server-retry-task/src/main/java/com/aizuda/easy/retry/server/retry/task/support/appender/EasyRetryServerLogbackAppender.java b/easy-retry-server/easy-retry-server-retry-task/src/main/java/com/aizuda/easy/retry/server/retry/task/support/appender/EasyRetryServerLogbackAppender.java new file mode 100644 index 00000000..e1f6d814 --- /dev/null +++ b/easy-retry-server/easy-retry-server-retry-task/src/main/java/com/aizuda/easy/retry/server/retry/task/support/appender/EasyRetryServerLogbackAppender.java @@ -0,0 +1,141 @@ +package com.aizuda.easy.retry.server.retry.task.support.appender; + +import akka.actor.ActorRef; +import ch.qos.logback.classic.spi.IThrowableProxy; +import ch.qos.logback.classic.spi.LoggingEvent; +import ch.qos.logback.classic.spi.StackTraceElementProxy; +import ch.qos.logback.classic.spi.ThrowableProxyUtil; +import ch.qos.logback.core.CoreConstants; +import ch.qos.logback.core.UnsynchronizedAppenderBase; +import cn.hutool.core.util.StrUtil; +import com.aizuda.easy.retry.common.core.util.JsonUtil; +import com.aizuda.easy.retry.common.log.EasyRetryLog; +import com.aizuda.easy.retry.common.log.constant.LogFieldConstants; +import com.aizuda.easy.retry.common.log.dto.LogContentDTO; +import com.aizuda.easy.retry.common.log.dto.TaskLogFieldDTO; +import com.aizuda.easy.retry.server.common.akka.ActorGenerator; +import com.aizuda.easy.retry.server.retry.task.dto.LogMetaDTO; +import com.aizuda.easy.retry.server.retry.task.support.dispatch.actor.log.RetryTaskLogDTO; +import com.google.common.collect.Lists; +import org.slf4j.MDC; + +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +/** + * @author xiaowoniu + * @date 2023-12-27 + * @since 3.2.0 + */ +public class EasyRetryServerLogbackAppender extends UnsynchronizedAppenderBase { + + @Override + protected void append(E eventObject) { + + // Not job context + if (!(eventObject instanceof LoggingEvent) || Objects.isNull( + MDC.getMDCAdapter().get(LogFieldConstants.MDC_REMOTE))) { + return; + } + + MDC.getMDCAdapter().remove(LogFieldConstants.MDC_REMOTE); + // Prepare processing + ((LoggingEvent) eventObject).prepareForDeferredProcessing(); + LoggingEvent event = (LoggingEvent) eventObject; + + LogContentDTO logContentDTO = new LogContentDTO(); + logContentDTO.addLevelField(event.getLevel().levelStr); + logContentDTO.addThreadField(event.getThreadName()); + logContentDTO.addLocationField(getLocationField(event)); + logContentDTO.addThrowableField(getThrowableField(event)); + + LogMetaDTO logMetaDTO = null; + try { + String patternString = "<\\|>(.*?)<\\|>"; + Pattern pattern = Pattern.compile(patternString); + Matcher matcher = pattern.matcher(event.getFormattedMessage()); + while (matcher.find()) { + String extractedData = matcher.group(1); + if (StrUtil.isBlank(extractedData)) { + continue; + } + + logMetaDTO = JsonUtil.parseObject(extractedData, LogMetaDTO.class); + String message = event.getFormattedMessage().replaceFirst(patternString, StrUtil.EMPTY); + logContentDTO.addMessageField(message); + logContentDTO.addTimeStamp(Optional.ofNullable(logMetaDTO.getTimestamp()).orElse(event.getTimeStamp())); + break; + } + + } catch (Exception e) { + EasyRetryLog.LOCAL.error("日志解析失败. msg:[{}]", event.getFormattedMessage(), e); + } + + if (Objects.isNull(logMetaDTO)) { + return; + } + + // 保存执行的日志 + saveLog(logContentDTO, logMetaDTO); + } + + /** + * 保存日志 + * + * @param logContentDTO 日志内容 + * @param logMetaDTO 日志元数据 + */ + private void saveLog(final LogContentDTO logContentDTO, final LogMetaDTO logMetaDTO) { + RetryTaskLogDTO jobLogDTO = new RetryTaskLogDTO(); + Map messageMap = logContentDTO.getFieldList() + .stream() + .filter(logTaskDTO_ -> !Objects.isNull(logTaskDTO_.getValue())) + .collect(Collectors.toMap(TaskLogFieldDTO::getName, TaskLogFieldDTO::getValue)); + jobLogDTO.setMessage(JsonUtil.toJsonString(Lists.newArrayList(messageMap))); + jobLogDTO.setGroupName(logMetaDTO.getGroupName()); + jobLogDTO.setNamespaceId(logMetaDTO.getNamespaceId()); + jobLogDTO.setUniqueId(logMetaDTO.getUniqueId()); + jobLogDTO.setRealTime(logMetaDTO.getTimestamp()); + ActorRef actorRef = ActorGenerator.jobLogActor(); + actorRef.tell(jobLogDTO, actorRef); + } + + private String getThrowableField(LoggingEvent event) { + IThrowableProxy iThrowableProxy = event.getThrowableProxy(); + if (iThrowableProxy != null) { + String throwable = getExceptionInfo(iThrowableProxy); + throwable += formatThrowable(event.getThrowableProxy().getStackTraceElementProxyArray()); + return throwable; + } + return null; + } + + private String getLocationField(LoggingEvent event) { + StackTraceElement[] caller = event.getCallerData(); + if (caller != null && caller.length > 0) { + return caller[0].toString(); + } + return null; + } + + private String formatThrowable(StackTraceElementProxy[] stackTraceElementProxyArray) { + StringBuilder builder = new StringBuilder(); + for (StackTraceElementProxy step : stackTraceElementProxyArray) { + builder.append(CoreConstants.LINE_SEPARATOR); + String string = step.toString(); + builder.append(CoreConstants.TAB).append(string); + ThrowableProxyUtil.subjoinPackagingData(builder, step); + } + return builder.toString(); + } + + private String getExceptionInfo(IThrowableProxy iThrowableProxy) { + String s = iThrowableProxy.getClassName(); + String message = iThrowableProxy.getMessage(); + return (message != null) ? (s + ": " + message) : s; + } +} diff --git a/easy-retry-server/easy-retry-server-retry-task/src/main/java/com/aizuda/easy/retry/server/retry/task/support/dispatch/actor/exec/ExecCallbackUnitActor.java b/easy-retry-server/easy-retry-server-retry-task/src/main/java/com/aizuda/easy/retry/server/retry/task/support/dispatch/actor/exec/ExecCallbackUnitActor.java index 6246ea8f..2b2be05d 100644 --- a/easy-retry-server/easy-retry-server-retry-task/src/main/java/com/aizuda/easy/retry/server/retry/task/support/dispatch/actor/exec/ExecCallbackUnitActor.java +++ b/easy-retry-server/easy-retry-server-retry-task/src/main/java/com/aizuda/easy/retry/server/retry/task/support/dispatch/actor/exec/ExecCallbackUnitActor.java @@ -14,7 +14,10 @@ import com.aizuda.easy.retry.server.common.client.RequestBuilder; import com.aizuda.easy.retry.server.common.dto.RegisterNodeInfo; import com.aizuda.easy.retry.server.common.exception.EasyRetryServerException; import com.aizuda.easy.retry.server.common.util.ClientInfoUtils; +import com.aizuda.easy.retry.server.common.util.DateUtils; import com.aizuda.easy.retry.server.retry.task.client.RetryRpcClient; +import com.aizuda.easy.retry.server.retry.task.dto.LogMetaDTO; +import com.aizuda.easy.retry.server.retry.task.support.RetryTaskConverter; import com.aizuda.easy.retry.server.retry.task.support.RetryTaskLogConverter; import com.aizuda.easy.retry.server.retry.task.support.context.CallbackRetryContext; import com.aizuda.easy.retry.server.retry.task.support.dispatch.actor.log.RetryTaskLogDTO; @@ -62,9 +65,9 @@ public class ExecCallbackUnitActor extends AbstractActor { RegisterNodeInfo serverNode = context.getServerNode(); SceneConfig sceneConfig = context.getSceneConfig(); - RetryTaskLogDTO retryTaskLog = RetryTaskLogConverter.INSTANCE.toRetryTaskLogDTO(retryTask); - retryTaskLog.setTriggerTime(LocalDateTime.now()); - retryTaskLog.setClientInfo(ClientInfoUtils.generate(serverNode)); +// RetryTaskLogDTO retryTaskLog = RetryTaskLogConverter.INSTANCE.toRetryTaskLogDTO(retryTask); +// retryTaskLog.setTriggerTime(LocalDateTime.now()); +// retryTaskLog.setClientInfo(ClientInfoUtils.generate(serverNode)); try { @@ -80,23 +83,24 @@ public class ExecCallbackUnitActor extends AbstractActor { message = "回调客户端失败: 异常信息为空"; } } - retryTaskLog.setMessage(message); +// retryTaskLog.setMessage(message); return result; }); if (context.hasException()) { - retryTaskLog.setMessage(context.getException().getMessage()); +// retryTaskLog.setMessage(context.getException().getMessage()); } } else { - retryTaskLog.setMessage("There are currently no available client PODs."); +// retryTaskLog.setMessage("There are currently no available client PODs."); } } catch (Exception e) { - EasyRetryLog.LOCAL.error("callback client error. retryTask:[{}]", JsonUtil.toJsonString(retryTask), e); - retryTaskLog.setMessage(StringUtils.isBlank(e.getMessage()) ? StrUtil.EMPTY : e.getMessage()); + LogMetaDTO logMetaDTO = RetryTaskConverter.INSTANCE.toLogMetaDTO(retryTask); + logMetaDTO.setTimestamp(DateUtils.toNowMilli()); + EasyRetryLog.REMOTE.error("请求客户端异常. <|>{}<|>", retryTask.getUniqueId(), logMetaDTO, e);// retryTaskLog.setMessage(StringUtils.isBlank(e.getMessage()) ? StrUtil.EMPTY : e.getMessage()); } finally { - ActorRef actorRef = ActorGenerator.logActor(); - actorRef.tell(retryTaskLog, actorRef); +// ActorRef actorRef = ActorGenerator.logActor(); +// actorRef.tell(retryTaskLog, actorRef); getContext().stop(getSelf()); @@ -135,6 +139,7 @@ public class ExecCallbackUnitActor extends AbstractActor { retryCallbackDTO.setGroup(callbackTask.getGroupName()); retryCallbackDTO.setExecutorName(callbackTask.getExecutorName()); retryCallbackDTO.setUniqueId(callbackTask.getUniqueId()); + retryCallbackDTO.setNamespaceId(callbackTask.getNamespaceId()); RetryRpcClient rpcClient = RequestBuilder.newBuilder() .nodeInfo(serverNode) diff --git a/easy-retry-server/easy-retry-server-retry-task/src/main/java/com/aizuda/easy/retry/server/retry/task/support/dispatch/actor/exec/ExecUnitActor.java b/easy-retry-server/easy-retry-server-retry-task/src/main/java/com/aizuda/easy/retry/server/retry/task/support/dispatch/actor/exec/ExecUnitActor.java index 1baa3dc0..d3058a91 100644 --- a/easy-retry-server/easy-retry-server-retry-task/src/main/java/com/aizuda/easy/retry/server/retry/task/support/dispatch/actor/exec/ExecUnitActor.java +++ b/easy-retry-server/easy-retry-server-retry-task/src/main/java/com/aizuda/easy/retry/server/retry/task/support/dispatch/actor/exec/ExecUnitActor.java @@ -15,7 +15,10 @@ import com.aizuda.easy.retry.server.common.akka.ActorGenerator; import com.aizuda.easy.retry.server.common.client.RequestBuilder; import com.aizuda.easy.retry.server.common.dto.RegisterNodeInfo; import com.aizuda.easy.retry.server.common.util.ClientInfoUtils; +import com.aizuda.easy.retry.server.common.util.DateUtils; import com.aizuda.easy.retry.server.retry.task.client.RetryRpcClient; +import com.aizuda.easy.retry.server.retry.task.dto.LogMetaDTO; +import com.aizuda.easy.retry.server.retry.task.support.RetryTaskConverter; import com.aizuda.easy.retry.server.retry.task.support.RetryTaskLogConverter; import com.aizuda.easy.retry.server.retry.task.support.context.MaxAttemptsPersistenceRetryContext; import com.aizuda.easy.retry.server.retry.task.support.dispatch.actor.log.RetryTaskLogDTO; @@ -52,9 +55,9 @@ public class ExecUnitActor extends AbstractActor { RegisterNodeInfo serverNode = context.getServerNode(); SceneConfig sceneConfig = context.getSceneConfig(); - RetryTaskLogDTO retryTaskLog = RetryTaskLogConverter.INSTANCE.toRetryTaskLogDTO(retryTask); - retryTaskLog.setTriggerTime(LocalDateTime.now()); - retryTaskLog.setClientInfo(ClientInfoUtils.generate(serverNode)); +// RetryTaskLogDTO retryTaskLog = RetryTaskLogConverter.INSTANCE.toRetryTaskLogDTO(retryTask); +// retryTaskLog.setTriggerTime(LocalDateTime.now()); +// retryTaskLog.setClientInfo(ClientInfoUtils.generate(serverNode)); try { @@ -67,9 +70,9 @@ public class ExecUnitActor extends AbstractActor { // 回调接口请求成功,处理返回值 if (StatusEnum.YES.getStatus() != result.getStatus()) { if (StrUtil.isNotBlank(result.getMessage())) { - retryTaskLog.setMessage(result.getMessage()); +// retryTaskLog.setMessage(result.getMessage()); } else { - retryTaskLog.setMessage("客户端执行失败: 异常信息为空"); +// retryTaskLog.setMessage("客户端执行失败: 异常信息为空"); } } else { DispatchRetryResultDTO data = JsonUtil.parseObject(JsonUtil.toJsonString(result.getData()), DispatchRetryResultDTO.class); @@ -77,14 +80,14 @@ public class ExecUnitActor extends AbstractActor { if (Objects.nonNull(data)) { if (RetryResultStatusEnum.FAILURE.getStatus().equals(data.getStatusCode())) { if (StrUtil.isNotBlank(data.getExceptionMsg())) { - retryTaskLog.setMessage(data.getExceptionMsg()); +// retryTaskLog.setMessage(data.getExceptionMsg()); } else { - retryTaskLog.setMessage("客户端重试失败: 异常信息为空"); +// retryTaskLog.setMessage("客户端重试失败: 异常信息为空"); } } else if (RetryResultStatusEnum.STOP.getStatus().equals(data.getStatusCode())) { - retryTaskLog.setMessage("客户端主动停止任务"); +// retryTaskLog.setMessage("客户端主动停止任务"); } else { - retryTaskLog.setMessage("客户端执行成功"); +// retryTaskLog.setMessage("客户端执行成功"); } } @@ -95,19 +98,20 @@ public class ExecUnitActor extends AbstractActor { // 请求发生异常 if (context.hasException()) { - retryTaskLog.setMessage(context.getException().getMessage()); +// retryTaskLog.setMessage(context.getException().getMessage()); } } else { - retryTaskLog.setMessage("There are currently no available client PODs."); +// retryTaskLog.setMessage("There are currently no available client PODs."); } } catch (Exception e) { - EasyRetryLog.LOCAL.error("callback client error. retryTask:[{}]", JsonUtil.toJsonString(retryTask), e); - retryTaskLog.setMessage(e.getMessage()); + LogMetaDTO logMetaDTO = RetryTaskConverter.INSTANCE.toLogMetaDTO(retryTask); + logMetaDTO.setTimestamp(DateUtils.toNowMilli()); + EasyRetryLog.REMOTE.error("请求客户端异常. <|>{}<|>", retryTask.getUniqueId(), logMetaDTO, e); } finally { - ActorRef actorRef = ActorGenerator.logActor(); - actorRef.tell(retryTaskLog, actorRef); +// ActorRef actorRef = ActorGenerator.logActor(); +// actorRef.tell(retryTaskLog, actorRef); getContext().stop(getSelf()); } @@ -130,6 +134,8 @@ public class ExecUnitActor extends AbstractActor { dispatchRetryDTO.setArgsStr(retryTask.getArgsStr()); dispatchRetryDTO.setUniqueId(retryTask.getUniqueId()); dispatchRetryDTO.setRetryCount(retryTask.getRetryCount()); + dispatchRetryDTO.setGroupName(retryTask.getGroupName()); + dispatchRetryDTO.setNamespaceId(retryTask.getNamespaceId()); // 设置header EasyRetryHeaders easyRetryHeaders = new EasyRetryHeaders(); diff --git a/easy-retry-server/easy-retry-server-retry-task/src/main/java/com/aizuda/easy/retry/server/retry/task/support/dispatch/actor/log/LogActor.java b/easy-retry-server/easy-retry-server-retry-task/src/main/java/com/aizuda/easy/retry/server/retry/task/support/dispatch/actor/log/LogActor.java deleted file mode 100644 index 9bba0f0a..00000000 --- a/easy-retry-server/easy-retry-server-retry-task/src/main/java/com/aizuda/easy/retry/server/retry/task/support/dispatch/actor/log/LogActor.java +++ /dev/null @@ -1,80 +0,0 @@ -package com.aizuda.easy.retry.server.retry.task.support.dispatch.actor.log; - -import akka.actor.AbstractActor; -import cn.hutool.core.util.StrUtil; -import com.aizuda.easy.retry.common.core.enums.RetryStatusEnum; -import com.aizuda.easy.retry.server.common.akka.ActorGenerator; -import com.aizuda.easy.retry.template.datasource.persistence.mapper.RetryTaskLogMapper; -import com.aizuda.easy.retry.template.datasource.persistence.mapper.RetryTaskLogMessageMapper; -import com.aizuda.easy.retry.template.datasource.persistence.po.RetryTaskLog; -import com.aizuda.easy.retry.template.datasource.persistence.po.RetryTaskLogMessage; -import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.config.ConfigurableBeanFactory; -import org.springframework.context.annotation.Scope; -import org.springframework.stereotype.Component; - -import java.time.LocalDateTime; -import java.util.Optional; - -/** - * 处理日志信息 - * - * @author: www.byteblogs.com - * @date : 2023-06-16 11:33 - * @since 2.0.0 - */ -@Component(ActorGenerator.LOG_ACTOR) -@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) -@Slf4j -public class LogActor extends AbstractActor { - - @Autowired - private RetryTaskLogMessageMapper retryTaskLogMessageMapper; - @Autowired - private RetryTaskLogMapper retryTaskLogMapper; - - @Override - public Receive createReceive() { - return receiveBuilder().match(RetryTaskLogDTO.class, - retryTaskLogDTO -> RetryStatusEnum.RUNNING.getStatus().equals(retryTaskLogDTO.getRetryStatus()), - retryTaskLogDTO -> { - saveRetryTaskLogMessage(retryTaskLogDTO); - getContext().stop(getSelf()); - }).match(RetryTaskLogDTO.class, (retryTaskLogDTO) -> - RetryStatusEnum.MAX_COUNT.getStatus().equals(retryTaskLogDTO.getRetryStatus()) - || RetryStatusEnum.FINISH.getStatus().equals(retryTaskLogDTO.getRetryStatus()), - retryTaskLogDTO -> { - - // 变动日志的状态 - RetryTaskLog retryTaskLog = new RetryTaskLog(); - retryTaskLog.setRetryStatus(retryTaskLogDTO.getRetryStatus()); - retryTaskLogMapper.update(retryTaskLog, new LambdaUpdateWrapper() - .eq(RetryTaskLog::getNamespaceId, retryTaskLogDTO.getNamespaceId()) - .eq(RetryTaskLog::getUniqueId, retryTaskLogDTO.getUniqueId()) - .eq(RetryTaskLog::getGroupName, retryTaskLogDTO.getGroupName())); - - getContext().stop(getSelf()); - }).build(); - } - - /** - * 报错日志详情 - */ - private void saveRetryTaskLogMessage(final RetryTaskLogDTO retryTaskLogDTO) { - - // 记录重试日志 - RetryTaskLogMessage retryTaskLogMessage = new RetryTaskLogMessage(); - retryTaskLogMessage.setUniqueId(retryTaskLogDTO.getUniqueId()); - retryTaskLogMessage.setGroupName(retryTaskLogDTO.getGroupName()); - retryTaskLogMessage.setClientInfo(retryTaskLogDTO.getClientInfo()); - retryTaskLogMessage.setNamespaceId(retryTaskLogDTO.getNamespaceId()); - String errorMessage = retryTaskLogDTO.getMessage(); - retryTaskLogMessage.setMessage( - StrUtil.isBlank(errorMessage) ? StrUtil.EMPTY : errorMessage); - retryTaskLogMessage.setCreateDt(Optional.ofNullable(retryTaskLogDTO.getTriggerTime()).orElse(LocalDateTime.now())); - retryTaskLogMessageMapper.insert(retryTaskLogMessage); - - } -} diff --git a/easy-retry-server/easy-retry-server-retry-task/src/main/java/com/aizuda/easy/retry/server/retry/task/support/dispatch/actor/log/RetryLogActor.java b/easy-retry-server/easy-retry-server-retry-task/src/main/java/com/aizuda/easy/retry/server/retry/task/support/dispatch/actor/log/RetryLogActor.java new file mode 100644 index 00000000..ffefc30d --- /dev/null +++ b/easy-retry-server/easy-retry-server-retry-task/src/main/java/com/aizuda/easy/retry/server/retry/task/support/dispatch/actor/log/RetryLogActor.java @@ -0,0 +1,100 @@ +package com.aizuda.easy.retry.server.retry.task.support.dispatch.actor.log; + +import akka.actor.AbstractActor; +import cn.hutool.core.util.StrUtil; +import com.aizuda.easy.retry.common.core.util.JsonUtil; +import com.aizuda.easy.retry.common.log.dto.TaskLogFieldDTO; +import com.aizuda.easy.retry.server.common.akka.ActorGenerator; +import com.aizuda.easy.retry.server.model.dto.RetryLogTaskDTO; +import com.aizuda.easy.retry.server.retry.task.support.RetryTaskConverter; +import com.aizuda.easy.retry.template.datasource.persistence.mapper.RetryTaskLogMessageMapper; +import com.aizuda.easy.retry.template.datasource.persistence.po.RetryTaskLogMessage; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.stream.Collectors; + +/** + * 处理日志信息 + * + * @author: www.byteblogs.com + * @date : 2023-06-16 11:33 + * @since 2.0.0 + */ +@Component(ActorGenerator.LOG_ACTOR) +@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) +@Slf4j +public class RetryLogActor extends AbstractActor { + + @Autowired + private RetryTaskLogMessageMapper retryTaskLogMessageMapper; + + @Override + public Receive createReceive() { + return receiveBuilder().match(List.class, + list -> { + if (CollectionUtils.isEmpty(list)) { + return; + } + saveRetryTaskLogMessage((List) list); + getContext().stop(getSelf()); + }).match(RetryTaskLogDTO.class, + retryTaskLogDTO -> { + saveRetryTaskLogMessage(retryTaskLogDTO); + getContext().stop(getSelf()); + }).build(); + } + + private void saveRetryTaskLogMessage(final List list) { + + List jobLogTasks = list; + Map> logTaskDTOMap = jobLogTasks. + stream().collect(Collectors.groupingBy(RetryLogTaskDTO::getUniqueId, Collectors.toList())); + List retryTaskLogMessages = new ArrayList<>(); + for (List logTaskDTOList : logTaskDTOMap.values()) { + RetryTaskLogMessage retryTaskLogMessage = RetryTaskConverter.INSTANCE.toRetryTaskLogMessage( + logTaskDTOList.get(0)); + retryTaskLogMessage.setCreateDt(LocalDateTime.now()); + retryTaskLogMessage.setLogNum(logTaskDTOList.size()); + List> messageMapList = logTaskDTOList.stream() + .map(taskDTO -> taskDTO.getFieldList() + .stream().filter(logTaskDTO_ -> !Objects.isNull(logTaskDTO_.getValue())) + .collect(Collectors.toMap(TaskLogFieldDTO::getName, TaskLogFieldDTO::getValue))) + .collect(Collectors.toList()); + retryTaskLogMessage.setMessage(JsonUtil.toJsonString(messageMapList)); + + retryTaskLogMessages.add(retryTaskLogMessage); + } + + retryTaskLogMessageMapper.batchInsert(retryTaskLogMessages); + } + + /** + * 报错日志详情 + */ + private void saveRetryTaskLogMessage(final RetryTaskLogDTO retryTaskLogDTO) { + + // 记录重试日志 + RetryTaskLogMessage retryTaskLogMessage = new RetryTaskLogMessage(); + retryTaskLogMessage.setUniqueId(retryTaskLogDTO.getUniqueId()); + retryTaskLogMessage.setGroupName(retryTaskLogDTO.getGroupName()); + retryTaskLogMessage.setClientInfo(retryTaskLogDTO.getClientInfo()); + retryTaskLogMessage.setNamespaceId(retryTaskLogDTO.getNamespaceId()); + String errorMessage = retryTaskLogDTO.getMessage(); + retryTaskLogMessage.setMessage( + StrUtil.isBlank(errorMessage) ? StrUtil.EMPTY : errorMessage); + retryTaskLogMessage.setCreateDt(Optional.ofNullable(retryTaskLogDTO.getTriggerTime()).orElse(LocalDateTime.now())); + retryTaskLogMessageMapper.insert(retryTaskLogMessage); + + } +} diff --git a/easy-retry-server/easy-retry-server-retry-task/src/main/java/com/aizuda/easy/retry/server/retry/task/support/dispatch/actor/log/RetryTaskLogDTO.java b/easy-retry-server/easy-retry-server-retry-task/src/main/java/com/aizuda/easy/retry/server/retry/task/support/dispatch/actor/log/RetryTaskLogDTO.java index a2c2f4c3..f0f0fbdd 100644 --- a/easy-retry-server/easy-retry-server-retry-task/src/main/java/com/aizuda/easy/retry/server/retry/task/support/dispatch/actor/log/RetryTaskLogDTO.java +++ b/easy-retry-server/easy-retry-server-retry-task/src/main/java/com/aizuda/easy/retry/server/retry/task/support/dispatch/actor/log/RetryTaskLogDTO.java @@ -49,4 +49,9 @@ public class RetryTaskLogDTO { */ private String clientInfo; + /** + * 真实上报时间 + */ + private Long realTime; + } diff --git a/easy-retry-server/easy-retry-server-retry-task/src/main/java/com/aizuda/easy/retry/server/retry/task/support/dispatch/actor/result/FailureActor.java b/easy-retry-server/easy-retry-server-retry-task/src/main/java/com/aizuda/easy/retry/server/retry/task/support/dispatch/actor/result/FailureActor.java index e6a006fc..4b2faf17 100644 --- a/easy-retry-server/easy-retry-server-retry-task/src/main/java/com/aizuda/easy/retry/server/retry/task/support/dispatch/actor/result/FailureActor.java +++ b/easy-retry-server/easy-retry-server-retry-task/src/main/java/com/aizuda/easy/retry/server/retry/task/support/dispatch/actor/result/FailureActor.java @@ -11,13 +11,17 @@ import com.aizuda.easy.retry.server.common.akka.ActorGenerator; import com.aizuda.easy.retry.server.common.config.SystemProperties; import com.aizuda.easy.retry.server.common.enums.SyetemTaskTypeEnum; import com.aizuda.easy.retry.server.common.exception.EasyRetryServerException; +import com.aizuda.easy.retry.server.retry.task.dto.LogMetaDTO; import com.aizuda.easy.retry.server.retry.task.support.RetryTaskLogConverter; import com.aizuda.easy.retry.server.retry.task.support.dispatch.actor.log.RetryTaskLogDTO; import com.aizuda.easy.retry.server.retry.task.support.event.RetryTaskFailMoreThresholdAlarmEvent; import com.aizuda.easy.retry.server.retry.task.support.handler.CallbackRetryTaskHandler; import com.aizuda.easy.retry.template.datasource.access.AccessTemplate; +import com.aizuda.easy.retry.template.datasource.persistence.mapper.RetryTaskLogMapper; import com.aizuda.easy.retry.template.datasource.persistence.po.RetryTask; +import com.aizuda.easy.retry.template.datasource.persistence.po.RetryTaskLog; import com.aizuda.easy.retry.template.datasource.persistence.po.SceneConfig; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; @@ -55,13 +59,13 @@ public class FailureActor extends AbstractActor { @Autowired @Qualifier("retryIdempotentStrategyHandler") private IdempotentStrategy, Long> idempotentStrategy; - + @Autowired + private RetryTaskLogMapper retryTaskLogMapper; @Override public Receive createReceive() { return receiveBuilder().match(RetryTask.class, retryTask -> { EasyRetryLog.LOCAL.debug("FailureActor params:[{}]", retryTask); - try { // 超过最大等级 SceneConfig sceneConfig = @@ -91,6 +95,14 @@ public class FailureActor extends AbstractActor { () -> new EasyRetryServerException("更新重试任务失败. groupName:[{}] uniqueId:[{}]", retryTask.getGroupName(), retryTask.getUniqueId())); + // 变动日志的状态 + RetryTaskLog retryTaskLog = new RetryTaskLog(); + retryTaskLog.setRetryStatus(retryTask.getRetryStatus()); + retryTaskLogMapper.update(retryTaskLog, new LambdaUpdateWrapper() + .eq(RetryTaskLog::getNamespaceId, retryTask.getNamespaceId()) + .eq(RetryTaskLog::getUniqueId, retryTask.getUniqueId()) + .eq(RetryTaskLog::getGroupName, retryTask.getGroupName())); + context.publishEvent(new RetryTaskFailMoreThresholdAlarmEvent(retryTask)); } }); @@ -99,15 +111,6 @@ public class FailureActor extends AbstractActor { } finally { // 清除幂等标识位 idempotentStrategy.clear(Pair.of(retryTask.getGroupName(), retryTask.getNamespaceId()), retryTask.getId()); - - if (RetryStatusEnum.MAX_COUNT.getStatus().equals(retryTask.getRetryStatus())) { - - RetryTaskLogDTO retryTaskLogDTO = RetryTaskLogConverter.INSTANCE.toRetryTaskLogDTO(retryTask); - retryTaskLogDTO.setMessage("任务已经到达最大执行次数了."); - ActorRef actorRef = ActorGenerator.logActor(); - actorRef.tell(retryTaskLogDTO, actorRef); - } - getContext().stop(getSelf()); } diff --git a/easy-retry-server/easy-retry-server-retry-task/src/main/java/com/aizuda/easy/retry/server/retry/task/support/dispatch/actor/result/FinishActor.java b/easy-retry-server/easy-retry-server-retry-task/src/main/java/com/aizuda/easy/retry/server/retry/task/support/dispatch/actor/result/FinishActor.java index 65cfb55d..6e63a9b8 100644 --- a/easy-retry-server/easy-retry-server-retry-task/src/main/java/com/aizuda/easy/retry/server/retry/task/support/dispatch/actor/result/FinishActor.java +++ b/easy-retry-server/easy-retry-server-retry-task/src/main/java/com/aizuda/easy/retry/server/retry/task/support/dispatch/actor/result/FinishActor.java @@ -13,7 +13,10 @@ import com.aizuda.easy.retry.server.retry.task.support.RetryTaskLogConverter; import com.aizuda.easy.retry.server.retry.task.support.dispatch.actor.log.RetryTaskLogDTO; import com.aizuda.easy.retry.server.retry.task.support.handler.CallbackRetryTaskHandler; import com.aizuda.easy.retry.template.datasource.access.AccessTemplate; +import com.aizuda.easy.retry.template.datasource.persistence.mapper.RetryTaskLogMapper; import com.aizuda.easy.retry.template.datasource.persistence.po.RetryTask; +import com.aizuda.easy.retry.template.datasource.persistence.po.RetryTaskLog; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; @@ -40,6 +43,7 @@ import java.time.LocalDateTime; @Slf4j public class FinishActor extends AbstractActor { + @Autowired private AccessTemplate accessTemplate; @Autowired @@ -49,6 +53,8 @@ public class FinishActor extends AbstractActor { @Autowired @Qualifier("retryIdempotentStrategyHandler") private IdempotentStrategy, Long> idempotentStrategy; + @Autowired + private RetryTaskLogMapper retryTaskLogMapper; @Override public Receive createReceive() { @@ -70,6 +76,15 @@ public class FinishActor extends AbstractActor { // 创建一个回调任务 callbackRetryTaskHandler.create(retryTask); + + // 变动日志的状态 + RetryTaskLog retryTaskLog = new RetryTaskLog(); + retryTaskLog.setRetryStatus(retryTask.getRetryStatus()); + retryTaskLogMapper.update(retryTaskLog, new LambdaUpdateWrapper() + .eq(RetryTaskLog::getNamespaceId, retryTask.getNamespaceId()) + .eq(RetryTaskLog::getUniqueId, retryTask.getUniqueId()) + .eq(RetryTaskLog::getGroupName, retryTask.getGroupName())); + } }); @@ -79,11 +94,6 @@ public class FinishActor extends AbstractActor { // 清除幂等标识位 idempotentStrategy.clear(Pair.of(retryTask.getGroupName(), retryTask.getNamespaceId()), retryTask.getId()); - RetryTaskLogDTO retryTaskLogDTO = RetryTaskLogConverter.INSTANCE.toRetryTaskLogDTO(retryTask); - retryTaskLogDTO.setMessage("任务已经执行成功了."); - ActorRef actorRef = ActorGenerator.logActor(); - actorRef.tell(retryTaskLogDTO, actorRef); - getContext().stop(getSelf()); } diff --git a/easy-retry-server/easy-retry-server-retry-task/src/main/java/com/aizuda/easy/retry/server/retry/task/support/dispatch/task/AbstractTaskExecutor.java b/easy-retry-server/easy-retry-server-retry-task/src/main/java/com/aizuda/easy/retry/server/retry/task/support/dispatch/task/AbstractTaskExecutor.java index 0542a255..d311a383 100644 --- a/easy-retry-server/easy-retry-server-retry-task/src/main/java/com/aizuda/easy/retry/server/retry/task/support/dispatch/task/AbstractTaskExecutor.java +++ b/easy-retry-server/easy-retry-server-retry-task/src/main/java/com/aizuda/easy/retry/server/retry/task/support/dispatch/task/AbstractTaskExecutor.java @@ -2,11 +2,15 @@ package com.aizuda.easy.retry.server.retry.task.support.dispatch.task; import akka.actor.ActorRef; import cn.hutool.core.lang.Pair; +import com.aizuda.easy.retry.common.log.EasyRetryLog; import com.aizuda.easy.retry.server.common.akka.ActorGenerator; import com.aizuda.easy.retry.server.common.config.SystemProperties; import com.aizuda.easy.retry.server.common.handler.ClientNodeAllocateHandler; import com.aizuda.easy.retry.server.common.IdempotentStrategy; +import com.aizuda.easy.retry.server.common.util.DateUtils; +import com.aizuda.easy.retry.server.retry.task.dto.LogMetaDTO; import com.aizuda.easy.retry.server.retry.task.support.RetryContext; +import com.aizuda.easy.retry.server.retry.task.support.RetryTaskConverter; import com.aizuda.easy.retry.server.retry.task.support.dispatch.actor.log.RetryTaskLogDTO; import com.aizuda.easy.retry.server.retry.task.support.retry.RetryExecutor; import com.aizuda.easy.retry.template.datasource.access.AccessTemplate; @@ -66,14 +70,18 @@ public abstract class AbstractTaskExecutor implements TaskExecutor, Initializing retryTask.getUniqueId(), pair.getValue().toString()); // 记录日志 - RetryTaskLogDTO retryTaskLog = new RetryTaskLogDTO(); - retryTaskLog.setGroupName(retryTask.getGroupName()); - retryTaskLog.setUniqueId(retryTask.getUniqueId()); - retryTaskLog.setRetryStatus(retryTask.getRetryStatus()); - retryTaskLog.setMessage(pair.getValue().toString()); - retryTaskLog.setTriggerTime(LocalDateTime.now()); - ActorRef actorRef = ActorGenerator.logActor(); - actorRef.tell(retryTaskLog, actorRef); +// RetryTaskLogDTO retryTaskLog = new RetryTaskLogDTO(); +// retryTaskLog.setGroupName(retryTask.getGroupName()); +// retryTaskLog.setUniqueId(retryTask.getUniqueId()); +// retryTaskLog.setRetryStatus(retryTask.getRetryStatus()); +// retryTaskLog.setMessage(pair.getValue().toString()); +// retryTaskLog.setTriggerTime(LocalDateTime.now()); +// ActorRef actorRef = ActorGenerator.logActor(); + + LogMetaDTO logMetaDTO = RetryTaskConverter.INSTANCE.toLogMetaDTO(retryTask); + logMetaDTO.setTimestamp(DateUtils.toNowMilli()); + EasyRetryLog.REMOTE.error("触发条件不满足 原因: [{}] <|>{}<|>", pair.getValue().toString(), logMetaDTO); + return false; } diff --git a/easy-retry-server/easy-retry-server-starter/src/main/java/com/aizuda/easy/retry/server/starter/server/RequestHandlerActor.java b/easy-retry-server/easy-retry-server-starter/src/main/java/com/aizuda/easy/retry/server/starter/server/RequestHandlerActor.java index d4ebc1f6..9ad51a2a 100644 --- a/easy-retry-server/easy-retry-server-starter/src/main/java/com/aizuda/easy/retry/server/starter/server/RequestHandlerActor.java +++ b/easy-retry-server/easy-retry-server-starter/src/main/java/com/aizuda/easy/retry/server/starter/server/RequestHandlerActor.java @@ -103,7 +103,6 @@ public class RequestHandlerActor extends AbstractActor { EasyRetryLog.LOCAL.warn("client register error. groupName:[{}]", groupName); } - UrlBuilder builder = UrlBuilder.ofHttp(uri); Collection httpRequestHandlers = SpringContext.CONTEXT .getBeansOfType(HttpRequestHandler.class).values(); diff --git a/easy-retry-server/easy-retry-server-starter/src/main/java/com/aizuda/easy/retry/server/starter/server/handler/BeatHttpRequestHandler.java b/easy-retry-server/easy-retry-server-starter/src/main/java/com/aizuda/easy/retry/server/starter/server/handler/BeatHttpRequestHandler.java index ed67811b..72efe78f 100644 --- a/easy-retry-server/easy-retry-server-starter/src/main/java/com/aizuda/easy/retry/server/starter/server/handler/BeatHttpRequestHandler.java +++ b/easy-retry-server/easy-retry-server-starter/src/main/java/com/aizuda/easy/retry/server/starter/server/handler/BeatHttpRequestHandler.java @@ -37,7 +37,7 @@ public class BeatHttpRequestHandler extends GetHttpRequestHandler { @Override public String doHandler(String content, UrlQuery query, HttpHeaders headers) { - EasyRetryLog.LOCAL.info("Beat check content:[{}]", content); + EasyRetryLog.LOCAL.debug("Beat check content:[{}]", content); EasyRetryRequest retryRequest = JsonUtil.parseObject(content, EasyRetryRequest.class); return JsonUtil.toJsonString(new NettyResult(PONG, retryRequest.getReqId())); } diff --git a/easy-retry-server/easy-retry-server-starter/src/main/java/com/aizuda/easy/retry/server/starter/server/handler/ReportLogHttpRequestHandler.java b/easy-retry-server/easy-retry-server-starter/src/main/java/com/aizuda/easy/retry/server/starter/server/handler/ReportLogHttpRequestHandler.java new file mode 100644 index 00000000..7a2edd8f --- /dev/null +++ b/easy-retry-server/easy-retry-server-starter/src/main/java/com/aizuda/easy/retry/server/starter/server/handler/ReportLogHttpRequestHandler.java @@ -0,0 +1,102 @@ +package com.aizuda.easy.retry.server.starter.server.handler; + +import akka.actor.ActorRef; +import cn.hutool.core.lang.Assert; +import cn.hutool.core.net.url.UrlQuery; +import com.aizuda.easy.retry.common.core.enums.HeadersEnum; +import com.aizuda.easy.retry.common.core.enums.StatusEnum; +import com.aizuda.easy.retry.common.core.model.EasyRetryRequest; +import com.aizuda.easy.retry.common.core.model.NettyResult; +import com.aizuda.easy.retry.common.core.util.JsonUtil; +import com.aizuda.easy.retry.common.log.EasyRetryLog; +import com.aizuda.easy.retry.common.log.enums.LogTypeEnum; +import com.aizuda.easy.retry.server.common.akka.ActorGenerator; +import com.aizuda.easy.retry.server.common.dto.RegisterNodeInfo; +import com.aizuda.easy.retry.server.common.exception.EasyRetryServerException; +import com.aizuda.easy.retry.server.common.handler.PostHttpRequestHandler; +import com.aizuda.easy.retry.server.common.util.ClientInfoUtils; +import com.aizuda.easy.retry.server.model.dto.JobLogTaskDTO; +import com.aizuda.easy.retry.server.model.dto.RetryLogTaskDTO; +import com.fasterxml.jackson.databind.JsonNode; +import com.google.common.collect.Lists; +import io.netty.handler.codec.http.HttpHeaders; +import io.netty.handler.codec.http.HttpMethod; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; + +import java.util.List; + +import static com.aizuda.easy.retry.common.core.constant.SystemConstants.HTTP_PATH.BATCH_LOG_REPORT; + +/** + * 处理日志上报数据 + * + * @author: wodeyangzipingpingwuqi + * @date : 2023-12-26 + * @since 1.0.0 + */ +@Component +public class ReportLogHttpRequestHandler extends PostHttpRequestHandler { + + private static final String JSON_FILED = "logType" ; + @Override + public boolean supports(String path) { + return BATCH_LOG_REPORT.equals(path); + } + + @Override + public HttpMethod method() { + return HttpMethod.POST; + } + + @Override + public String doHandler(String content, UrlQuery urlQuery, HttpHeaders headers) { + + EasyRetryLog.LOCAL.info("Begin Handler Log Report Data. [{}]", content); + EasyRetryRequest retryRequest = JsonUtil.parseObject(content, EasyRetryRequest.class); + Object[] args = retryRequest.getArgs(); + + Assert.notEmpty(args, () -> new EasyRetryServerException("日志上报的数据不能为空. ReqId:[{}]", retryRequest.getReqId())); + + JsonNode jsonNode = JsonUtil.toJson(args[0]); + List retryTasks = Lists.newArrayList(); + List jobTasks = Lists.newArrayList(); + for (final JsonNode node : jsonNode) { + if (node.findValue(JSON_FILED).asText().equals(LogTypeEnum.JOB.name())) { + jobTasks.add(JsonUtil.parseObject(node.toPrettyString(), JobLogTaskDTO.class)); + } + + if (node.findValue(JSON_FILED).asText().equals(LogTypeEnum.RETRY.name())) { + retryTasks.add(JsonUtil.parseObject(node.toPrettyString(), RetryLogTaskDTO.class)); + } + } + + // 批量新增日志数据 + if (!CollectionUtils.isEmpty(jobTasks)) { + ActorRef actorRef = ActorGenerator.jobLogActor(); + actorRef.tell(jobTasks, actorRef); + } + + if (!CollectionUtils.isEmpty(retryTasks)) { + String clintInfo = getClientInfo(headers); + for (final RetryLogTaskDTO retryTask : retryTasks) { + retryTask.setClientInfo(clintInfo); + } + ActorRef actorRef = ActorGenerator.logActor(); + actorRef.tell(retryTasks, actorRef); + } + + return JsonUtil.toJsonString(new NettyResult(StatusEnum.YES.getStatus(), "Batch Log Retry Data Upload Processed Successfully", Boolean.TRUE, retryRequest.getReqId())); + } + + private String getClientInfo(final HttpHeaders headers) { + String hostId = headers.get(HeadersEnum.HOST_ID.getKey()); + String hostIp = headers.get(HeadersEnum.HOST_IP.getKey()); + Integer hostPort = headers.getInt(HeadersEnum.HOST_PORT.getKey()); + RegisterNodeInfo registerNodeInfo = new RegisterNodeInfo(); + registerNodeInfo.setHostIp(hostIp); + registerNodeInfo.setHostPort(hostPort); + registerNodeInfo.setHostId(hostId); + return ClientInfoUtils.generate(registerNodeInfo); + } +} diff --git a/easy-retry-server/easy-retry-server-starter/src/main/resources/logback-boot.xml b/easy-retry-server/easy-retry-server-starter/src/main/resources/logback-boot.xml index 31ecd73c..58d30e7e 100644 --- a/easy-retry-server/easy-retry-server-starter/src/main/resources/logback-boot.xml +++ b/easy-retry-server/easy-retry-server-starter/src/main/resources/logback-boot.xml @@ -81,6 +81,8 @@ + + @@ -89,5 +91,6 @@ +