diff --git a/server/common/common-service/src/main/java/io/holoinsight/server/common/service/FuseProtector.java b/server/common/common-service/src/main/java/io/holoinsight/server/common/service/FuseProtector.java deleted file mode 100644 index ec63a8234..000000000 --- a/server/common/common-service/src/main/java/io/holoinsight/server/common/service/FuseProtector.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright 2022 Holoinsight Project Authors. Licensed under Apache-2.0. - */ -package io.holoinsight.server.common.service; - -import org.springframework.util.CollectionUtils; - -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.CopyOnWriteArrayList; -import java.util.concurrent.atomic.AtomicInteger; - -/** - * Monitor background tasks such as alarm calculation, and fuse when the threshold is reached. Used - * for health check, e2e test. - * - * @author masaimu - * @version 2023-03-13 18:27:00 - */ -public class FuseProtector { - - private static final String CRITICAL = "critical"; - private static final String NORMAL = "normal"; - - public static final String CRITICAL_AlertSaveHistoryHandler = "AlertSaveHistoryHandler"; - public static final String CRITICAL_AlertTaskCompute = "AlertTaskCompute"; - public static final String CRITICAL_AlertTaskScheduler = "AlertTaskScheduler"; - public static final String CRITICAL_GetSubscription = "GetSubscription"; - - public static final String NORMAL_NotifyChain = "NotifyChain"; - public static final String NORMAL_AlertNotifyHandler = "AlertNotifyHandler"; - public static final String NORMAL_AlertSaveHistoryDetail = "AlertSaveHistoryDetail"; - public static final String NORMAL_MakeAlertRecover = "MakeAlertRecover"; - public static final String NORMAL_GetSubscriptionDetail = "GetSubscriptionDetail"; - - protected static Map> criticalEventMap = - new ConcurrentHashMap<>(); - protected static Map> normalEventMap = - new ConcurrentHashMap<>(); - protected static Map completeEventMap = - new ConcurrentHashMap<>(); - - public static void voteCriticalError(String name, String msg) { - List set = - criticalEventMap.computeIfAbsent(name, k -> new CopyOnWriteArrayList<>()); - set.add(new EventResult(CRITICAL, name, msg)); - } - - public static void voteNormalError(String name, String msg) { - List set = normalEventMap.computeIfAbsent(name, k -> new CopyOnWriteArrayList<>()); - set.add(new EventResult(NORMAL, name, msg)); - } - - public static void voteComplete(String name) { - AtomicInteger atomicInteger = completeEventMap.computeIfAbsent(name, k -> new AtomicInteger(0)); - atomicInteger.incrementAndGet(); - } - - /** - * - * @throws HoloInsightCriticalException failed assert - */ - public static synchronized void doAssert() throws HoloInsightCriticalException { - if (!CollectionUtils.isEmpty(criticalEventMap)) { - EventResult eventResult = getFirstEventResult(criticalEventMap, 0); - if (eventResult != null) { - throw new HoloInsightCriticalException(eventResult.msg, eventResult.name, - eventResult.timestamp); - } - } - - if (CollectionUtils.isEmpty(normalEventMap)) { - return; - } - - if (CollectionUtils.isEmpty(completeEventMap)) { - EventResult eventResult = getFirstEventResult(normalEventMap, 10); - if (eventResult != null) { - throw new HoloInsightCriticalException(eventResult.msg, eventResult.name, - eventResult.timestamp); - } - } - - compareSize(completeEventMap, normalEventMap, 10); - } - - /** - * - * @return true: pass, false: pending - */ - public static synchronized boolean doAssert(List keywords) { - if (!CollectionUtils.isEmpty(keywords)) { - for (String keyword : keywords) { - AtomicInteger atomicInteger = completeEventMap.get(keyword); - if (atomicInteger == null || atomicInteger.get() <= 0) { - return false; - } - } - } - return true; - } - - public static synchronized void clean() { - criticalEventMap = new ConcurrentHashMap<>(); - normalEventMap = new ConcurrentHashMap<>(); - completeEventMap = new ConcurrentHashMap<>(); - } - - private static void compareSize(Map completeEventMap, - Map> normalEventMap, int threshold) { - Set keySet = new HashSet<>(); - keySet.addAll(completeEventMap.keySet()); - keySet.addAll(normalEventMap.keySet()); - for (String key : keySet) { - AtomicInteger completeList = completeEventMap.get(key); - int completeSize = completeList == null ? 0 : completeList.get(); - List normalList = normalEventMap.get(key); - int normalSize = CollectionUtils.isEmpty(normalList) ? 0 : normalList.size(); - if (completeSize < normalSize && normalSize > threshold) { - throw new HoloInsightCriticalException("more fail result", key); - } - } - } - - private static EventResult getFirstEventResult(Map> eventMap, - int threshold) { - for (Map.Entry> entry : eventMap.entrySet()) { - List eventResults = entry.getValue(); - if (!CollectionUtils.isEmpty(eventResults) && eventResults.size() > threshold) { - return eventResults.get(0); - } - } - return null; - } - - public static class EventResult { - String level; - String name; - String msg; - long timestamp; - - public EventResult(String level, String name, String msg) { - this.level = level; - this.name = name; - this.msg = msg; - this.timestamp = System.currentTimeMillis(); - } - } -} diff --git a/server/common/common-service/src/test/java/io/holoinsight/server/common/service/FuseProtectorTest.java b/server/common/common-service/src/test/java/io/holoinsight/server/common/service/FuseProtectorTest.java deleted file mode 100644 index 731dbeb2c..000000000 --- a/server/common/common-service/src/test/java/io/holoinsight/server/common/service/FuseProtectorTest.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright 2022 Holoinsight Project Authors. Licensed under Apache-2.0. - */ - -package io.holoinsight.server.common.service; - -import org.apache.commons.lang3.StringUtils; -import org.junit.After; -import org.junit.Test; -import org.springframework.util.Assert; -import org.springframework.util.CollectionUtils; - -import java.util.Arrays; - -import static io.holoinsight.server.common.service.FuseProtector.CRITICAL_AlertSaveHistoryHandler; -import static io.holoinsight.server.common.service.FuseProtector.CRITICAL_AlertTaskCompute; -import static io.holoinsight.server.common.service.FuseProtector.CRITICAL_AlertTaskScheduler; -import static io.holoinsight.server.common.service.FuseProtector.NORMAL_NotifyChain; - -/** - * @author masaimu - * @version 2023-03-15 15:54:00 - */ -public class FuseProtectorTest { - - @After - public void tearDown() throws Exception { - FuseProtector.clean(); - } - - @Test - public void testVoteCriticalError() { - FuseProtector.voteCriticalError(CRITICAL_AlertSaveHistoryHandler, "test critical"); - Exception exception = null; - try { - FuseProtector.doAssert(); - } catch (Exception e) { - exception = e; - } - Assert.notNull(exception, "can not be null"); - Assert.isInstanceOf(HoloInsightCriticalException.class, exception); - Assert.isTrue(StringUtils.equals("test critical", exception.getMessage()), "exception equal"); - } - - @Test - public void testVoteNormalError() { - FuseProtector.voteNormalError(NORMAL_NotifyChain, "test normal"); - Exception exception = null; - try { - FuseProtector.doAssert(); - } catch (Exception e) { - exception = e; - } - Assert.isNull(exception, "should be null"); - - for (int i = 0; i < 10; i++) { - FuseProtector.voteNormalError(NORMAL_NotifyChain, "test normal"); - } - try { - FuseProtector.doAssert(); - } catch (Exception e) { - exception = e; - } - Assert.notNull(exception, "can not be null"); - Assert.isInstanceOf(HoloInsightCriticalException.class, exception); - Assert.isTrue(StringUtils.equals("test normal", exception.getMessage()), "exception equal"); - } - - @Test - public void testVoteComplete() { - Assert.isTrue( - !FuseProtector - .doAssert(Arrays.asList(CRITICAL_AlertTaskCompute, CRITICAL_AlertTaskScheduler)), - "should be pending"); - - FuseProtector.voteComplete(CRITICAL_AlertTaskCompute); - Assert.isTrue( - !FuseProtector - .doAssert(Arrays.asList(CRITICAL_AlertTaskCompute, CRITICAL_AlertTaskScheduler)), - "should be pending"); - - FuseProtector.voteComplete(CRITICAL_AlertTaskScheduler); - Assert.isTrue( - FuseProtector - .doAssert(Arrays.asList(CRITICAL_AlertTaskCompute, CRITICAL_AlertTaskScheduler)), - "should complete"); - } - - @Test - public void testClean() { - FuseProtector.voteNormalError(NORMAL_NotifyChain, "test normal"); - FuseProtector.voteComplete(CRITICAL_AlertTaskCompute); - FuseProtector.voteCriticalError(CRITICAL_AlertSaveHistoryHandler, "test critical"); - FuseProtector.clean(); - Assert.isTrue(CollectionUtils.isEmpty(FuseProtector.criticalEventMap), "should be cleaned"); - Assert.isTrue(CollectionUtils.isEmpty(FuseProtector.normalEventMap), "should be cleaned"); - Assert.isTrue(CollectionUtils.isEmpty(FuseProtector.completeEventMap), "should be cleaned"); - - } -} diff --git a/server/extension/extension-common-flyway/src/main/resources/db/migration/V15__230718_CREATE_alert_notify_record_TABLE.sql b/server/extension/extension-common-flyway/src/main/resources/db/migration/V15__230718_CREATE_alert_notify_record_TABLE.sql new file mode 100644 index 000000000..6e6e6573b --- /dev/null +++ b/server/extension/extension-common-flyway/src/main/resources/db/migration/V15__230718_CREATE_alert_notify_record_TABLE.sql @@ -0,0 +1,22 @@ +CREATE TABLE `alert_notify_record` ( + `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键id', + `history_id` BIGINT DEFAULT NULL COMMENT '历史id', + `history_detail_id` BIGINT DEFAULT NULL COMMENT '历史详情id', + `unique_id` VARCHAR ( 64 ) DEFAULT NULL, + `rule_name` VARCHAR ( 255 ) DEFAULT NULL COMMENT '告警规则名称', + `gmt_create` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP comment '创建时间', + `gmt_modified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP comment '修改时间', + `notify_error_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '告警异常时间', + `is_success` TINYINT NOT NULL COMMENT '告警是否成功', + `notify_channel` VARCHAR ( 255 ) DEFAULT NULL COMMENT '通知渠道', + `notify_error_node` LONGTEXT DEFAULT NULL COMMENT '通知异常节点', + `notify_user` TEXT DEFAULT NULL COMMENT '通知人信息', + `tenant` VARCHAR ( 64 ) DEFAULT NULL COMMENT '租户', + `extra` LONGTEXT DEFAULT NULL COMMENT '额外信息', + `trigger_result` LONGTEXT DEFAULT NULL COMMENT '告警计算信息', + `env_type` VARCHAR ( 255 ) DEFAULT NULL COMMENT '运行环境', + `workspace` VARCHAR ( 64 ) DEFAULT NULL, + PRIMARY KEY ( `id` ), + INDEX ( `history_detail_id` ), + INDEX ( `history_id` ), + INDEX ( `unique_id` )) ENGINE = INNODB COMMENT = '告警通知记录'; \ No newline at end of file diff --git a/server/home/home-alert/src/main/java/io/holoinsight/server/home/alert/model/compute/ComputeTaskPackage.java b/server/home/home-alert/src/main/java/io/holoinsight/server/home/alert/model/compute/ComputeTaskPackage.java index ca5b1041c..933a2e958 100644 --- a/server/home/home-alert/src/main/java/io/holoinsight/server/home/alert/model/compute/ComputeTaskPackage.java +++ b/server/home/home-alert/src/main/java/io/holoinsight/server/home/alert/model/compute/ComputeTaskPackage.java @@ -3,6 +3,8 @@ */ package io.holoinsight.server.home.alert.model.compute; +import io.holoinsight.server.home.dal.model.AlertNotifyRecord; +import io.holoinsight.server.home.facade.AlertNotifyRecordDTO; import io.holoinsight.server.home.facade.InspectConfig; import lombok.Data; @@ -34,4 +36,9 @@ public class ComputeTaskPackage { // 后续可以考虑聚合数据源查询 + /** + * 告警通知记录 + */ + public AlertNotifyRecordDTO alertNotifyRecord; + } diff --git a/server/home/home-alert/src/main/java/io/holoinsight/server/home/alert/model/event/AlertNotify.java b/server/home/home-alert/src/main/java/io/holoinsight/server/home/alert/model/event/AlertNotify.java index a088981cb..fd13f235f 100644 --- a/server/home/home-alert/src/main/java/io/holoinsight/server/home/alert/model/event/AlertNotify.java +++ b/server/home/home-alert/src/main/java/io/holoinsight/server/home/alert/model/event/AlertNotify.java @@ -4,6 +4,9 @@ package io.holoinsight.server.home.alert.model.event; import io.holoinsight.server.common.AddressUtil; +import io.holoinsight.server.common.J; +import io.holoinsight.server.home.alert.service.event.RecordSucOrFailNotify; +import io.holoinsight.server.home.facade.AlertNotifyRecordDTO; import io.holoinsight.server.home.facade.InspectConfig; import io.holoinsight.server.home.facade.PqlRule; import io.holoinsight.server.home.facade.TemplateValue; @@ -23,6 +26,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; /** * @author wangsiyuan @@ -94,32 +98,53 @@ public class AlertNotify { private List logSample; - public static AlertNotify eventInfoConvert(EventInfo eventInfo, InspectConfig inspectConfig) { + private AlertNotifyRecordDTO alertNotifyRecord; + + private boolean alertRecord; + + public static AlertNotify eventInfoConvert(EventInfo eventInfo, InspectConfig inspectConfig, + List alertNotifyRecordDTOS) { AlertNotify alertNotify = new AlertNotify(); - BeanUtils.copyProperties(inspectConfig, alertNotify); - BeanUtils.copyProperties(eventInfo, alertNotify); - if (!eventInfo.getIsRecover()) { - alertNotify.setIsPql(inspectConfig.getIsPql() != null && inspectConfig.getIsPql()); - Map> notifyDataInfoMap = new HashMap<>(); - eventInfo.getAlarmTriggerResults().forEach((trigger, resultList) -> { - List notifyDataInfos = new ArrayList<>(); - resultList.forEach(result -> { - NotifyDataInfo notifyDataInfo = new NotifyDataInfo(); - notifyDataInfo.setMetric(result.getMetric()); - notifyDataInfo.setTags(result.getTags()); - notifyDataInfo.setCurrentValue(result.getCurrentValue()); - notifyDataInfo.setTriggerContent(result.getTriggerContent()); - notifyDataInfos.add(notifyDataInfo); + try { + BeanUtils.copyProperties(inspectConfig, alertNotify); + BeanUtils.copyProperties(eventInfo, alertNotify); + if (!eventInfo.getIsRecover()) { + alertNotify.setIsPql(inspectConfig.getIsPql() != null && inspectConfig.getIsPql()); + Map> notifyDataInfoMap = new HashMap<>(); + eventInfo.getAlarmTriggerResults().forEach((trigger, resultList) -> { + List notifyDataInfos = new ArrayList<>(); + resultList.forEach(result -> { + NotifyDataInfo notifyDataInfo = new NotifyDataInfo(); + notifyDataInfo.setMetric(result.getMetric()); + notifyDataInfo.setTags(result.getTags()); + notifyDataInfo.setCurrentValue(result.getCurrentValue()); + notifyDataInfo.setTriggerContent(result.getTriggerContent()); + notifyDataInfos.add(notifyDataInfo); + }); + notifyDataInfoMap.put(trigger, notifyDataInfos); }); - notifyDataInfoMap.put(trigger, notifyDataInfos); - }); - alertNotify.setNotifyDataInfos(notifyDataInfoMap); - alertNotify.setAggregationNum(notifyDataInfoMap.size()); - alertNotify.setEnvType(eventInfo.getEnvType()); - // 对于平台消费侧,可能需要知道完整的告警规则 - alertNotify.setRuleConfig(inspectConfig); - tryFixAlertLevel(alertNotify, eventInfo.getAlarmTriggerResults()); - alertNotify.setAlertServer(AddressUtil.getHostAddress()); + // add alert trigger result for record + if (!CollectionUtils.isEmpty(alertNotifyRecordDTOS)) { + for (AlertNotifyRecordDTO alertNotifyRecord : alertNotifyRecordDTOS) { + if (Objects.equals(alertNotifyRecord.getUniqueId(), alertNotify.getUniqueId())) { + alertNotifyRecord.setTriggerResult(J.toJson(notifyDataInfoMap.values())); + alertNotify.setAlertNotifyRecord(alertNotifyRecord); + break; + } + } + } + alertNotify.setNotifyDataInfos(notifyDataInfoMap); + alertNotify.setAggregationNum(notifyDataInfoMap.size()); + alertNotify.setEnvType(eventInfo.getEnvType()); + // 对于平台消费侧,可能需要知道完整的告警规则 + alertNotify.setRuleConfig(inspectConfig); + tryFixAlertLevel(alertNotify, eventInfo.getAlarmTriggerResults()); + alertNotify.setAlertServer(AddressUtil.getHostAddress()); + } + } catch (Exception e) { + RecordSucOrFailNotify.alertNotifyProcess("event convert alert notify exception" + e, + "alert task compute", "event convert alert notify", alertNotify.getAlertNotifyRecord()); + throw e; } return alertNotify; } diff --git a/server/home/home-alert/src/main/java/io/holoinsight/server/home/alert/model/event/AlertNotifyRecordLatch.java b/server/home/home-alert/src/main/java/io/holoinsight/server/home/alert/model/event/AlertNotifyRecordLatch.java new file mode 100644 index 000000000..6286a41ce --- /dev/null +++ b/server/home/home-alert/src/main/java/io/holoinsight/server/home/alert/model/event/AlertNotifyRecordLatch.java @@ -0,0 +1,39 @@ +/* + * Copyright 2022 Holoinsight Project Authors. Licensed under Apache-2.0. + */ +package io.holoinsight.server.home.alert.model.event; + +import io.holoinsight.server.home.facade.AlertNotifyRecordDTO; +import lombok.Data; +import org.springframework.util.CollectionUtils; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author limengyang + * @date 2023/7/27 15:28 + * @DESCRIPTION + */ +@Data +public class AlertNotifyRecordLatch { + + private List alertNotifyRecordDTOList = new ArrayList<>(); + + public void add(AlertNotifyRecordDTO alertNotifyRecord) { + if (alertNotifyRecord == null) { + return; + } + if (this.alertNotifyRecordDTOList == null) { + this.alertNotifyRecordDTOList = new ArrayList<>(); + } + this.alertNotifyRecordDTOList.add(alertNotifyRecord); + } + + public int size() { + if (!CollectionUtils.isEmpty(alertNotifyRecordDTOList)) { + return alertNotifyRecordDTOList.size(); + } + return 0; + } +} diff --git a/server/home/home-alert/src/main/java/io/holoinsight/server/home/alert/model/event/AlertNotifyRequest.java b/server/home/home-alert/src/main/java/io/holoinsight/server/home/alert/model/event/AlertNotifyRequest.java index 2e24d15fc..a48affb16 100644 --- a/server/home/home-alert/src/main/java/io/holoinsight/server/home/alert/model/event/AlertNotifyRequest.java +++ b/server/home/home-alert/src/main/java/io/holoinsight/server/home/alert/model/event/AlertNotifyRequest.java @@ -4,6 +4,7 @@ package io.holoinsight.server.home.alert.model.event; +import io.holoinsight.server.home.facade.AlertNotifyRecordDTO; import io.holoinsight.server.home.facade.AlertRuleExtra; import io.holoinsight.server.home.facade.InspectConfig; import io.holoinsight.server.home.facade.trigger.Trigger; @@ -69,4 +70,6 @@ public class AlertNotifyRequest { private List logSample; + private AlertNotifyRecordDTO alertNotifyRecord; + } diff --git a/server/home/home-alert/src/main/java/io/holoinsight/server/home/alert/plugin/AlertNotifyHandler.java b/server/home/home-alert/src/main/java/io/holoinsight/server/home/alert/plugin/AlertNotifyHandler.java index dec943b47..dafb5aa2a 100644 --- a/server/home/home-alert/src/main/java/io/holoinsight/server/home/alert/plugin/AlertNotifyHandler.java +++ b/server/home/home-alert/src/main/java/io/holoinsight/server/home/alert/plugin/AlertNotifyHandler.java @@ -5,19 +5,23 @@ package io.holoinsight.server.home.alert.plugin; import io.holoinsight.server.common.J; -import io.holoinsight.server.common.service.FuseProtector; import io.holoinsight.server.home.alert.common.G; import io.holoinsight.server.home.alert.model.event.AlertNotify; +import io.holoinsight.server.home.alert.model.event.AlertNotifyRecordLatch; import io.holoinsight.server.home.alert.model.event.AlertNotifyRequest; import io.holoinsight.server.home.alert.service.event.AlertHandlerExecutor; +import io.holoinsight.server.home.alert.service.event.RecordSucOrFailNotify; +import io.holoinsight.server.home.facade.AlertNotifyRecordDTO; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.util.CollectionUtils; import javax.annotation.Resource; +import java.util.ArrayList; import java.util.List; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; -import static io.holoinsight.server.common.service.FuseProtector.NORMAL_AlertNotifyHandler; /** * @author masaimu @@ -29,12 +33,28 @@ public abstract class AlertNotifyHandler implements AlertHandlerExecutor { @Resource private GatewayService gatewayService; + private static final String NOTIFY_HANDLER = "AlertNotifyHandler"; + @Override public void handle(List alertNotifies) { if (CollectionUtils.isEmpty(alertNotifies)) { LOGGER.info("alertNotifies is empty."); } int count = 0; + int latchSize = 0; + for (AlertNotify alertNotify : alertNotifies) { + if (alertNotify.isAlertRecord()) { + latchSize++; + } + } + AlertNotifyRecordLatch recordLatch = new AlertNotifyRecordLatch(); + List alertNotifyRecordDTOList = new ArrayList<>(); + CountDownLatch latch = null; + if (latchSize > 0) { + latch = new CountDownLatch(latchSize); + } ; + recordLatch.setAlertNotifyRecordDTOList(alertNotifyRecordDTOList); + for (AlertNotify alertNotify : alertNotifies) { try { LOGGER.info("{} alert notify handle begin.", alertNotify.getTraceId()); @@ -43,19 +63,40 @@ public void handle(List alertNotifies) { continue; } count++; - sendPlugin(alertNotify); - FuseProtector.voteComplete(NORMAL_AlertNotifyHandler); + sendPlugin(alertNotify, recordLatch); } catch (Throwable e) { LOGGER.error( "[HoloinsightAlertInternalException][AlertNotifyHandler][1] {} fail to alert_notify_handle for {}", alertNotify.getTraceId(), e.getMessage(), e); - FuseProtector.voteNormalError(NORMAL_AlertNotifyHandler, e.getMessage()); + RecordSucOrFailNotify.alertNotifyProcess( + "fail to alert_notify_handle for " + e.getMessage(), NOTIFY_HANDLER, + "alert notify handle", alertNotify.getAlertNotifyRecord()); + } finally { + if (latch != null && alertNotify.isAlertRecord()) { + latch.countDown(); + } } } + boolean status = true; + try { + if (latch != null) { + status = latch.await(30, TimeUnit.SECONDS); + if (!status) { + throw new RuntimeException("the AlertTaskCompute waiting time elapsed"); + } + } + } catch (Exception e) { + LOGGER.error("[ALERT_CountDownLatch][AlertTaskCompute] error {}", e.getMessage(), e); + } + if (status) { + LOGGER.info("alert notify record data size {} .", recordLatch.size()); + RecordSucOrFailNotify.batchInsert(recordLatch.getAlertNotifyRecordDTOList()); + } + LOGGER.info("alert_notification_notify_step size [{}]", count); } - private void sendPlugin(AlertNotify alertNotify) { + private void sendPlugin(AlertNotify alertNotify, AlertNotifyRecordLatch recordLatch) { AlertNotifyRequest alertNotifyRequest = new AlertNotifyRequest(); alertNotifyRequest.setTraceId(alertNotify.getTraceId()); alertNotifyRequest.setUniqueId(alertNotify.getUniqueId()); @@ -81,12 +122,16 @@ private void sendPlugin(AlertNotify alertNotify) { alertNotifyRequest.setLogAnalysis(alertNotify.getLogAnalysis()); alertNotifyRequest.setLogSample(alertNotify.getLogSample()); + alertNotifyRequest.setAlertNotifyRecord(alertNotify.getAlertNotifyRecord()); + if (!CollectionUtils.isEmpty(alertNotify.getNotifyDataInfos())) { alertNotifyRequest.setNotifyDataInfos(alertNotify.getNotifyDataInfos()); } LOGGER.info("{} begin to send alert notify to gateway for {}", alertNotify.getTraceId(), G.get().toJson(alertNotifyRequest)); - boolean success = this.gatewayService.sendAlertNotifyV3(alertNotifyRequest); + RecordSucOrFailNotify.alertNotifyProcessSuc(NOTIFY_HANDLER, "alert notify handle", + alertNotify.getAlertNotifyRecord()); + boolean success = this.gatewayService.sendAlertNotifyV3(alertNotifyRequest, recordLatch); if (!success) { LOGGER.error("{} AlarmNotifyHandler send notify Exception Request:{}", diff --git a/server/home/home-alert/src/main/java/io/holoinsight/server/home/alert/plugin/AlertSaveHistoryHandler.java b/server/home/home-alert/src/main/java/io/holoinsight/server/home/alert/plugin/AlertSaveHistoryHandler.java index c912e934d..e3dbad4e3 100644 --- a/server/home/home-alert/src/main/java/io/holoinsight/server/home/alert/plugin/AlertSaveHistoryHandler.java +++ b/server/home/home-alert/src/main/java/io/holoinsight/server/home/alert/plugin/AlertSaveHistoryHandler.java @@ -7,7 +7,6 @@ import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import io.holoinsight.server.common.J; -import io.holoinsight.server.common.service.FuseProtector; import io.holoinsight.server.home.alert.common.AlarmContentGenerator; import io.holoinsight.server.home.alert.common.G; import io.holoinsight.server.home.alert.common.TimeRangeUtil; @@ -15,11 +14,13 @@ import io.holoinsight.server.home.alert.model.event.NotifyDataInfo; import io.holoinsight.server.home.alert.service.converter.DoConvert; import io.holoinsight.server.home.alert.service.event.AlertHandlerExecutor; +import io.holoinsight.server.home.alert.service.event.RecordSucOrFailNotify; import io.holoinsight.server.home.common.service.QueryClientService; import io.holoinsight.server.home.dal.mapper.AlarmHistoryDetailMapper; import io.holoinsight.server.home.dal.mapper.AlarmHistoryMapper; import io.holoinsight.server.home.dal.model.AlarmHistory; import io.holoinsight.server.home.dal.model.AlarmHistoryDetail; +import io.holoinsight.server.home.facade.AlertNotifyRecordDTO; import io.holoinsight.server.home.facade.DataResult; import io.holoinsight.server.home.facade.InspectConfig; import io.holoinsight.server.home.facade.trigger.AlertHistoryDetailExtra; @@ -38,13 +39,10 @@ import java.util.Date; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Set; import java.util.stream.Collectors; -import static io.holoinsight.server.common.service.FuseProtector.CRITICAL_AlertSaveHistoryHandler; -import static io.holoinsight.server.common.service.FuseProtector.NORMAL_AlertSaveHistoryDetail; -import static io.holoinsight.server.common.service.FuseProtector.NORMAL_MakeAlertRecover; - /** * @author wangsiyuan * @date 2022/3/28 9:32 下午 @@ -63,6 +61,8 @@ public class AlertSaveHistoryHandler implements AlertHandlerExecutor { @Resource private QueryClientService queryClientService; + private static final String SAVE_HISTORY = "AlertSaveHistoryHandler"; + public void handle(List alertNotifies) { try { // Get alert histories that have not yet been recovered @@ -84,12 +84,32 @@ public void handle(List alertNotifies) { makeAlertHistory(alertHistoryMap, alertNotifyList); makeAlertRecover(alertHistoryMap, alertNotifyRecover); + + // Get alert histories detail to alert notify record + buildAlertNotifyRecord(alertNotifies, alertHistoryMap); LOGGER.info("alert_notification_history_step size [{}]", alertNotifies.size()); } catch (Exception e) { LOGGER.error( "[HoloinsightAlertInternalException][AlertSaveHistoryHandler][{}] fail to alert_history_save for {}", alertNotifies.size(), e.getMessage(), e); - FuseProtector.voteCriticalError(CRITICAL_AlertSaveHistoryHandler, e.getMessage()); + } + } + + private void buildAlertNotifyRecord(List alertNotifies, + Map alertHistoryMap) { + if (CollectionUtils.isEmpty(alertNotifies)) { + return; + } + for (AlertNotify alertNotify : alertNotifies) { + String uniqueId = alertNotify.getUniqueId(); + AlarmHistory alarmHistory = alertHistoryMap.get(uniqueId); + AlertNotifyRecordDTO alertNotifyRecord = alertNotify.getAlertNotifyRecord(); + alertNotifyRecord.setHistoryDetailId(alertNotify.getAlarmHistoryDetailId()); + if (Objects.nonNull(alarmHistory)) { + alertNotifyRecord.setHistoryId(alarmHistory.getId()); + } else { + alertNotifyRecord.setHistoryId(alertNotify.getAlarmHistoryId()); + } } } @@ -331,12 +351,15 @@ private void makeAlertHistory(Map alertHistoryMap, } genAlertHistoryDetail(alertNotify, historyId); } - FuseProtector.voteComplete(NORMAL_AlertSaveHistoryDetail); + RecordSucOrFailNotify.alertNotifyProcessSuc(SAVE_HISTORY, "save history", + alertNotify.getAlertNotifyRecord()); } catch (Exception e) { + RecordSucOrFailNotify.alertNotifyProcess( + alertNotify.getTraceId() + "fail to alert_history_save for" + e.getMessage(), + SAVE_HISTORY, "save history", alertNotify.getAlertNotifyRecord()); LOGGER.error( "[HoloinsightAlertInternalException][AlertSaveHistoryHandler][1] {} fail to alert_history_save for {}", alertNotify.getTraceId(), e.getMessage(), e); - FuseProtector.voteNormalError(NORMAL_AlertSaveHistoryDetail, e.getMessage()); } } } @@ -436,12 +459,15 @@ private void makeAlertRecover(Map alertHistoryDOMap, AlarmHistory alertHistory = alertHistoryDOMap.get(alertNotify.getUniqueId()); alertHistory.setRecoverTime(new Date(alertNotify.getAlarmTime())); alarmHistoryDOMapper.updateById(alertHistory); - FuseProtector.voteComplete(NORMAL_MakeAlertRecover); + RecordSucOrFailNotify.alertNotifyProcessSuc(SAVE_HISTORY, "save history is recover", + alertNotify.getAlertNotifyRecord()); } catch (Exception e) { + RecordSucOrFailNotify.alertNotifyProcess( + alertNotify.getTraceId() + "fail to alert_recover_update for" + e.getMessage(), + SAVE_HISTORY, "save history is recover", alertNotify.getAlertNotifyRecord()); LOGGER.error( "[HoloinsightAlertInternalException][AlertSaveHistoryHandler][1] {} fail to alert_recover_update for {}", alertNotify.getTraceId(), e.getMessage(), e); - FuseProtector.voteNormalError(NORMAL_MakeAlertRecover, e.getMessage()); } }); } diff --git a/server/home/home-alert/src/main/java/io/holoinsight/server/home/alert/plugin/GatewayService.java b/server/home/home-alert/src/main/java/io/holoinsight/server/home/alert/plugin/GatewayService.java index 2fb3f9353..e79c9f142 100644 --- a/server/home/home-alert/src/main/java/io/holoinsight/server/home/alert/plugin/GatewayService.java +++ b/server/home/home-alert/src/main/java/io/holoinsight/server/home/alert/plugin/GatewayService.java @@ -3,10 +3,13 @@ */ package io.holoinsight.server.home.alert.plugin; +import io.holoinsight.server.common.J; import io.holoinsight.server.common.config.EnvironmentProperties; +import io.holoinsight.server.home.alert.model.event.AlertNotifyRecordLatch; import io.holoinsight.server.home.alert.model.event.AlertNotifyRequest; import io.holoinsight.server.home.alert.model.event.NotifyDataInfo; import io.holoinsight.server.home.alert.service.event.AlertNotifyChainBuilder; +import io.holoinsight.server.home.alert.service.event.RecordSucOrFailNotify; import io.holoinsight.server.home.biz.plugin.model.PluginContext; import io.holoinsight.server.home.biz.service.IntegrationPluginService; import io.holoinsight.server.home.dal.converter.AlarmRuleConverter; @@ -14,6 +17,7 @@ import io.holoinsight.server.home.dal.model.AlarmRule; import io.holoinsight.server.home.dal.model.dto.IntegrationPluginDTO; import io.holoinsight.server.home.facade.AlarmRuleDTO; +import io.holoinsight.server.home.facade.AlertNotifyRecordDTO; import io.holoinsight.server.home.facade.AlertRuleExtra; import io.holoinsight.server.home.facade.trigger.Trigger; import org.apache.commons.lang3.StringUtils; @@ -28,6 +32,8 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; +import java.util.concurrent.CountDownLatch; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; @@ -54,7 +60,9 @@ public abstract class GatewayService { @Resource private AlarmRuleConverter alarmRuleConverter; - public boolean sendAlertNotifyV3(AlertNotifyRequest notify) { + private static final String GATEWAY = "GatewayService"; + + public boolean sendAlertNotifyV3(AlertNotifyRequest notify, AlertNotifyRecordLatch recordLatch) { String traceId = notify.getTraceId(); LOGGER.info("{} receive_alarm_notify_request at {}", traceId, this.environmentProperties.getDeploymentSite()); @@ -65,12 +73,16 @@ public boolean sendAlertNotifyV3(AlertNotifyRequest notify) { String type = defaultNotifyChain.name; if (CollectionUtils.isEmpty(notify.getNotifyDataInfos())) { LOGGER.info("{} notify data info is empty.", traceId); + RecordSucOrFailNotify.alertNotifyProcess(traceId + ": notify data info is empty ", GATEWAY, + "check notify data info", notify.getAlertNotifyRecord()); return true; } String ruleId = notify.getRuleId(); if (!StringUtils.isNumeric(ruleId)) { LOGGER.warn("{} invalid rule {}", traceId, ruleId); + RecordSucOrFailNotify.alertNotifyProcess(traceId + ": invalid rule fail; ruleId is " + ruleId, + GATEWAY, "invalid rule", notify.getAlertNotifyRecord()); return true; } @@ -84,8 +96,11 @@ public boolean sendAlertNotifyV3(AlertNotifyRequest notify) { List notifyChainList = this.alertNotifyChainBuilder.buildNotifyChains(traceId, integrationPlugins); + if (CollectionUtils.isEmpty(notifyChainList)) { LOGGER.info("{} {} notifyChainList is empty, skip.", traceId, ruleId); + RecordSucOrFailNotify.alertNotifyProcess(traceId + ": notifyChainList is empty, skip ", + GATEWAY, " get notify chainList", notify.getAlertNotifyRecord()); return true; } @@ -93,18 +108,44 @@ public boolean sendAlertNotifyV3(AlertNotifyRequest notify) { AlarmRuleDTO alertRule = this.alarmRuleConverter.doToDTO(rawRule); if (alertRule == null) { LOGGER.warn("{} can not find alarmRule by {}", traceId, ruleId); + RecordSucOrFailNotify.alertNotifyProcess(traceId + ": can not find alarmRule by " + ruleId, + GATEWAY, "find alarmRule", notify.getAlertNotifyRecord()); return true; } AlertRuleExtra extra = alertRule.getExtra(); notify.setAlertRuleExtra(extra); - PluginContext pluginContext = buildNotifyContext(traceId, notify); + RecordSucOrFailNotify.alertNotifyProcessSuc(GATEWAY, "send alert notify", + notify.getAlertNotifyRecord()); + if (extra.isRecord) { + pluginContext.latch = new CountDownLatch(notifyChainList.size()); + } + for (NotifyChain notifyChain : notifyChainList) { notifyChain.input(inputDatas, pluginContext); this.executorService.execute(notifyChain); } + boolean status = true; + try { + if (pluginContext.latch != null) { + status = pluginContext.latch.await(30, TimeUnit.SECONDS); + if (!status) { + throw new RuntimeException("the GatewayService waiting time elapsed"); + } + } + } catch (Exception e) { + LOGGER.error("[ALERT_CountDownLatch][GatewayService] error {}", e.getMessage(), e); + } + if (status) { + AlertNotifyRecordDTO alertNotifyRecord = pluginContext.getAlertNotifyRecord(); + LOGGER.info("plugin record data {} .", J.toJson(alertNotifyRecord)); + if (Objects.nonNull(recordLatch)) { + recordLatch.add(alertNotifyRecord); + } + } + return true; } diff --git a/server/home/home-alert/src/main/java/io/holoinsight/server/home/alert/plugin/GetSubscriptionHandler.java b/server/home/home-alert/src/main/java/io/holoinsight/server/home/alert/plugin/GetSubscriptionHandler.java index d0376c4a2..944919001 100644 --- a/server/home/home-alert/src/main/java/io/holoinsight/server/home/alert/plugin/GetSubscriptionHandler.java +++ b/server/home/home-alert/src/main/java/io/holoinsight/server/home/alert/plugin/GetSubscriptionHandler.java @@ -5,13 +5,13 @@ package io.holoinsight.server.home.alert.plugin; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import io.holoinsight.server.common.service.FuseProtector; import io.holoinsight.server.home.alert.common.G; import io.holoinsight.server.home.alert.model.event.AlertNotify; import io.holoinsight.server.home.alert.model.event.NotifyDataInfo; import io.holoinsight.server.home.alert.model.event.WebhookInfo; import io.holoinsight.server.home.alert.service.converter.DoConvert; import io.holoinsight.server.home.alert.service.event.AlertHandlerExecutor; +import io.holoinsight.server.home.alert.service.event.RecordSucOrFailNotify; import io.holoinsight.server.home.common.service.RequestContextAdapter; import io.holoinsight.server.home.dal.mapper.AlarmBlockMapper; import io.holoinsight.server.home.dal.mapper.AlarmDingDingRobotMapper; @@ -45,9 +45,6 @@ import java.util.regex.Pattern; import java.util.stream.Collectors; -import static io.holoinsight.server.common.service.FuseProtector.CRITICAL_GetSubscription; -import static io.holoinsight.server.common.service.FuseProtector.NORMAL_GetSubscriptionDetail; - /** * @author masaimu * @version 2023-01-12 20:34:00 @@ -74,6 +71,7 @@ public class GetSubscriptionHandler implements AlertHandlerExecutor { @Autowired private RequestContextAdapter requestContextAdapter; + private static final String GET_SUBSCRIPTION = "GetSubscriptionHandler"; @Override public void handle(List alertNotifies) { @@ -90,6 +88,8 @@ public void handle(List alertNotifies) { AlarmBlock alertBlock = alertBlockMap.get(alertNotify.getUniqueId()); if (alertBlock != null) { if (alertNotify.getIsRecover()) { + RecordSucOrFailNotify.alertNotifyProcess("alertNotify is recover", GET_SUBSCRIPTION, + "remove block subscription", alertNotify.getAlertNotifyRecord()); iterator.remove(); } else { Map tagMap = G.get().fromJson(alertBlock.getTags(), Map.class); @@ -143,6 +143,8 @@ public void handle(List alertNotifies) { } } } + RecordSucOrFailNotify.alertNotifyProcessSuc(GET_SUBSCRIPTION, "remove block subscription", + alertNotify.getAlertNotifyRecord()); } // 查询消息通知订阅关系 @@ -250,12 +252,14 @@ public void handle(List alertNotifies) { alertNotify.setDingdingUrl(dingdingUrls); } } - FuseProtector.voteComplete(NORMAL_GetSubscriptionDetail); + RecordSucOrFailNotify.alertNotifyProcessSuc(GET_SUBSCRIPTION, "query subscription", + alertNotify.getAlertNotifyRecord()); } catch (Throwable e) { LOGGER.error( "[HoloinsightAlertInternalException][GetSubscriptionHandler][1] {} fail to get_subscription for {}", alertNotify.getTraceId(), e.getMessage(), e); - FuseProtector.voteNormalError(NORMAL_GetSubscriptionDetail, e.getMessage()); + RecordSucOrFailNotify.alertNotifyProcess("fail to get_subscription for " + e.getMessage(), + GET_SUBSCRIPTION, "query subscription", alertNotify.getAlertNotifyRecord()); } }); LOGGER.info("[GetSubscriptionHandler][{}] finish to get_subscription.", alertNotifies.size()); @@ -263,7 +267,6 @@ public void handle(List alertNotifies) { LOGGER.error( "[HoloinsightAlertInternalException][GetSubscriptionHandler][{}] fail to get_subscription for {}", alertNotifies.size(), e.getMessage(), e); - FuseProtector.voteCriticalError(CRITICAL_GetSubscription, e.getMessage()); } } diff --git a/server/home/home-alert/src/main/java/io/holoinsight/server/home/alert/plugin/NotifyChain.java b/server/home/home-alert/src/main/java/io/holoinsight/server/home/alert/plugin/NotifyChain.java index 875fb47f5..a6acd0bec 100644 --- a/server/home/home-alert/src/main/java/io/holoinsight/server/home/alert/plugin/NotifyChain.java +++ b/server/home/home-alert/src/main/java/io/holoinsight/server/home/alert/plugin/NotifyChain.java @@ -3,7 +3,6 @@ */ package io.holoinsight.server.home.alert.plugin; -import io.holoinsight.server.common.service.FuseProtector; import io.holoinsight.server.home.biz.plugin.model.ChainPlugin; import io.holoinsight.server.home.biz.plugin.model.PluginContext; import io.holoinsight.server.home.biz.plugin.model.PluginModel; @@ -18,7 +17,6 @@ import java.util.List; -import static io.holoinsight.server.common.service.FuseProtector.NORMAL_NotifyChain; /** * 通知流程 @@ -104,7 +102,6 @@ public void handle() throws Exception { public void run() { try { handle(); - FuseProtector.voteComplete(NORMAL_NotifyChain); } catch (HoloinsightAlertIllegalArgumentException e) { LOGGER.error( "[HoloinsightAlertIllegalArgumentException][1] {} fail to handle notify chain for {}", @@ -112,7 +109,10 @@ public void run() { } catch (Throwable e) { LOGGER.error("[HoloinsightAlertInternalException][1] {} fail to handle notify chain for {}", this.traceId, e.getMessage(), e); - FuseProtector.voteNormalError(NORMAL_NotifyChain, e.getMessage()); + } finally { + if (context != null && context.latch != null) { + context.latch.countDown();; + } } } diff --git a/server/home/home-alert/src/main/java/io/holoinsight/server/home/alert/service/calculate/AbstractUniformInspectRunningRule.java b/server/home/home-alert/src/main/java/io/holoinsight/server/home/alert/service/calculate/AbstractUniformInspectRunningRule.java index 30283cef0..94e44c4e3 100644 --- a/server/home/home-alert/src/main/java/io/holoinsight/server/home/alert/service/calculate/AbstractUniformInspectRunningRule.java +++ b/server/home/home-alert/src/main/java/io/holoinsight/server/home/alert/service/calculate/AbstractUniformInspectRunningRule.java @@ -10,6 +10,8 @@ import io.holoinsight.server.home.alert.model.function.FunctionConfigAIParam; import io.holoinsight.server.home.alert.model.function.FunctionConfigParam; import io.holoinsight.server.home.alert.model.function.FunctionLogic; +import io.holoinsight.server.home.alert.service.event.RecordSucOrFailNotify; +import io.holoinsight.server.home.facade.AlertNotifyRecordDTO; import io.holoinsight.server.home.facade.DataResult; import io.holoinsight.server.home.facade.InspectConfig; import io.holoinsight.server.home.facade.PqlRule; @@ -27,11 +29,11 @@ import org.springframework.util.CollectionUtils; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CountDownLatch; @@ -54,7 +56,10 @@ public class AbstractUniformInspectRunningRule { @Autowired private NullValueTracker nullValueTracker; - public EventInfo eval(ComputeContext context) { + private static String ALERT_TASK_COMPUTE = "AlertTaskCompute"; + + public EventInfo eval(ComputeContext context, + List alertNotifyRecordDTOList) { long period = context.getTimestamp(); InspectConfig inspectConfig = context.getInspectConfig(); String traceId = inspectConfig.getTraceId(); @@ -62,18 +67,21 @@ public EventInfo eval(ComputeContext context) { EventInfo events = null; try { if (inspectConfig.getIsPql()) { - events = runPqlRule(inspectConfig, period); + events = runPqlRule(inspectConfig, period, alertNotifyRecordDTOList); } else { - events = runRule(inspectConfig, period); + events = runRule(inspectConfig, period, alertNotifyRecordDTOList); } } catch (Throwable ex) { + RecordSucOrFailNotify.alertNotifyProcess("AlertTaskCompute Exception: " + ex, + ALERT_TASK_COMPUTE, "alert task compute", inspectConfig.getAlertNotifyRecord()); logger.error("fail to eval inspectConfig {}, traceId: {} ", G.get().toJson(inspectConfig), traceId, ex); } return events; } - public EventInfo runPqlRule(InspectConfig inspectConfig, long period) { + public EventInfo runPqlRule(InspectConfig inspectConfig, long period, + List alertNotifyRecordDTOList) { if (inspectConfig.getIsPql() && !CollectionUtils.isEmpty(inspectConfig.getPqlRule().getDataResult())) { EventInfo eventInfo = new EventInfo(); @@ -88,6 +96,13 @@ public EventInfo runPqlRule(InspectConfig inspectConfig, long period) { eventInfo.setAlarmTriggerResults(triggerMap); return eventInfo; } + // record pql rule alert + AlertNotifyRecordDTO alertNotifyRecordDTO = inspectConfig.getAlertNotifyRecord(); + if (Objects.nonNull(alertNotifyRecordDTO)) { + RecordSucOrFailNotify.alertNotifyNoEventGenerated("pql rule is empty", ALERT_TASK_COMPUTE, + "run pql rule", alertNotifyRecordDTO, null); + alertNotifyRecordDTOList.add(alertNotifyRecordDTO); + } // 恢复时这里返回null return null; } @@ -125,9 +140,11 @@ private Map> convertFromPql(PqlRule pqlRule, long p return map; } - public EventInfo runRule(InspectConfig inspectConfig, long period) throws InterruptedException { + public EventInfo runRule(InspectConfig inspectConfig, long period, + List alertNotifyRecordDTOList) throws InterruptedException { Map> triggerMap = new HashMap<>();// 告警 + List noEventGeneratedList = new ArrayList<>();// 不告警 for (Trigger trigger : inspectConfig.getRule().getTriggers()) { // 后续考虑增加tags比较 List dataResultList = trigger.getDataResult(); @@ -147,6 +164,9 @@ public EventInfo runRule(InspectConfig inspectConfig, long period) throws Interr triggerResults.add(ruleResult); } } + if (!CollectionUtils.isEmpty(ruleResults)) { + noEventGeneratedList.addAll(ruleResults); + } } finally { latch.countDown(); } @@ -170,6 +190,13 @@ public EventInfo runRule(InspectConfig inspectConfig, long period) throws Interr eventInfo.setEnvType(inspectConfig.getEnvType()); return eventInfo; } + // record no alarm event generated data + AlertNotifyRecordDTO alertNotifyRecordDTO = inspectConfig.getAlertNotifyRecord(); + if (Objects.nonNull(alertNotifyRecordDTO)) { + RecordSucOrFailNotify.alertNotifyNoEventGenerated("no alarm event generated", + ALERT_TASK_COMPUTE, "run rule", alertNotifyRecordDTO, noEventGeneratedList); + alertNotifyRecordDTOList.add(alertNotifyRecordDTO); + } return null; } diff --git a/server/home/home-alert/src/main/java/io/holoinsight/server/home/alert/service/calculate/AlertTaskCompute.java b/server/home/home-alert/src/main/java/io/holoinsight/server/home/alert/service/calculate/AlertTaskCompute.java index e75cffec1..0e9379716 100644 --- a/server/home/home-alert/src/main/java/io/holoinsight/server/home/alert/service/calculate/AlertTaskCompute.java +++ b/server/home/home-alert/src/main/java/io/holoinsight/server/home/alert/service/calculate/AlertTaskCompute.java @@ -4,7 +4,6 @@ package io.holoinsight.server.home.alert.service.calculate; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import io.holoinsight.server.common.service.FuseProtector; import io.holoinsight.server.home.alert.common.AlertStat; import io.holoinsight.server.home.alert.common.G; import io.holoinsight.server.home.alert.model.compute.ComputeContext; @@ -14,10 +13,12 @@ import io.holoinsight.server.home.alert.service.data.AlarmDataSet; import io.holoinsight.server.home.alert.service.data.CacheData; import io.holoinsight.server.home.alert.service.event.AlertEventService; +import io.holoinsight.server.home.alert.service.event.RecordSucOrFailNotify; import io.holoinsight.server.home.alert.service.task.AlarmTaskExecutor; import io.holoinsight.server.home.common.exception.HoloinsightAlertIllegalArgumentException; import io.holoinsight.server.home.dal.mapper.AlarmHistoryMapper; import io.holoinsight.server.home.dal.model.AlarmHistory; +import io.holoinsight.server.home.facade.AlertNotifyRecordDTO; import io.holoinsight.server.home.facade.InspectConfig; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; @@ -31,6 +32,7 @@ import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Set; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.CopyOnWriteArrayList; @@ -38,8 +40,6 @@ import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; -import static io.holoinsight.server.common.service.FuseProtector.CRITICAL_AlertTaskCompute; - /** * @author wangsiyuan * @date 2022/2/24 16:29 @@ -67,9 +67,14 @@ public class AlertTaskCompute implements AlarmTaskExecutor { @Resource private CacheData cacheData; + private static final String ALERT_TASK_COMPUTE = "AlertTaskCompute"; + @Override public void process(ComputeTaskPackage computeTaskPackage) { try { + // alert notify record migrate + RecordSucOrFailNotify.alertNotifyMigrate(computeTaskPackage); + // get metric data alarmDataSet.loadData(computeTaskPackage); @@ -89,7 +94,14 @@ public void process(ComputeTaskPackage computeTaskPackage) { if (inspectConfig == null) { continue; } - alarmNotifies.add(AlertNotify.eventInfoConvert(eventInfo, inspectConfig)); + + List alertNotifyRecordDTOS = + getAlertNotifyRecord(computeTaskPackage); + AlertNotify alertNotify = + AlertNotify.eventInfoConvert(eventInfo, inspectConfig, alertNotifyRecordDTOS); + alarmNotifies.add(alertNotify); + RecordSucOrFailNotify.alertNotifyProcessSuc(ALERT_TASK_COMPUTE, + "event convert alert notify", alertNotify.getAlertNotifyRecord()); } alertEventService.handleEvent(alarmNotifies); } @@ -101,9 +113,7 @@ public void process(ComputeTaskPackage computeTaskPackage) { LOGGER.error( "[HoloinsightAlertInternalException][AlertTaskCompute][{}] fail to execute alert task compute for {}", computeTaskPackage.inspectConfigs.size(), e.getMessage(), e); - FuseProtector.voteCriticalError(CRITICAL_AlertTaskCompute, e.getMessage()); } finally { - FuseProtector.voteComplete(CRITICAL_AlertTaskCompute); Map> counterMap = AlertStat.statRuleTypeCount(computeTaskPackage); for (Map.Entry> entry : counterMap .entrySet()) { @@ -115,6 +125,24 @@ public void process(ComputeTaskPackage computeTaskPackage) { } } + private List getAlertNotifyRecord(ComputeTaskPackage computeTaskPackage) { + if (Objects.isNull(computeTaskPackage)) { + return Collections.emptyList(); + } + List inspectConfigs = computeTaskPackage.getInspectConfigs(); + if (CollectionUtils.isEmpty(inspectConfigs)) { + return Collections.emptyList(); + } + List alertNotifyRecordDTOList = new ArrayList<>(); + for (InspectConfig inspectConfig : inspectConfigs) { + if (inspectConfig.getAlertNotifyRecord() == null) { + continue; + } + alertNotifyRecordDTOList.add(inspectConfig.getAlertNotifyRecord()); + } + return alertNotifyRecordDTOList; + } + protected List calculate(ComputeTaskPackage computeTaskPackage) { List eventLists = new CopyOnWriteArrayList<>(); @@ -133,6 +161,7 @@ protected List calculate(ComputeTaskPackage computeTaskPackage) { } int parallelSize = computeTaskPackage.getInspectConfigs().size(); CountDownLatch latch = new CountDownLatch(parallelSize); + List alertNotifyRecordDTOList = new ArrayList<>(); // detection, generate alert event for (InspectConfig inspectConfig : computeTaskPackage.getInspectConfigs()) { calculator.execute(() -> { @@ -140,7 +169,8 @@ protected List calculate(ComputeTaskPackage computeTaskPackage) { ComputeContext context = new ComputeContext(); context.setTimestamp(computeTaskPackage.getTimestamp()); context.setInspectConfig(inspectConfig); - EventInfo eventInfo = abstractUniformInspectRunningRule.eval(context); + EventInfo eventInfo = + abstractUniformInspectRunningRule.eval(context, alertNotifyRecordDTOList); if (eventInfo != null) { eventLists.add(eventInfo); } else if (uniqueIds.contains(inspectConfig.getUniqueId())) { @@ -164,8 +194,13 @@ protected List calculate(ComputeTaskPackage computeTaskPackage) { latch.countDown(); } }); + RecordSucOrFailNotify.alertNotifyProcessSuc(ALERT_TASK_COMPUTE, "alert task compute", + inspectConfig.getAlertNotifyRecord()); } latch.await(); + if (!CollectionUtils.isEmpty(alertNotifyRecordDTOList)) { + RecordSucOrFailNotify.batchInsert(alertNotifyRecordDTOList); + } } catch (Exception e) { LOGGER.error("AlertTaskCompute Exception", e); } diff --git a/server/home/home-alert/src/main/java/io/holoinsight/server/home/alert/service/converter/DoConvert.java b/server/home/home-alert/src/main/java/io/holoinsight/server/home/alert/service/converter/DoConvert.java index 8db7f8197..fd34a5af0 100644 --- a/server/home/home-alert/src/main/java/io/holoinsight/server/home/alert/service/converter/DoConvert.java +++ b/server/home/home-alert/src/main/java/io/holoinsight/server/home/alert/service/converter/DoConvert.java @@ -12,6 +12,7 @@ import io.holoinsight.server.home.dal.model.AlarmRule; import io.holoinsight.server.home.dal.model.AlarmWebhook; import io.holoinsight.server.home.dal.model.AlertmanagerWebhook; +import io.holoinsight.server.home.facade.AlertRuleExtra; import io.holoinsight.server.home.facade.InspectConfig; import io.holoinsight.server.home.facade.PqlRule; import io.holoinsight.server.home.facade.Rule; @@ -61,6 +62,10 @@ public static InspectConfig alarmRuleConverter(AlarmRule alarmRuleDO) { inspectConfig.setIsMerge(alarmRuleDO.getIsMerge() != 0); inspectConfig.setRecover(alarmRuleDO.getRecover() != 0); inspectConfig.setEnvType(alarmRuleDO.getEnvType()); + if (StringUtils.isNotBlank(alarmRuleDO.getExtra())) { + AlertRuleExtra alertRuleExtra = J.fromJson(alarmRuleDO.getExtra(), AlertRuleExtra.class); + inspectConfig.setAlertRecord(alertRuleExtra.isRecord); + } } catch (Exception e) { LOGGER.error("fail to convert alarmRule {}", G.get().toJson(alarmRuleDO), e); } diff --git a/server/home/home-alert/src/main/java/io/holoinsight/server/home/alert/service/data/AlarmDataSet.java b/server/home/home-alert/src/main/java/io/holoinsight/server/home/alert/service/data/AlarmDataSet.java index 2ca50cd58..b476d8971 100644 --- a/server/home/home-alert/src/main/java/io/holoinsight/server/home/alert/service/data/AlarmDataSet.java +++ b/server/home/home-alert/src/main/java/io/holoinsight/server/home/alert/service/data/AlarmDataSet.java @@ -5,6 +5,7 @@ import io.holoinsight.server.home.alert.model.compute.ComputeTaskPackage; import io.holoinsight.server.home.alert.service.data.load.PqlAlarmLoadData; +import io.holoinsight.server.home.alert.service.event.RecordSucOrFailNotify; import io.holoinsight.server.home.facade.DataResult; import io.holoinsight.server.home.facade.PqlRule; import io.holoinsight.server.home.facade.Rule; @@ -35,6 +36,8 @@ public class AlarmDataSet { @Resource private PqlAlarmLoadData pqlAlarmLoadData; + private static final String ALERT_TASK_COMPUTE = "AlertTaskCompute"; + public void loadData(ComputeTaskPackage computeTaskPackage) { if (computeTaskPackage == null @@ -53,7 +56,11 @@ public void loadData(ComputeTaskPackage computeTaskPackage) { pqlRule.setDataResult(result); inspectConfig.setPqlRule(pqlRule); } + RecordSucOrFailNotify.alertNotifyProcessSuc(ALERT_TASK_COMPUTE, "Pql query", + inspectConfig.getAlertNotifyRecord()); } catch (Exception exception) { + RecordSucOrFailNotify.alertNotifyProcess("Pql query Exception: " + exception, + ALERT_TASK_COMPUTE, "Pql query", inspectConfig.getAlertNotifyRecord()); LOGGER.error("Pql query Exception", exception); } } @@ -72,11 +79,16 @@ public void loadData(ComputeTaskPackage computeTaskPackage) { trigger.setDataResult(dataResults); } catch (Exception exception) { LOGGER.error("AlarmLoadData Exception", exception); + RecordSucOrFailNotify.alertNotifyProcess("alarm load data Exception: " + exception, + ALERT_TASK_COMPUTE, "alarm load data", inspectConfig.getAlertNotifyRecord()); } } + RecordSucOrFailNotify.alertNotifyProcessSuc(ALERT_TASK_COMPUTE, "alarm load data", + inspectConfig.getAlertNotifyRecord()); } }); } + } diff --git a/server/home/home-alert/src/main/java/io/holoinsight/server/home/alert/service/event/RecordSucOrFailNotify.java b/server/home/home-alert/src/main/java/io/holoinsight/server/home/alert/service/event/RecordSucOrFailNotify.java new file mode 100644 index 000000000..a0f105d50 --- /dev/null +++ b/server/home/home-alert/src/main/java/io/holoinsight/server/home/alert/service/event/RecordSucOrFailNotify.java @@ -0,0 +1,341 @@ +/* + * Copyright 2022 Holoinsight Project Authors. Licensed under Apache-2.0. + */ +package io.holoinsight.server.home.alert.service.event; + +import io.holoinsight.server.common.AddressUtil; +import io.holoinsight.server.common.J; +import io.holoinsight.server.home.alert.model.compute.ComputeTaskPackage; +import io.holoinsight.server.home.biz.service.AlertNotifyRecordService; +import io.holoinsight.server.home.common.service.SpringContext; +import io.holoinsight.server.home.dal.mapper.AlertNotifyRecordMapper; +import io.holoinsight.server.home.dal.model.AlertNotifyRecord; +import io.holoinsight.server.home.facade.AlertNotifyRecordDTO; +import io.holoinsight.server.home.facade.InspectConfig; +import io.holoinsight.server.home.facade.NotifyErrorMsg; +import io.holoinsight.server.home.facade.NotifyStage; +import io.holoinsight.server.home.facade.NotifyUser; +import io.holoinsight.server.home.facade.Steps; +import io.holoinsight.server.home.facade.trigger.TriggerResult; +import lombok.extern.slf4j.Slf4j; +import org.jetbrains.annotations.NotNull; +import org.springframework.beans.BeanUtils; +import org.springframework.util.CollectionUtils; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +/** + * + * @author limengyang + * @version 2023-07-17 10:27:00 + * @decription Record the whole process of alarm + */ +@Slf4j +public class RecordSucOrFailNotify { + private static AlertNotifyRecordMapper alertNotifyRecordMapper = + SpringContext.getBean(AlertNotifyRecordMapper.class); + + private static AlertNotifyRecordService alertNotifyRecordService = + SpringContext.getBean(AlertNotifyRecordService.class); + + private static String address = AddressUtil.getLocalHostName(); + + private static final String NOTIFY_CHAIN = "NotifyChains"; + + + + public static void alertNotifyChannelFail(String errorNode, String notifyChannel, + AlertNotifyRecordDTO alertNotifyRecord, String notifyUser) { + if (Objects.nonNull(alertNotifyRecord)) { + try { + if (alertNotifyRecord.getIsRecord()) { + List notifyStageList = alertNotifyRecord.getNotifyStage(); + buildNotifyStage(notifyStageList, NOTIFY_CHAIN, notifyChannel, false); + alertNotifyRecord.setNotifyStage(notifyStageList); + + buildChannelAndUser(notifyChannel, alertNotifyRecord, notifyUser); + + List notifyErrorMsgList = + buildErrorMsg(errorNode, notifyChannel, alertNotifyRecord, notifyUser); + + alertNotifyRecord.setNotifyErrorTime(new Date()); + alertNotifyRecord.setIsSuccess((byte) 0); + alertNotifyRecord.setExtra(J.toJson(notifyStageList)); + alertNotifyRecord.setNotifyErrorNode(J.toJson(notifyErrorMsgList)); + alertNotifyRecord.setNotifyChannel(J.toJson(alertNotifyRecord.getNotifyChannelList())); + alertNotifyRecord.setNotifyUser(J.toJson(alertNotifyRecord.getNotifyUserList())); + + AlertNotifyRecord alertNotifyRecord1 = new AlertNotifyRecord(); + BeanUtils.copyProperties(alertNotifyRecord, alertNotifyRecord1); + alertNotifyRecordMapper.insert(alertNotifyRecord1); + } + } catch (Exception e) { + log.error("{} {} {} {} {} record fail. ", alertNotifyRecord.getTraceId(), + alertNotifyRecord.getUniqueId(), NOTIFY_CHAIN, notifyChannel, errorNode, e); + } + } else { + log.warn("{} record fail. alertNotifyRecord is null", errorNode); + } + + } + + @NotNull + private static List buildErrorMsg(String errorNode, String notifyChannel, + AlertNotifyRecordDTO alertNotifyRecord, String notifyUser) { + NotifyErrorMsg notifyErrorMsg = new NotifyErrorMsg(); + notifyErrorMsg.setNotifyType(notifyChannel); + notifyErrorMsg.setErrMsg(errorNode); + notifyErrorMsg.setIsSuccess(false); + notifyErrorMsg.setAddress(address); + notifyErrorMsg.setNotifyUser(notifyUser); + List notifyErrorMsgList = alertNotifyRecord.getNotifyErrorMsgList(); + if (CollectionUtils.isEmpty(notifyErrorMsgList)) { + notifyErrorMsgList = new ArrayList<>(); + } + notifyErrorMsgList.add(notifyErrorMsg); + return notifyErrorMsgList; + } + + public static void alertNotifySuccess(String notifyChannel, + AlertNotifyRecordDTO alertNotifyRecord, String user) { + if (Objects.isNull(alertNotifyRecord)) { + log.warn("{} {} record fail. alertNotifyRecord is null", NOTIFY_CHAIN, notifyChannel); + return; + } + try { + if (alertNotifyRecord.getIsRecord()) { + List notifyStageList = alertNotifyRecord.getNotifyStage(); + buildNotifyStage(notifyStageList, NOTIFY_CHAIN, notifyChannel, true); + alertNotifyRecord.setNotifyStage(notifyStageList); + buildChannelAndUser(notifyChannel, alertNotifyRecord, user); + } + } catch (Exception e) { + log.error("{} {} {} {} record fail. ", alertNotifyRecord.getTraceId(), + alertNotifyRecord.getUniqueId(), NOTIFY_CHAIN, notifyChannel, e); + } + + } + + public static void alertNotifyNoEventGenerated(String errorNode, String stage, String step, + AlertNotifyRecordDTO alertNotifyRecord, List noEventGeneratedList) { + if (Objects.isNull(alertNotifyRecord)) { + log.warn("{} {} record fail. alertNotifyRecord is null", stage, step); + } + try { + if (alertNotifyRecord.getIsRecord()) { + List notifyStageList = alertNotifyRecord.getNotifyStage(); + buildNotifyStage(notifyStageList, stage, step, true); + List notifyErrorMsgList = + buildErrorMsg(errorNode, "", alertNotifyRecord, ""); + alertNotifyRecord.setNotifyStage(notifyStageList); + alertNotifyRecord.setNotifyErrorMsgList(notifyErrorMsgList); + alertNotifyRecord.setIsSuccess((byte) 1); + alertNotifyRecord.setNotifyErrorTime(new Date()); + alertNotifyRecord.setTriggerResult(J.toJson(noEventGeneratedList)); + } + } catch (Exception e) { + log.error("{} {} {} {} record fail. ", alertNotifyRecord.getTraceId(), + alertNotifyRecord.getUniqueId(), stage, step, e); + } + } + + private static void buildChannelAndUser(String notifyChannel, + AlertNotifyRecordDTO alertNotifyRecord, String user) { + List notifyUserList = alertNotifyRecord.getNotifyUserList(); + if (CollectionUtils.isEmpty(notifyUserList)) { + notifyUserList = new ArrayList<>(); + } + NotifyUser notifyUser = new NotifyUser(); + notifyUser.setNotifyChannel(notifyChannel); + notifyUser.setUser(user); + if (!notifyUserList.contains(notifyUser)) { + notifyUserList.add(notifyUser); + alertNotifyRecord.setNotifyUserList(notifyUserList); + } + + List notifyChannelList = alertNotifyRecord.getNotifyChannelList(); + if (CollectionUtils.isEmpty(notifyChannelList)) { + notifyChannelList = new ArrayList<>(); + } + if (!notifyChannelList.contains(notifyChannel)) { + notifyChannelList.add(notifyChannel); + alertNotifyRecord.setNotifyChannelList(notifyChannelList); + } + } + + public static void alertNotifyProcess(String errorNode, String stage, String step, + AlertNotifyRecordDTO alertNotifyRecord) { + if (Objects.isNull(alertNotifyRecord)) { + log.warn("{} {} {} record fail. alertNotifyRecord is null", stage, step, errorNode); + return; + } + try { + if (alertNotifyRecord.getIsRecord()) { + alertNotifyRecord.setNotifyErrorTime(new Date()); + List notifyStageList = alertNotifyRecord.getNotifyStage(); + buildNotifyStage(notifyStageList, stage, step, false); + + NotifyErrorMsg notifyErrorMsg = new NotifyErrorMsg(); + notifyErrorMsg.setNotifyType("default"); + notifyErrorMsg.setErrMsg(errorNode); + notifyErrorMsg.setIsSuccess(false); + notifyErrorMsg.setAddress(address); + List notifyErrorMsgList = new ArrayList<>(); + notifyErrorMsgList.add(notifyErrorMsg); + alertNotifyRecord.setNotifyStage(notifyStageList); + alertNotifyRecord.setExtra(J.toJson(notifyStageList)); + alertNotifyRecord.setNotifyErrorNode(J.toJson(notifyErrorMsgList)); + alertNotifyRecord.setIsSuccess((byte) 0); + AlertNotifyRecord alertNotifyRecord1 = new AlertNotifyRecord(); + BeanUtils.copyProperties(alertNotifyRecord, alertNotifyRecord1); + alertNotifyRecordMapper.insert(alertNotifyRecord1); + } + } catch (Exception e) { + log.error("{} {} {} {} record fail. ", alertNotifyRecord.getTraceId(), + alertNotifyRecord.getUniqueId(), stage, step, e); + } + } + + private static void buildNotifyStage(List notifyStageList, String stage, String step, + boolean isSuccess) { + if (CollectionUtils.isEmpty(notifyStageList)) { + notifyStageList = new ArrayList<>(); + } + List stageList = + notifyStageList.stream().map(NotifyStage::getStage).collect(Collectors.toList()); + if (!CollectionUtils.isEmpty(stageList) && stageList.contains(stage)) { + int i = notifyStageList.size() - 1; + NotifyStage notifyStage = notifyStageList.get(i); + if (Objects.equals(notifyStage.getStage(), stage)) { + notifyStageList.remove(i); + List stepsList = notifyStage.getSteps(); + if (CollectionUtils.isEmpty(stepsList)) { + stepsList = new ArrayList<>(); + } + Steps steps = new Steps(); + steps.setStep(step); + steps.setIsSuccess(isSuccess); + if (!stepsList.contains(steps)) { + stepsList.add(steps); + } + notifyStage.setSteps(stepsList); + notifyStageList.add(notifyStage); + } + } else { + NotifyStage notifyStage = new NotifyStage(); + notifyStage.setStage(stage); + List stepsList = new ArrayList<>(); + Steps steps = new Steps(); + steps.setStep(step); + steps.setIsSuccess(isSuccess); + stepsList.add(steps); + notifyStage.setSteps(stepsList); + notifyStageList.add(notifyStage); + } + } + + public static void alertNotifyProcessSuc(String stage, String step, + AlertNotifyRecordDTO alertNotifyRecord) { + if (Objects.isNull(alertNotifyRecord)) { + log.warn("{} {} record fail. alertNotifyRecord is null", stage, step); + return; + } + try { + if (Objects.isNull(alertNotifyRecord.getIsRecord()) || alertNotifyRecord.getIsRecord()) { + List notifyStageList = alertNotifyRecord.getNotifyStage(); + buildNotifyStage(notifyStageList, stage, step, true); + alertNotifyRecord.setNotifyStage(notifyStageList); + } + } catch (Exception e) { + log.error("{} {} {} {} record fail. ", alertNotifyRecord.getTraceId(), + alertNotifyRecord.getUniqueId(), stage, step, e); + } + } + + + public static void alertNotifyMigrate(ComputeTaskPackage computeTaskPackage) { + if (Objects.isNull(computeTaskPackage) + || Objects.isNull(computeTaskPackage.getAlertNotifyRecord())) { + log.warn("alertNotifyMigrate record fail. computeTaskPackage or alertNotifyRecord is null"); + return; + } + try { + AlertNotifyRecordDTO alertNotifyRecord = computeTaskPackage.getAlertNotifyRecord(); + List inspectConfigs = computeTaskPackage.getInspectConfigs(); + List inspectConfigList = new ArrayList<>(); + for (int i = 0; i < inspectConfigs.size(); i++) { + AlertNotifyRecordDTO alertNotifyRecordDTO = new AlertNotifyRecordDTO(); + BeanUtils.copyProperties(alertNotifyRecord, alertNotifyRecordDTO); + InspectConfig inspectConfig = inspectConfigs.get(i); + BeanUtils.copyProperties(inspectConfig, alertNotifyRecordDTO); + alertNotifyRecordDTO.setIsRecord(inspectConfig.isAlertRecord()); + inspectConfig.setAlertNotifyRecord(alertNotifyRecordDTO); + log.info("alertNotifyRecord switch :{}", alertNotifyRecordDTO.getIsRecord()); + inspectConfigList.add(inspectConfig); + } + computeTaskPackage.setInspectConfigs(inspectConfigList); + } catch (Exception e) { + log.error("{} alertNotifyMigrate record fail.", computeTaskPackage.getTraceId(), e); + } + } + + public static void alertNotifyFailAppendMsg(String errorNode, String notifyChannel, + AlertNotifyRecordDTO alertNotifyRecord, String notifyUser) { + if (Objects.isNull(alertNotifyRecord)) { + log.warn("{} {} {} record fail. alertNotifyRecord is null", NOTIFY_CHAIN, notifyChannel, + errorNode); + return; + } + try { + if (alertNotifyRecord.getIsRecord()) { + List notifyStageList = alertNotifyRecord.getNotifyStage(); + buildNotifyStage(notifyStageList, NOTIFY_CHAIN, notifyChannel, false); + alertNotifyRecord.setNotifyStage(notifyStageList); + + buildChannelAndUser(notifyChannel, alertNotifyRecord, notifyUser); + + List notifyErrorMsgList = + buildErrorMsg(errorNode, notifyChannel, alertNotifyRecord, notifyUser); + alertNotifyRecord.setNotifyErrorNode(J.toJson(notifyErrorMsgList)); + alertNotifyRecord.setIsSuccess((byte) 0); + } + } catch (Exception e) { + log.error("{} {} {} {} {} record fail. ", alertNotifyRecord.getTraceId(), + alertNotifyRecord.getUniqueId(), NOTIFY_CHAIN, notifyChannel, errorNode, e); + } + } + + public static void batchInsert(List alertNotifyRecordDTOList) { + try { + List alertNotifyRecords = new ArrayList<>(); + if (!CollectionUtils.isEmpty(alertNotifyRecordDTOList)) { + alertNotifyRecordDTOList.forEach(alertNotifyRecord -> { + if (Objects.nonNull(alertNotifyRecord) && alertNotifyRecord.getIsRecord()) { + alertNotifyRecord.setExtra(J.toJson(alertNotifyRecord.getNotifyStage())); + alertNotifyRecord.setNotifyUser(J.toJson(alertNotifyRecord.getNotifyUserList())); + alertNotifyRecord + .setNotifyErrorNode(J.toJson(alertNotifyRecord.getNotifyErrorMsgList())); + alertNotifyRecord.setNotifyChannel(J.toJson(alertNotifyRecord.getNotifyChannelList())); + alertNotifyRecord.setNotifyUser(J.toJson(alertNotifyRecord.getNotifyUserList())); + + AlertNotifyRecord alertNotifyRecord1 = new AlertNotifyRecord(); + BeanUtils.copyProperties(alertNotifyRecord, alertNotifyRecord1); + alertNotifyRecords.add(alertNotifyRecord1); + } + }); + } else { + log.warn("batch insert record fail. alertNotifyRecordDTOList is null"); + return; + } + log.info("batch insert data size {}", alertNotifyRecords.size()); + alertNotifyRecordService.saveBatch(alertNotifyRecords); + } catch (Exception e) { + log.error("batch insert record fail. {}", e.getMessage(), e); + } + + } +} diff --git a/server/home/home-alert/src/main/java/io/holoinsight/server/home/alert/service/task/AlertTaskScheduler.java b/server/home/home-alert/src/main/java/io/holoinsight/server/home/alert/service/task/AlertTaskScheduler.java index 74066c988..e8a445aaf 100644 --- a/server/home/home-alert/src/main/java/io/holoinsight/server/home/alert/service/task/AlertTaskScheduler.java +++ b/server/home/home-alert/src/main/java/io/holoinsight/server/home/alert/service/task/AlertTaskScheduler.java @@ -3,10 +3,11 @@ */ package io.holoinsight.server.home.alert.service.task; -import io.holoinsight.server.common.service.FuseProtector; import io.holoinsight.server.home.alert.model.compute.ComputeTaskPackage; import io.holoinsight.server.home.alert.service.calculate.AlertTaskCompute; +import io.holoinsight.server.home.alert.service.event.RecordSucOrFailNotify; import io.holoinsight.server.home.common.exception.HoloinsightAlertInternalException; +import io.holoinsight.server.home.facade.AlertNotifyRecordDTO; import io.holoinsight.server.home.facade.InspectConfig; import io.holoinsight.server.home.facade.emuns.PeriodType; import org.apache.commons.lang3.concurrent.BasicThreadFactory; @@ -22,7 +23,6 @@ import org.quartz.impl.StdSchedulerFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; @@ -34,9 +34,6 @@ import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; -import static io.holoinsight.server.common.service.FuseProtector.CRITICAL_AlertTaskCompute; -import static io.holoinsight.server.common.service.FuseProtector.CRITICAL_AlertTaskScheduler; - /** * @author wangsiyuan * @date 2022/2/28 3:34 下午 @@ -52,6 +49,7 @@ public class AlertTaskScheduler { @Resource private AlertTaskCompute alertTaskCompute; + private static final String ALERT_TASK_SCHEDULE = "AlertTaskScheduler"; public void start() { try { @@ -74,10 +72,7 @@ public void start() { logger.error( "[HoloinsightAlertInternalException][AlertTaskScheduler] fail to schedule alert task for {}", e.getMessage()); - FuseProtector.voteCriticalError(CRITICAL_AlertTaskScheduler, e.getMessage()); throw new HoloinsightAlertInternalException(e); - } finally { - FuseProtector.voteComplete(CRITICAL_AlertTaskScheduler); } } @@ -128,14 +123,21 @@ public void execute(JobExecutionContext context) throws JobExecutionException { AlertTaskCompute alertTaskCompute = (AlertTaskCompute) context.getJobDetail().getJobDataMap().get("alertTaskCompute"); while (true) { + AlertNotifyRecordDTO alertNotifyRecordDTO = new AlertNotifyRecordDTO(); try { final ComputeTaskPackage computeTaskPackage = TaskQueueManager.getInstance().poll(); if (computeTaskPackage != null) { + alertNotifyRecordDTO = computeTaskPackage.getAlertNotifyRecord(); + RecordSucOrFailNotify.alertNotifyProcessSuc(ALERT_TASK_SCHEDULE, "consume compute task", + computeTaskPackage.getAlertNotifyRecord()); graphProcess(computeTaskPackage, alertTaskCompute); } else { break; } } catch (Throwable e) { + RecordSucOrFailNotify.alertNotifyProcess( + "fail to consume compute task for {}" + e.getMessage(), ALERT_TASK_SCHEDULE, + "consume compute task", alertNotifyRecordDTO); logger.error("fail to consume compute task for {}", e.getMessage(), e); } } diff --git a/server/home/home-alert/src/main/java/io/holoinsight/server/home/alert/service/task/CacheAlertTask.java b/server/home/home-alert/src/main/java/io/holoinsight/server/home/alert/service/task/CacheAlertTask.java index 6d5b6ba69..79f26a0c0 100644 --- a/server/home/home-alert/src/main/java/io/holoinsight/server/home/alert/service/task/CacheAlertTask.java +++ b/server/home/home-alert/src/main/java/io/holoinsight/server/home/alert/service/task/CacheAlertTask.java @@ -9,10 +9,13 @@ import io.holoinsight.server.home.alert.model.compute.ComputeTaskPackage; import io.holoinsight.server.home.alert.service.converter.DoConvert; import io.holoinsight.server.home.alert.service.data.CacheData; +import io.holoinsight.server.home.alert.service.event.RecordSucOrFailNotify; import io.holoinsight.server.home.biz.service.CustomPluginService; import io.holoinsight.server.home.dal.mapper.AlarmRuleMapper; import io.holoinsight.server.home.dal.model.AlarmRule; +import io.holoinsight.server.home.facade.AlertNotifyRecordDTO; import io.holoinsight.server.home.facade.InspectConfig; +import io.holoinsight.server.home.facade.NotifyStage; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -23,9 +26,11 @@ import javax.annotation.Resource; import java.util.ArrayList; import java.util.Collections; +import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.UUID; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledThreadPoolExecutor; @@ -63,10 +68,11 @@ public class CacheAlertTask { @Resource private MetricInfoMapper metricInfoMapper; - private Map logPatternCache = new HashMap<>(); private Map logSampleCache = new HashMap<>(); + private static final String ALARM_CONFIG = "CacheAlertTask"; + public void start() { LOGGER.info("[AlarmConfig] start alarm config syn!"); @@ -127,9 +133,12 @@ public ComputeTaskPackage convert(List alarmRules) { List inspectConfigs = new ArrayList<>(); Map> logInspectConfigs = new HashMap<>(); Map uniqueIdMap = new HashMap<>(); + buildAlertNotifyRecord(computeTaskPackage); try { if (!CollectionUtils.isEmpty(alarmRules)) { + RecordSucOrFailNotify.alertNotifyProcessSuc(ALARM_CONFIG, "query alarmRule", + computeTaskPackage.getAlertNotifyRecord()); for (AlarmRule alarmRule : alarmRules) { try { InspectConfig inspectConfig = DoConvert.alarmRuleConverter(alarmRule); @@ -156,12 +165,33 @@ public ComputeTaskPackage convert(List alarmRules) { if (inspectConfigs.size() != 0) { computeTaskPackage.setInspectConfigs(inspectConfigs); } + RecordSucOrFailNotify.alertNotifyProcessSuc(ALARM_CONFIG, "convert alarmRule", + computeTaskPackage.getAlertNotifyRecord()); } catch (Exception e) { + RecordSucOrFailNotify.alertNotifyProcess("fail to convert alarmRule", ALARM_CONFIG, + "convert alarmRule", computeTaskPackage.getAlertNotifyRecord()); LOGGER.error("{} [CRITICAL] fail to convert alarmRules", computeTaskPackage.getTraceId(), e); } return computeTaskPackage; } + private void buildAlertNotifyRecord(ComputeTaskPackage computeTaskPackage) { + if (Objects.nonNull(computeTaskPackage)) { + AlertNotifyRecordDTO alertNotifyRecord = new AlertNotifyRecordDTO(); + alertNotifyRecord.setTraceId(computeTaskPackage.getTraceId()); + alertNotifyRecord.setGmtCreate(new Date()); + alertNotifyRecord.setIsSuccess((byte) 1); + NotifyStage notifyStage = new NotifyStage(); + notifyStage.setStage(ALARM_CONFIG); + List notifyStageList = new ArrayList<>(); + notifyStageList.add(notifyStage); + alertNotifyRecord.setNotifyStage(notifyStageList); + computeTaskPackage.setAlertNotifyRecord(alertNotifyRecord); + LOGGER.info("build alert notify record ,record data is: {}", alertNotifyRecord); + } + + } + private void supplementLogConfig( Map> logInspectConfigs) { if (CollectionUtils.isEmpty(logInspectConfigs)) { diff --git a/server/home/home-alert/src/test/java/io/holoinsight/server/home/alert/service/calculate/AlertTaskComputeTest.java b/server/home/home-alert/src/test/java/io/holoinsight/server/home/alert/service/calculate/AlertTaskComputeTest.java index 4fdbbe9c5..b77a5b652 100644 --- a/server/home/home-alert/src/test/java/io/holoinsight/server/home/alert/service/calculate/AlertTaskComputeTest.java +++ b/server/home/home-alert/src/test/java/io/holoinsight/server/home/alert/service/calculate/AlertTaskComputeTest.java @@ -6,6 +6,7 @@ import io.holoinsight.server.home.alert.model.compute.ComputeTaskPackage; import io.holoinsight.server.home.alert.model.event.EventInfo; import io.holoinsight.server.home.dal.mapper.AlarmHistoryMapper; +import io.holoinsight.server.home.facade.AlertNotifyRecordDTO; import io.holoinsight.server.home.facade.InspectConfig; import org.junit.Before; import org.junit.Test; @@ -29,7 +30,9 @@ public void setUp() throws Exception { AlarmHistoryMapper alertHistoryDOMapper = Mockito.mock(AlarmHistoryMapper.class); AbstractUniformInspectRunningRule abstractUniformInspectRunningRule = Mockito.mock(AbstractUniformInspectRunningRule.class); - Mockito.when(abstractUniformInspectRunningRule.eval(Mockito.any())).thenReturn(new EventInfo()); + List alertNotifyRecordDTOList = new ArrayList<>(); + Mockito.when(abstractUniformInspectRunningRule.eval(Mockito.any(), alertNotifyRecordDTOList)) + .thenReturn(new EventInfo()); alertTaskCompute.abstractUniformInspectRunningRule = abstractUniformInspectRunningRule; alertTaskCompute.alertHistoryDOMapper = alertHistoryDOMapper; } diff --git a/server/home/home-dal/src/main/java/io/holoinsight/server/home/dal/converter/AlertNotifyRecordConverter.java b/server/home/home-dal/src/main/java/io/holoinsight/server/home/dal/converter/AlertNotifyRecordConverter.java new file mode 100644 index 000000000..1dbbf9e7f --- /dev/null +++ b/server/home/home-dal/src/main/java/io/holoinsight/server/home/dal/converter/AlertNotifyRecordConverter.java @@ -0,0 +1,20 @@ +/* + * Copyright 2022 Holoinsight Project Authors. Licensed under Apache-2.0. + */ +package io.holoinsight.server.home.dal.converter; + +import io.holoinsight.server.home.dal.model.AlertNotifyRecord; +import io.holoinsight.server.home.dal.transformer.MapJsonMapper; +import io.holoinsight.server.home.facade.AlertNotifyRecordDTO; +import org.mapstruct.Mapper; + +import java.util.List; + +@Mapper(componentModel = "spring", uses = {MapJsonMapper.class}) +public interface AlertNotifyRecordConverter { + AlertNotifyRecordDTO doToDTO(AlertNotifyRecord alertNotifyRecord); + + AlertNotifyRecord dtoToDO(AlertNotifyRecordDTO target); + + List dosToDTOs(List records); +} diff --git a/server/home/home-dal/src/main/java/io/holoinsight/server/home/dal/mapper/AlertNotifyRecordMapper.java b/server/home/home-dal/src/main/java/io/holoinsight/server/home/dal/mapper/AlertNotifyRecordMapper.java new file mode 100644 index 000000000..4e0ab7c39 --- /dev/null +++ b/server/home/home-dal/src/main/java/io/holoinsight/server/home/dal/mapper/AlertNotifyRecordMapper.java @@ -0,0 +1,10 @@ +/* + * Copyright 2022 Holoinsight Project Authors. Licensed under Apache-2.0. + */ +package io.holoinsight.server.home.dal.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import io.holoinsight.server.home.dal.model.AlertNotifyRecord; + +public interface AlertNotifyRecordMapper extends BaseMapper { +} diff --git a/server/home/home-dal/src/main/java/io/holoinsight/server/home/dal/model/AlertNotifyRecord.java b/server/home/home-dal/src/main/java/io/holoinsight/server/home/dal/model/AlertNotifyRecord.java new file mode 100644 index 000000000..d7fbe2fb0 --- /dev/null +++ b/server/home/home-dal/src/main/java/io/holoinsight/server/home/dal/model/AlertNotifyRecord.java @@ -0,0 +1,118 @@ +/* + * Copyright 2022 Holoinsight Project Authors. Licensed under Apache-2.0. + */ +package io.holoinsight.server.home.dal.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import lombok.Data; + +import javax.persistence.Column; +import javax.persistence.Id; +import javax.persistence.Table; +import java.util.Date; + +/** + * @author limengyang + * @date 2023/7/17 9:52 + */ +@Data +@Table(name = "alert_notify_record") +public class AlertNotifyRecord { + + /** + * id + */ + @Id + @TableId(type = IdType.AUTO) + private Long id; + + /** + * gmtCreate + */ + @Column(name = "gmt_create") + private Date gmtCreate; + + /** + * gmtModified + */ + @Column(name = "gmt_modified") + private Date gmtModified; + + /** + * alert history detail id + */ + @Column(name = "history_detail_id") + private Long historyDetailId; + + /** + * alert history id + */ + @Column(name = "history_id") + private Long historyId; + + /** + * alert exception time + */ + @Column(name = "notify_error_time") + private Date notifyErrorTime; + + /** + * alert success + */ + @Column(name = "is_success") + private Byte isSuccess; + + /** + * notify channel + */ + @Column(name = "notify_channel") + private String notifyChannel; + + /** + * exception node + */ + @Column(name = "notify_error_node") + private String notifyErrorNode; + + /** + * tenant + */ + @Column(name = "tenant") + private String tenant; + + /** + * alert compute detail + */ + @Column(name = "extra") + private String extra; + + /** + * envType + */ + @Column(name = "env_type") + private String envType; + + + @Column(name = "workspace") + private String workspace; + + /** + * alert rule name + */ + @Column(name = "rule_name") + private String ruleName; + + @Column(name = "unique_id") + private String uniqueId; + + /** + * notify target detail + */ + @Column(name = "notify_user") + private String notifyUser; + + @Column(name = "trigger_result") + private String triggerResult; + +} diff --git a/server/home/home-facade/src/main/java/io/holoinsight/server/home/facade/AlertNotifyRecordDTO.java b/server/home/home-facade/src/main/java/io/holoinsight/server/home/facade/AlertNotifyRecordDTO.java new file mode 100644 index 000000000..7b81a69a1 --- /dev/null +++ b/server/home/home-facade/src/main/java/io/holoinsight/server/home/facade/AlertNotifyRecordDTO.java @@ -0,0 +1,101 @@ +/* + * Copyright 2022 Holoinsight Project Authors. Licensed under Apache-2.0. + */ +package io.holoinsight.server.home.facade; + +import lombok.Data; + +import java.util.Date; +import java.util.List; + +/** + * @author limengyang + * @date 2023/7/17 9:32 + */ +@Data +public class AlertNotifyRecordDTO { + /** + * id + */ + private Long id; + + /** + * traceId + */ + private String traceId; + + /** + * gmtCreate + */ + private Date gmtCreate; + + private Date gmtModified; + + /** + * alert history detail id + */ + private Long historyDetailId; + + /** + * alert history id + */ + private Long historyId; + + /** + * alert exception time + */ + private Date notifyErrorTime; + + /** + * alert success + */ + private Byte isSuccess; + + /** + * notify channel + */ + private String notifyChannel; + + /** + * notify target detail + */ + private String notifyUser; + + /** + * exception node + */ + private String notifyErrorNode; + + /** + * tenant + */ + private String tenant; + + /** + * alert compute detail + */ + private String extra; + + /** + * env type + */ + private String envType; + + private String workspace; + + private String uniqueId; + + private String ruleName; + + private String triggerResult; + + private List notifyStage; + + private List notifyChannelList; + + private List notifyErrorMsgList; + + private List notifyUserList; + + private Boolean isRecord; +} diff --git a/server/home/home-facade/src/main/java/io/holoinsight/server/home/facade/AlertRuleExtra.java b/server/home/home-facade/src/main/java/io/holoinsight/server/home/facade/AlertRuleExtra.java index cf21dfdd4..3e956e131 100644 --- a/server/home/home-facade/src/main/java/io/holoinsight/server/home/facade/AlertRuleExtra.java +++ b/server/home/home-facade/src/main/java/io/holoinsight/server/home/facade/AlertRuleExtra.java @@ -17,4 +17,6 @@ public class AlertRuleExtra { public String sourceLink; public List alertTags; public Map tagAlias; + + public boolean isRecord; } diff --git a/server/home/home-facade/src/main/java/io/holoinsight/server/home/facade/InspectConfig.java b/server/home/home-facade/src/main/java/io/holoinsight/server/home/facade/InspectConfig.java index d4af9954b..3aeae1ced 100644 --- a/server/home/home-facade/src/main/java/io/holoinsight/server/home/facade/InspectConfig.java +++ b/server/home/home-facade/src/main/java/io/holoinsight/server/home/facade/InspectConfig.java @@ -62,4 +62,8 @@ public class InspectConfig { private boolean logSampleEnable; private List metrics; + + private AlertNotifyRecordDTO alertNotifyRecord; + + private boolean alertRecord; } diff --git a/server/home/home-facade/src/main/java/io/holoinsight/server/home/facade/NotifyErrorMsg.java b/server/home/home-facade/src/main/java/io/holoinsight/server/home/facade/NotifyErrorMsg.java new file mode 100644 index 000000000..77317213e --- /dev/null +++ b/server/home/home-facade/src/main/java/io/holoinsight/server/home/facade/NotifyErrorMsg.java @@ -0,0 +1,25 @@ +/* + * Copyright 2022 Holoinsight Project Authors. Licensed under Apache-2.0. + */ +package io.holoinsight.server.home.facade; + +import lombok.Data; + +/** + * @author limengyang + * @date 2023/7/19 17:39 + * @DESCRIPTION + */ +@Data +public class NotifyErrorMsg { + + private String notifyType; + + private String errMsg; + + private Boolean isSuccess; + + private String address; + + private String notifyUser; +} diff --git a/server/home/home-facade/src/main/java/io/holoinsight/server/home/facade/NotifyStage.java b/server/home/home-facade/src/main/java/io/holoinsight/server/home/facade/NotifyStage.java new file mode 100644 index 000000000..700d760cf --- /dev/null +++ b/server/home/home-facade/src/main/java/io/holoinsight/server/home/facade/NotifyStage.java @@ -0,0 +1,22 @@ +/* + * Copyright 2022 Holoinsight Project Authors. Licensed under Apache-2.0. + */ +package io.holoinsight.server.home.facade; + +import lombok.Data; + +import java.util.List; + +/** + * @author limengyang + * @date 2023/7/19 17:35 + * @DESCRIPTION + */ +@Data +public class NotifyStage { + + private String stage; + + private List steps; + +} diff --git a/server/home/home-facade/src/main/java/io/holoinsight/server/home/facade/NotifyUser.java b/server/home/home-facade/src/main/java/io/holoinsight/server/home/facade/NotifyUser.java new file mode 100644 index 000000000..fdd8e1a24 --- /dev/null +++ b/server/home/home-facade/src/main/java/io/holoinsight/server/home/facade/NotifyUser.java @@ -0,0 +1,19 @@ +/* + * Copyright 2022 Holoinsight Project Authors. Licensed under Apache-2.0. + */ +package io.holoinsight.server.home.facade; + +import lombok.Data; + +/** + * @author limengyang + * @date 2023/7/20 15:55 + * @DESCRIPTION + */ +@Data +public class NotifyUser { + + private String notifyChannel; + + private String user; +} diff --git a/server/home/home-facade/src/main/java/io/holoinsight/server/home/facade/Steps.java b/server/home/home-facade/src/main/java/io/holoinsight/server/home/facade/Steps.java new file mode 100644 index 000000000..04bf85634 --- /dev/null +++ b/server/home/home-facade/src/main/java/io/holoinsight/server/home/facade/Steps.java @@ -0,0 +1,19 @@ +/* + * Copyright 2022 Holoinsight Project Authors. Licensed under Apache-2.0. + */ +package io.holoinsight.server.home.facade; + +import lombok.Data; + +/** + * @author limengyang + * @date 2023/7/19 18:42 + * @DESCRIPTION + */ +@Data +public class Steps { + + private String step; + + private Boolean isSuccess; +} diff --git a/server/home/home-service/src/main/java/io/holoinsight/server/home/biz/plugin/model/PluginContext.java b/server/home/home-service/src/main/java/io/holoinsight/server/home/biz/plugin/model/PluginContext.java index 0f0fbbe27..7c8ecd45f 100644 --- a/server/home/home-service/src/main/java/io/holoinsight/server/home/biz/plugin/model/PluginContext.java +++ b/server/home/home-service/src/main/java/io/holoinsight/server/home/biz/plugin/model/PluginContext.java @@ -3,14 +3,22 @@ */ package io.holoinsight.server.home.biz.plugin.model; +import io.holoinsight.server.home.facade.AlertNotifyRecordDTO; + import java.util.HashMap; import java.util.Map; +import java.util.concurrent.CountDownLatch; /** * @author masaimu * @version 2022-10-31 17:12:00 */ public class PluginContext { + + private AlertNotifyRecordDTO alertNotifyRecord; + + public CountDownLatch latch; + private Map context = new HashMap<>(); public Object get(String key) { @@ -24,4 +32,12 @@ public Object getOrDefault(String key, Object defaultValue) { public void put(String key, Object value) { this.context.put(key, value); } + + public AlertNotifyRecordDTO getAlertNotifyRecord() { + return alertNotifyRecord; + } + + public void setAlertNotifyRecord(AlertNotifyRecordDTO alertNotifyRecord) { + this.alertNotifyRecord = alertNotifyRecord; + } } diff --git a/server/home/home-service/src/main/java/io/holoinsight/server/home/biz/service/AlertNotifyRecordService.java b/server/home/home-service/src/main/java/io/holoinsight/server/home/biz/service/AlertNotifyRecordService.java new file mode 100644 index 000000000..b3ad96d11 --- /dev/null +++ b/server/home/home-service/src/main/java/io/holoinsight/server/home/biz/service/AlertNotifyRecordService.java @@ -0,0 +1,18 @@ +/* + * Copyright 2022 Holoinsight Project Authors. Licensed under Apache-2.0. + */ +package io.holoinsight.server.home.biz.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import io.holoinsight.server.home.dal.model.AlertNotifyRecord; +import io.holoinsight.server.home.facade.AlertNotifyRecordDTO; +import io.holoinsight.server.home.facade.page.MonitorPageRequest; +import io.holoinsight.server.home.facade.page.MonitorPageResult; + +public interface AlertNotifyRecordService extends IService { + AlertNotifyRecordDTO queryByHistoryDetailId(Long historyDetailId, String tenant, + String workspace); + + MonitorPageResult getListByPage( + MonitorPageRequest pageRequest); +} diff --git a/server/home/home-service/src/main/java/io/holoinsight/server/home/biz/service/impl/AlertNotifyRecordServiceImpl.java b/server/home/home-service/src/main/java/io/holoinsight/server/home/biz/service/impl/AlertNotifyRecordServiceImpl.java new file mode 100644 index 000000000..08ab7cb14 --- /dev/null +++ b/server/home/home-service/src/main/java/io/holoinsight/server/home/biz/service/impl/AlertNotifyRecordServiceImpl.java @@ -0,0 +1,180 @@ +/* + * Copyright 2022 Holoinsight Project Authors. Licensed under Apache-2.0. + */ +package io.holoinsight.server.home.biz.service.impl; + +import com.alibaba.fastjson.JSONArray; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import io.holoinsight.server.home.biz.service.AlertNotifyRecordService; +import io.holoinsight.server.home.common.service.RequestContextAdapter; +import io.holoinsight.server.home.dal.mapper.AlertNotifyRecordMapper; +import io.holoinsight.server.home.dal.converter.AlertNotifyRecordConverter; +import io.holoinsight.server.home.dal.model.AlertNotifyRecord; +import io.holoinsight.server.home.facade.AlertNotifyRecordDTO; +import io.holoinsight.server.home.facade.NotifyErrorMsg; +import io.holoinsight.server.home.facade.NotifyStage; +import io.holoinsight.server.home.facade.NotifyUser; +import io.holoinsight.server.home.facade.page.MonitorPageRequest; +import io.holoinsight.server.home.facade.page.MonitorPageResult; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +@Service +public class AlertNotifyRecordServiceImpl extends + ServiceImpl implements AlertNotifyRecordService { + + @Autowired + private RequestContextAdapter requestContextAdapter; + + @Resource + private AlertNotifyRecordConverter alertNotifyRecordConverter; + + @Override + public AlertNotifyRecordDTO queryByHistoryDetailId(Long historyDetailId, String tenant, + String workspace) { + QueryWrapper wrapper = new QueryWrapper<>(); + this.requestContextAdapter.queryWrapperTenantAdapt(wrapper, tenant, workspace); + + wrapper.eq("history_detail_id", historyDetailId); + wrapper.last("LIMIT 1"); + AlertNotifyRecord alertNotifyRecord = this.getOne(wrapper); + AlertNotifyRecordDTO alertNotifyRecordDTO = + alertNotifyRecordConverter.doToDTO(alertNotifyRecord); + return alertNotifyRecordDTO; + } + + @Override + public MonitorPageResult getListByPage( + MonitorPageRequest pageRequest) { + if (pageRequest.getTarget() == null) { + return null; + } + + QueryWrapper wrapper = new QueryWrapper<>(); + + AlertNotifyRecord alertNotifyRecord = + alertNotifyRecordConverter.dtoToDO(pageRequest.getTarget()); + + if (null != alertNotifyRecord.getId()) { + wrapper.eq("id", alertNotifyRecord.getId()); + } + + this.requestContextAdapter.queryWrapperTenantAdapt(wrapper, alertNotifyRecord.getTenant(), + alertNotifyRecord.getWorkspace()); + + if (null != alertNotifyRecord.getNotifyErrorTime()) { + wrapper.like("notify_error_time", alertNotifyRecord.getNotifyErrorTime()); + } + + if (StringUtils.isNotBlank(alertNotifyRecord.getNotifyChannel())) { + wrapper.eq("notify_channel", alertNotifyRecord.getNotifyChannel().trim()); + } + + if (StringUtils.isNotBlank(alertNotifyRecord.getRuleName())) { + wrapper.like("rule_name", alertNotifyRecord.getRuleName().trim()); + } + + if (StringUtils.isNotBlank(alertNotifyRecord.getNotifyUser())) { + wrapper.likeRight("notify_user", alertNotifyRecord.getNotifyUser().trim()); + } + + if (null != alertNotifyRecord.getHistoryId()) { + wrapper.eq("history_id", alertNotifyRecord.getHistoryId()); + } + + if (StringUtils.isNotBlank(alertNotifyRecord.getUniqueId())) { + wrapper.eq("unique_id", alertNotifyRecord.getUniqueId().trim()); + } + + if (null != alertNotifyRecord.getEnvType()) { + wrapper.eq("env_type", alertNotifyRecord.getEnvType()); + } + + if (Objects.nonNull(alertNotifyRecord.getHistoryDetailId())) { + wrapper.eq("history_detail_id", alertNotifyRecord.getHistoryDetailId()); + } + + if (Objects.nonNull(alertNotifyRecord.getIsSuccess())) { + wrapper.eq("is_success", alertNotifyRecord.getIsSuccess()); + } + + wrapper.orderByDesc("id"); + + if (null != alertNotifyRecord.getGmtCreate()) { + wrapper.ge("gmt_create", alertNotifyRecord.getGmtCreate()); + } + + Page page = new Page<>(pageRequest.getPageNum(), pageRequest.getPageSize()); + + page = page(page, wrapper); + + MonitorPageResult pageResult = new MonitorPageResult<>(); + + List alertNotifyRecordDTOList = recordConverter(page.getRecords()); + + + pageResult.setItems(alertNotifyRecordDTOList); + pageResult.setPageNum(pageRequest.getPageNum()); + pageResult.setPageSize(pageRequest.getPageSize()); + pageResult.setTotalCount(page.getTotal()); + pageResult.setTotalPage(page.getPages()); + + return pageResult; + } + + private List recordConverter(List records) { + if (records == null) { + return null; + } + + List list = new ArrayList(records.size()); + for (AlertNotifyRecord alertNotifyRecord : records) { + list.add(dTOConverter(alertNotifyRecord)); + } + + return list; + } + + private AlertNotifyRecordDTO dTOConverter(AlertNotifyRecord alertNotifyRecord) { + if (alertNotifyRecord == null) { + return null; + } + + AlertNotifyRecordDTO alertNotifyRecordDTO = new AlertNotifyRecordDTO(); + + alertNotifyRecordDTO.setId(alertNotifyRecord.getId()); + alertNotifyRecordDTO.setGmtCreate(alertNotifyRecord.getGmtCreate()); + alertNotifyRecordDTO.setGmtModified(alertNotifyRecord.getGmtModified()); + alertNotifyRecordDTO.setHistoryDetailId(alertNotifyRecord.getHistoryDetailId()); + alertNotifyRecordDTO.setHistoryId(alertNotifyRecord.getHistoryId()); + alertNotifyRecordDTO.setNotifyErrorTime(alertNotifyRecord.getNotifyErrorTime()); + alertNotifyRecordDTO.setIsSuccess(alertNotifyRecord.getIsSuccess()); + alertNotifyRecordDTO.setNotifyChannel(alertNotifyRecord.getNotifyChannel()); + alertNotifyRecordDTO.setNotifyUser(alertNotifyRecord.getNotifyUser()); + alertNotifyRecordDTO.setNotifyErrorNode(alertNotifyRecord.getNotifyErrorNode()); + alertNotifyRecordDTO.setTenant(alertNotifyRecord.getTenant()); + alertNotifyRecordDTO.setExtra(alertNotifyRecord.getExtra()); + alertNotifyRecordDTO.setEnvType(alertNotifyRecord.getEnvType()); + alertNotifyRecordDTO.setWorkspace(alertNotifyRecord.getWorkspace()); + alertNotifyRecordDTO.setUniqueId(alertNotifyRecord.getUniqueId()); + alertNotifyRecordDTO.setRuleName(alertNotifyRecord.getRuleName()); + alertNotifyRecordDTO.setTriggerResult(alertNotifyRecord.getTriggerResult()); + alertNotifyRecordDTO + .setNotifyStage(JSONArray.parseArray(alertNotifyRecord.getExtra(), NotifyStage.class)); + alertNotifyRecordDTO.setNotifyErrorMsgList( + JSONArray.parseArray(alertNotifyRecord.getNotifyErrorNode(), NotifyErrorMsg.class)); + alertNotifyRecordDTO.setNotifyChannelList( + JSONArray.parseArray(alertNotifyRecord.getNotifyChannel(), String.class)); + alertNotifyRecordDTO.setNotifyUserList( + JSONArray.parseArray(alertNotifyRecord.getNotifyUser(), NotifyUser.class)); + return alertNotifyRecordDTO; + } +} diff --git a/server/home/home-web/src/main/java/io/holoinsight/server/home/web/controller/AlertNotifyRecordController.java b/server/home/home-web/src/main/java/io/holoinsight/server/home/web/controller/AlertNotifyRecordController.java new file mode 100644 index 000000000..2b9c701c7 --- /dev/null +++ b/server/home/home-web/src/main/java/io/holoinsight/server/home/web/controller/AlertNotifyRecordController.java @@ -0,0 +1,87 @@ +/* + * Copyright 2022 Holoinsight Project Authors. Licensed under Apache-2.0. + */ +package io.holoinsight.server.home.web.controller; + +import io.holoinsight.server.common.JsonResult; +import io.holoinsight.server.home.biz.service.AlertNotifyRecordService; +import io.holoinsight.server.home.common.util.scope.AuthTargetType; +import io.holoinsight.server.home.common.util.scope.MonitorScope; +import io.holoinsight.server.home.common.util.scope.PowerConstants; +import io.holoinsight.server.home.common.util.scope.RequestContext; +import io.holoinsight.server.home.facade.AlertNotifyRecordDTO; +import io.holoinsight.server.home.facade.page.MonitorPageRequest; +import io.holoinsight.server.home.facade.page.MonitorPageResult; +import io.holoinsight.server.home.web.common.ManageCallback; +import io.holoinsight.server.home.web.common.ParaCheckUtil; +import io.holoinsight.server.home.web.common.TokenUrls; +import io.holoinsight.server.home.web.interceptor.MonitorScopeAuth; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +/** + * @author limengyang + * @date 2023/7/17 17:08 + */ +@Slf4j +@RestController +@RequestMapping("/webapi/alertNotifyRecord") +@TokenUrls("/webapi/alertNotifyRecord") +public class AlertNotifyRecordController extends BaseFacade { + + @Autowired + private AlertNotifyRecordService alertNotifyRecordService; + + @GetMapping("/queryByHistoryDetailId/{historyDetailId}") + @ResponseBody + @MonitorScopeAuth(targetType = AuthTargetType.TENANT, needPower = PowerConstants.EDIT) + public JsonResult queryByHistoryDetailId( + @PathVariable("historyDetailId") Long historyDetailId) { + final JsonResult result = new JsonResult<>(); + facadeTemplate.manage(result, new ManageCallback() { + @Override + public void checkParameter() { + ParaCheckUtil.checkParaNotNull(historyDetailId, "historyDetailId"); + } + + @Override + public void doManage() { + MonitorScope ms = RequestContext.getContext().ms; + AlertNotifyRecordDTO save = alertNotifyRecordService.queryByHistoryDetailId(historyDetailId, + ms.getTenant(), ms.getWorkspace()); + JsonResult.createSuccessResult(result, save); + } + }); + return result; + } + + @PostMapping("/pageQuery") + @ResponseBody + @MonitorScopeAuth(targetType = AuthTargetType.TENANT, needPower = PowerConstants.VIEW) + public JsonResult> pageQuery( + @RequestBody MonitorPageRequest pageRequest) { + final JsonResult> result = new JsonResult<>(); + facadeTemplate.manage(result, new ManageCallback() { + @Override + public void checkParameter() { + ParaCheckUtil.checkParaNotNull(pageRequest.getTarget(), "target"); + } + + @Override + public void doManage() { + MonitorScope ms = RequestContext.getContext().ms; + if (null != ms && !StringUtils.isEmpty(ms.tenant)) { + pageRequest.getTarget().setTenant(ms.tenant); + } + if (null != ms && !StringUtils.isEmpty(ms.workspace)) { + pageRequest.getTarget().setWorkspace(ms.workspace); + } + JsonResult.createSuccessResult(result, alertNotifyRecordService.getListByPage(pageRequest)); + } + }); + + return result; + } +}