From d4cd5e0ccc981b7398bee6898c1d37ecc4c3c64e Mon Sep 17 00:00:00 2001 From: jsy Date: Fri, 18 Oct 2024 13:50:11 +0800 Subject: [PATCH] feat: add alarm rrd (#883) --- .../common/dao/entity/AlarmCountable.java | 19 + .../server/common/dao/entity/Folder.java | 4 + .../server/common/dao/entity/FolderPath.java | 36 ++ .../server/common/dao/entity/FolderPaths.java | 22 ++ .../service/AlarmHistoryDetailService.java | 3 + .../common/service/AlarmHistoryService.java | 1 + .../impl/AlarmHistoryDetailServiceImpl.java | 10 + .../service/impl/AlarmHistoryServiceImpl.java | 14 + .../V34__240920_ADD_custom_plugin_COLUMN.sql | 8 + .../V35__240920_ADD_folder_COLUMN.sql | 4 + ...6__241011_ADD_folder_AND_custom_COLUMN.sql | 2 + .../home/alert/model/event/WebhookInfo.java | 5 + .../alert/plugin/GetSubscriptionHandler.java | 31 +- .../server/home/dal/model/CustomPlugin.java | 8 + .../home/dal/model/dto/CustomPluginDTO.java | 8 + .../server/home/task/MonitorAlarmRrdTask.java | 73 ++++ .../home/task/MonitorAlarmRrdTaskJob.java | 357 ++++++++++++++++++ 17 files changed, 601 insertions(+), 4 deletions(-) create mode 100644 server/common/common-dao/src/main/java/io/holoinsight/server/common/dao/entity/AlarmCountable.java create mode 100644 server/common/common-dao/src/main/java/io/holoinsight/server/common/dao/entity/FolderPath.java create mode 100644 server/common/common-dao/src/main/java/io/holoinsight/server/common/dao/entity/FolderPaths.java create mode 100644 server/extension/extension-common-flyway/src/main/resources/db/migration/V34__240920_ADD_custom_plugin_COLUMN.sql create mode 100644 server/extension/extension-common-flyway/src/main/resources/db/migration/V35__240920_ADD_folder_COLUMN.sql create mode 100644 server/extension/extension-common-flyway/src/main/resources/db/migration/V36__241011_ADD_folder_AND_custom_COLUMN.sql create mode 100644 server/home/home-task/src/main/java/io/holoinsight/server/home/task/MonitorAlarmRrdTask.java create mode 100644 server/home/home-task/src/main/java/io/holoinsight/server/home/task/MonitorAlarmRrdTaskJob.java diff --git a/server/common/common-dao/src/main/java/io/holoinsight/server/common/dao/entity/AlarmCountable.java b/server/common/common-dao/src/main/java/io/holoinsight/server/common/dao/entity/AlarmCountable.java new file mode 100644 index 000000000..ccce23b64 --- /dev/null +++ b/server/common/common-dao/src/main/java/io/holoinsight/server/common/dao/entity/AlarmCountable.java @@ -0,0 +1,19 @@ +/* + * Copyright 2022 Holoinsight Project Authors. Licensed under Apache-2.0. + */ +package io.holoinsight.server.common.dao.entity; + +import lombok.Data; + +/** + * 报警计数 + * + * @author limengyang + * @version AlarmCountable.java, v 0.1 2024年09月19日 17:38 limengyang + */ +@Data +public class AlarmCountable { + public Long customPluginId; + public Long parentFolderId; + public Long historyId; +} diff --git a/server/common/common-dao/src/main/java/io/holoinsight/server/common/dao/entity/Folder.java b/server/common/common-dao/src/main/java/io/holoinsight/server/common/dao/entity/Folder.java index 9c4cced99..6ded7ea90 100644 --- a/server/common/common-dao/src/main/java/io/holoinsight/server/common/dao/entity/Folder.java +++ b/server/common/common-dao/src/main/java/io/holoinsight/server/common/dao/entity/Folder.java @@ -22,6 +22,10 @@ public class Folder { public String tenant; public String workspace; public Long parentFolderId; + public Boolean alarmed; + public Integer recentAlarm; + public Long alarmRrdTime; + public String recentAlarmHistoryId; public String creator; public String modifier; diff --git a/server/common/common-dao/src/main/java/io/holoinsight/server/common/dao/entity/FolderPath.java b/server/common/common-dao/src/main/java/io/holoinsight/server/common/dao/entity/FolderPath.java new file mode 100644 index 000000000..bdf27713c --- /dev/null +++ b/server/common/common-dao/src/main/java/io/holoinsight/server/common/dao/entity/FolderPath.java @@ -0,0 +1,36 @@ +/* + * Copyright 2022 Holoinsight Project Authors. Licensed under Apache-2.0. + */ +package io.holoinsight.server.common.dao.entity; + +import lombok.Data; + +import java.io.Serializable; + +/** + * @author limengyang + * @version FolderPath.java, v 0.1 2024年09月20日 11:14 limengyang + */ +@Data +public class FolderPath implements Serializable { + private static final long serialVersionUID = -783815229535552853L; + private Long id; + private String name; + private String type = FOLDER; + + public static final String FILE = "file"; + public static final String FOLDER = "folder"; + + public FolderPath(Long id, String name) { + super(); + this.id = id; + this.name = name; + } + + public FolderPath(Long id, String name, String type) { + super(); + this.id = id; + this.name = name; + this.type = type; + } +} diff --git a/server/common/common-dao/src/main/java/io/holoinsight/server/common/dao/entity/FolderPaths.java b/server/common/common-dao/src/main/java/io/holoinsight/server/common/dao/entity/FolderPaths.java new file mode 100644 index 000000000..e07a88776 --- /dev/null +++ b/server/common/common-dao/src/main/java/io/holoinsight/server/common/dao/entity/FolderPaths.java @@ -0,0 +1,22 @@ +/* + * Copyright 2022 Holoinsight Project Authors. Licensed under Apache-2.0. + */ +package io.holoinsight.server.common.dao.entity; + +import lombok.Data; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +/** + * 文件夹路径 + * + * @author limengyang + * @version FolderPaths.java, v 0.1 2024年09月20日 10:09 limengyang + */ +@Data +public class FolderPaths implements Serializable { + private static final long serialVersionUID = 685496251839004159L; + public List paths = new ArrayList(); +} diff --git a/server/common/common-service/src/main/java/io/holoinsight/server/common/service/AlarmHistoryDetailService.java b/server/common/common-service/src/main/java/io/holoinsight/server/common/service/AlarmHistoryDetailService.java index 75f727758..2f221455f 100644 --- a/server/common/common-service/src/main/java/io/holoinsight/server/common/service/AlarmHistoryDetailService.java +++ b/server/common/common-service/src/main/java/io/holoinsight/server/common/service/AlarmHistoryDetailService.java @@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.extension.service.IService; import io.holoinsight.server.common.MonitorPageRequest; import io.holoinsight.server.common.MonitorPageResult; +import io.holoinsight.server.common.dao.entity.AlarmHistory; import io.holoinsight.server.common.dao.entity.AlarmHistoryDetail; import io.holoinsight.server.common.dao.entity.dto.AlarmHistoryDetailDTO; @@ -24,4 +25,6 @@ MonitorPageResult getListByPage( List> count(MonitorPageRequest pageRequest); + List queryByTime(long from, long to); + } diff --git a/server/common/common-service/src/main/java/io/holoinsight/server/common/service/AlarmHistoryService.java b/server/common/common-service/src/main/java/io/holoinsight/server/common/service/AlarmHistoryService.java index 057daf307..4d4cd6df5 100644 --- a/server/common/common-service/src/main/java/io/holoinsight/server/common/service/AlarmHistoryService.java +++ b/server/common/common-service/src/main/java/io/holoinsight/server/common/service/AlarmHistoryService.java @@ -25,4 +25,5 @@ MonitorPageResult getListByPage(MonitorPageRequest queryByTime(long from, long to); } diff --git a/server/common/common-service/src/main/java/io/holoinsight/server/common/service/impl/AlarmHistoryDetailServiceImpl.java b/server/common/common-service/src/main/java/io/holoinsight/server/common/service/impl/AlarmHistoryDetailServiceImpl.java index 507aa3d89..c9f2cb555 100644 --- a/server/common/common-service/src/main/java/io/holoinsight/server/common/service/impl/AlarmHistoryDetailServiceImpl.java +++ b/server/common/common-service/src/main/java/io/holoinsight/server/common/service/impl/AlarmHistoryDetailServiceImpl.java @@ -6,6 +6,7 @@ import io.holoinsight.server.common.DateUtil; import io.holoinsight.server.common.J; import io.holoinsight.server.common.dao.converter.AlarmHistoryDetailConverter; +import io.holoinsight.server.common.dao.entity.AlarmHistory; import io.holoinsight.server.common.dao.mapper.AlarmHistoryDetailMapper; import io.holoinsight.server.common.dao.entity.AlarmHistoryDetail; import io.holoinsight.server.common.dao.entity.dto.AlarmHistoryDetailDTO; @@ -122,4 +123,13 @@ public List> count(MonitorPageRequest return list; } + + @Override + public List queryByTime(long from, long to) { + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.le("alarm_time", new Date(to)); + wrapper.ge("alarm_time", new Date(from)); + List alarmHistoryDetails = list(wrapper); + return alarmHistoryDetails; + } } diff --git a/server/common/common-service/src/main/java/io/holoinsight/server/common/service/impl/AlarmHistoryServiceImpl.java b/server/common/common-service/src/main/java/io/holoinsight/server/common/service/impl/AlarmHistoryServiceImpl.java index 634f07576..adbd8e747 100644 --- a/server/common/common-service/src/main/java/io/holoinsight/server/common/service/impl/AlarmHistoryServiceImpl.java +++ b/server/common/common-service/src/main/java/io/holoinsight/server/common/service/impl/AlarmHistoryServiceImpl.java @@ -7,6 +7,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import io.holoinsight.server.common.EventBusHolder; +import io.holoinsight.server.common.J; import io.holoinsight.server.common.MonitorPageRequest; import io.holoinsight.server.common.MonitorPageResult; import io.holoinsight.server.common.dao.converter.AlarmHistoryConverter; @@ -22,7 +23,10 @@ import javax.annotation.Resource; import java.util.Date; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.Objects; @Service public class AlarmHistoryServiceImpl extends ServiceImpl @@ -57,6 +61,16 @@ public Boolean deleteById(Long id) { return this.removeById(id); } + @Override + public List queryByTime(long from, long to) { + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.le("alarm_time", to); + wrapper.ge("alarm_time", from); + wrapper.eq("deleted", false); + List alarmHistories = list(wrapper); + return alarmHistories; + } + @Override public MonitorPageResult getListByPage( MonitorPageRequest pageRequest, List uniqueIds) { diff --git a/server/extension/extension-common-flyway/src/main/resources/db/migration/V34__240920_ADD_custom_plugin_COLUMN.sql b/server/extension/extension-common-flyway/src/main/resources/db/migration/V34__240920_ADD_custom_plugin_COLUMN.sql new file mode 100644 index 000000000..2ad5d1e09 --- /dev/null +++ b/server/extension/extension-common-flyway/src/main/resources/db/migration/V34__240920_ADD_custom_plugin_COLUMN.sql @@ -0,0 +1,8 @@ +ALTER TABLE `custom_plugin` + ADD COLUMN `alarmed` TINYINT(4) NULL COMMENT '(归档)是否报警'; +ALTER TABLE `custom_plugin` + ADD COLUMN `recent_alarm_rule_unique_id` varchar(5000) DEFAULT NULL COMMENT '(归档)最近报警unique ID'; +ALTER TABLE `custom_plugin` + ADD COLUMN `recent_alarm` int(11) NULL COMMENT '(归档)最近报警数量'; +ALTER TABLE `custom_plugin` + ADD COLUMN `alarm_rrd_time` bigint(20) NULL COMMENT '归档时间'; \ No newline at end of file diff --git a/server/extension/extension-common-flyway/src/main/resources/db/migration/V35__240920_ADD_folder_COLUMN.sql b/server/extension/extension-common-flyway/src/main/resources/db/migration/V35__240920_ADD_folder_COLUMN.sql new file mode 100644 index 000000000..c0af616ca --- /dev/null +++ b/server/extension/extension-common-flyway/src/main/resources/db/migration/V35__240920_ADD_folder_COLUMN.sql @@ -0,0 +1,4 @@ +ALTER TABLE `folder` ADD COLUMN `alarmed` tinyint(4) DEFAULT NULL COMMENT '(归档)是否报警'; +ALTER TABLE `folder` ADD COLUMN `recent_alarm_rule_unique_id` varchar(5000) DEFAULT NULL COMMENT '(归档)最近报警unique ID'; +ALTER TABLE `folder` ADD COLUMN `recent_alarm` int(11) DEFAULT NULL COMMENT '(归档)最近报警数量'; +ALTER TABLE `folder` ADD COLUMN `alarm_rrd_time` bigint(20) DEFAULT NULL COMMENT '归档时间'; \ No newline at end of file diff --git a/server/extension/extension-common-flyway/src/main/resources/db/migration/V36__241011_ADD_folder_AND_custom_COLUMN.sql b/server/extension/extension-common-flyway/src/main/resources/db/migration/V36__241011_ADD_folder_AND_custom_COLUMN.sql new file mode 100644 index 000000000..e0efeb34f --- /dev/null +++ b/server/extension/extension-common-flyway/src/main/resources/db/migration/V36__241011_ADD_folder_AND_custom_COLUMN.sql @@ -0,0 +1,2 @@ +ALTER TABLE `folder` ADD COLUMN `recent_alarm_history_id` varchar(5000) DEFAULT NULL COMMENT '(归档)最近报警历史ID'; +ALTER TABLE `custom_plugin` ADD COLUMN `recent_alarm_history_id` varchar(5000) DEFAULT NULL COMMENT '(归档)最近报警历史ID'; diff --git a/server/home/home-alert/src/main/java/io/holoinsight/server/home/alert/model/event/WebhookInfo.java b/server/home/home-alert/src/main/java/io/holoinsight/server/home/alert/model/event/WebhookInfo.java index dd299eca0..730e15020 100644 --- a/server/home/home-alert/src/main/java/io/holoinsight/server/home/alert/model/event/WebhookInfo.java +++ b/server/home/home-alert/src/main/java/io/holoinsight/server/home/alert/model/event/WebhookInfo.java @@ -47,6 +47,11 @@ public class WebhookInfo implements Cloneable { */ private String webhookMsg; + /** + * 回调类型 + */ + private Byte type; + public WebhookInfo clone() { try { return (WebhookInfo) super.clone(); 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 4f103fa2e..c0a7f0021 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 @@ -172,10 +172,23 @@ public void handle(List alertNotifies) { break; case "webhook": if (!alertNotify.getIsRecover()) { - AlarmWebhook alertWebhook = - alarmWebhookDOMapper.selectById(alertSubscribe.getGroupId()); - if (alertWebhook != null && alertWebhook.getStatus().equals((byte) 1)) { - webhookInfos.add(DoConvert.alertWebhookDoConverter(alertWebhook)); + List alertWebhookList = + getAllAlertWebHook(alertSubscribe.getTenant()); + List alertWebhookIdList = alertWebhookList.stream() + .map(AlarmWebhook::getId).collect(Collectors.toList()); + if (!alertWebhookIdList.contains(alertSubscribe.getGroupId())) { + AlarmWebhook alertWebhook = + alarmWebhookDOMapper.selectById(alertSubscribe.getGroupId()); + if (alertWebhook != null) { + alertWebhookList.add(alertWebhook); + } + } + if (!CollectionUtils.isEmpty(alertWebhookList)) { + for (AlarmWebhook webhook : alertWebhookList) { + if (webhook != null && webhook.getStatus().equals((byte) 1)) { + webhookInfos.add(DoConvert.alertWebhookDoConverter(webhook)); + } + } } LOGGER.info("{} webhookInfos is {}.", alertNotify.getTraceId(), J.toJson(webhookInfos)); @@ -230,6 +243,16 @@ public void handle(List alertNotifies) { } } + public List getAllAlertWebHook(String tenant) { + QueryWrapper wrapper = new QueryWrapper<>(); + if (StringUtils.isNotBlank(tenant)) { + wrapper.eq("tenant", tenant); + } + wrapper.eq("type", 1); + List alarmWebhookList = alarmWebhookDOMapper.selectList(wrapper); + return alarmWebhookList; + } + private boolean keepSilence(boolean notifyRecover, AlertSilenceConfig alertSilenceConfig, Long alarmTime) { if (notifyRecover) { diff --git a/server/home/home-dal/src/main/java/io/holoinsight/server/home/dal/model/CustomPlugin.java b/server/home/home-dal/src/main/java/io/holoinsight/server/home/dal/model/CustomPlugin.java index ff1e4b299..558e33541 100644 --- a/server/home/home-dal/src/main/java/io/holoinsight/server/home/dal/model/CustomPlugin.java +++ b/server/home/home-dal/src/main/java/io/holoinsight/server/home/dal/model/CustomPlugin.java @@ -30,6 +30,14 @@ public class CustomPlugin { public String sampleLog; + public Boolean alarmed; + + public Integer recentAlarm; + + public Long alarmRrdTime; + + public String recentAlarmHistoryId; + public String creator; public String modifier; diff --git a/server/home/home-dal/src/main/java/io/holoinsight/server/home/dal/model/dto/CustomPluginDTO.java b/server/home/home-dal/src/main/java/io/holoinsight/server/home/dal/model/dto/CustomPluginDTO.java index e0f2b7435..5fb4056a8 100644 --- a/server/home/home-dal/src/main/java/io/holoinsight/server/home/dal/model/dto/CustomPluginDTO.java +++ b/server/home/home-dal/src/main/java/io/holoinsight/server/home/dal/model/dto/CustomPluginDTO.java @@ -40,6 +40,14 @@ public class CustomPluginDTO { public String sampleLog; + public Boolean alarmed; + + public Integer recentAlarm; + + public Long alarmRrdTime; + + public String recentAlarmHistoryId; + public String creator; public String modifier; diff --git a/server/home/home-task/src/main/java/io/holoinsight/server/home/task/MonitorAlarmRrdTask.java b/server/home/home-task/src/main/java/io/holoinsight/server/home/task/MonitorAlarmRrdTask.java new file mode 100644 index 000000000..293bfac1c --- /dev/null +++ b/server/home/home-task/src/main/java/io/holoinsight/server/home/task/MonitorAlarmRrdTask.java @@ -0,0 +1,73 @@ +/* + * Copyright 2022 Holoinsight Project Authors. Licensed under Apache-2.0. + */ +package io.holoinsight.server.home.task; + +import io.holoinsight.server.common.model.CLUSTER_ROLE_CONST; +import io.holoinsight.server.common.service.AlarmHistoryDetailService; +import io.holoinsight.server.common.service.AlarmMetricService; +import io.holoinsight.server.common.service.FolderService; +import io.holoinsight.server.common.service.MetricInfoService; +import io.holoinsight.server.home.biz.service.CustomPluginService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author limengyang + * @version MonitorAlarmRrdTask.java, v 0.1 2024年09月19日 15:41 limengyang + */ +@Service +@TaskHandler(code = "MONITOR_ALARM_RRD") +public class MonitorAlarmRrdTask extends AbstractMonitorTask { + + public final static String TASK_ID = "MONITOR_ALARM_RRD"; + + public final static Long PERIOD = 5 * MINUTE; + + @Autowired + private AlarmHistoryDetailService alarmHistoryDetailService; + + @Autowired + private CustomPluginService customPluginService; + + @Autowired + private FolderService folderService; + + @Autowired + private MetricInfoService metricInfoService; + + @Autowired + private AlarmMetricService alarmMetricService; + + + public MonitorAlarmRrdTask() { + super(1, 10, "MONITOR_ALARM_RRD"); + } + + @Override + public long getTaskPeriod() { + return PERIOD; + } + + @Override + public boolean needRun() { + return true; + } + + @Override + public List buildJobs(long period) { + List jobs = new ArrayList<>(); + jobs.add(new MonitorAlarmRrdTaskJob(period, alarmHistoryDetailService, customPluginService, + metricInfoService, alarmMetricService, folderService)); + return jobs; + } + + public String getRole() { + // 代表执行本任务的具体Role + return CLUSTER_ROLE_CONST.META; + } + +} diff --git a/server/home/home-task/src/main/java/io/holoinsight/server/home/task/MonitorAlarmRrdTaskJob.java b/server/home/home-task/src/main/java/io/holoinsight/server/home/task/MonitorAlarmRrdTaskJob.java new file mode 100644 index 000000000..560b49903 --- /dev/null +++ b/server/home/home-task/src/main/java/io/holoinsight/server/home/task/MonitorAlarmRrdTaskJob.java @@ -0,0 +1,357 @@ +/* + * Copyright 2022 Holoinsight Project Authors. Licensed under Apache-2.0. + */ +package io.holoinsight.server.home.task; + +import io.holoinsight.server.common.J; +import io.holoinsight.server.common.MD5Hash; +import io.holoinsight.server.common.cache.local.CommonLocalCache; +import io.holoinsight.server.common.dao.entity.AlarmCountable; +import io.holoinsight.server.common.dao.entity.AlarmHistoryDetail; +import io.holoinsight.server.common.dao.entity.AlarmMetric; +import io.holoinsight.server.common.dao.entity.Folder; +import io.holoinsight.server.common.dao.entity.FolderPath; +import io.holoinsight.server.common.dao.entity.FolderPaths; +import io.holoinsight.server.common.dao.entity.dto.MetricInfoDTO; +import io.holoinsight.server.common.service.AlarmHistoryDetailService; +import io.holoinsight.server.common.service.AlarmMetricService; +import io.holoinsight.server.common.service.FolderService; +import io.holoinsight.server.common.service.MetricInfoService; +import io.holoinsight.server.home.biz.service.CustomPluginService; +import io.holoinsight.server.home.dal.model.CustomPlugin; +import io.holoinsight.server.home.dal.model.dto.CustomPluginDTO; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.TimeUnit; + +/** + * @author limengyang + * @version MonitorAlarmRrdTaskJob.java, v 0.1 2024年09月19日 15:33 limengyang + */ +@Slf4j +public class MonitorAlarmRrdTaskJob extends MonitorTaskJob { + + + private static Long MINUTE = 6000l; + + private static final List LOG_METRIC_Type = + Arrays.asList("logsample", "logdefault", "logspm", "logpattern"); + + private static String ALARM_RRD_TASK_GET_CUSTOM_PLUGIN = "ALARM_RRD_TASK_GET_CUSTOM_PLUGIN"; + + private long period; + + private AlarmHistoryDetailService alarmHistoryDetailService; + + private CustomPluginService customPluginService; + + private FolderService folderService; + + private MetricInfoService metricInfoService; + + private AlarmMetricService alarmMetricService; + + + public MonitorAlarmRrdTaskJob(long period, AlarmHistoryDetailService alarmHistoryDetailService, + CustomPluginService customPluginService, MetricInfoService metricInfoService, + AlarmMetricService alarmMetricService, FolderService folderService) { + super(); + this.period = period; + this.alarmHistoryDetailService = alarmHistoryDetailService; + this.customPluginService = customPluginService; + this.metricInfoService = metricInfoService; + this.alarmMetricService = alarmMetricService; + this.folderService = folderService; + } + + @Override + public boolean run() throws Throwable { + // 获取最近5分钟所有的报警记录列表 + List ahs = alarmHistoryDetailService + .queryByTime(period - MINUTE - MonitorAlarmRrdTask.PERIOD, period - MINUTE); + List acs = new ArrayList<>(); + Set customPluginIds = fillCustomPluginId(ahs, acs); + if (customPluginIds == null || customPluginIds.size() == 0) { + return true; // 没有效报警 + } + Map customPlugins = buildCustomPluginMap(customPluginIds); + Set folderIds = fillParentFolderId(acs, customPlugins); + + Map folderPathMap = buildFolderMap(folderIds); + + // 产品的父文件夹+父文件夹所在的整个文件路径,做聚合 + Map resultFolder = getAllClearFolders(folderPathMap.values()); + Map resultCustomPlugin = getClearCustomPlugins(customPlugins.keySet()); + + for (AlarmCountable ac : acs) { + // 处理一个报警, 先给产品自己弄上 + CustomPlugin cp = resultCustomPlugin.get(ac.customPluginId); + if (cp == null) { + continue; + } + setAlarmForCustomPlugin(cp, ac.historyId, period); + if (ac.parentFolderId == null) { + continue; + } + // 给产品向上的父文件搞上 + FolderPaths fps = folderPathMap.get(ac.parentFolderId); + // to fix npe + if (fps != null) { + for (FolderPath fp : fps.paths) { + Folder folder = resultFolder.get(fp.getId()); + if (folder == null) { + break; + } + setAlarmForFolder(folder, ac.historyId, period); + } + } + } + // 都搞完了,更新入库 + updateRrdData(resultFolder.values(), resultCustomPlugin.values()); + return true; + } + + @Override + public String id() { + return MonitorAlarmRrdTask.TASK_ID; // 就一个job + } + + private void updateRrdData(Collection folders, Collection cps) { + for (CustomPlugin cp : cps) { + try { + customPluginService.updateById(cp); + } catch (Exception e) { + log.error("update customplugin alarm rrd failed for " + J.toJson(cp), e); + } + } + for (Folder f : folders) { + try { + folderService.updateById(f); + } catch (Exception e) { + log.error("update folder alarm rrd failed for " + J.toJson(f), e); + } + } + } + + private void setAlarmForFolder(Folder f, Long historyId, long period) { + // 报警标记 + f.setAlarmed(true); + // 报警数量 + Integer recent = f.getRecentAlarm(); + if (recent == null) { + recent = 1; + f.setRecentAlarm(recent); + } else { + f.setRecentAlarm(recent + 1); + } + // 设置归档时间 + f.setAlarmRrdTime(period); + + if (recent != null && recent < 150) { + String alarmHistoryIdStr = f.getRecentAlarmHistoryId(); + if (StringUtils.isBlank(alarmHistoryIdStr)) { + // 防止默认的null字符串 + alarmHistoryIdStr = String.valueOf(historyId); + } else { + alarmHistoryIdStr += "," + historyId; + } + f.setRecentAlarmHistoryId(alarmHistoryIdStr); + } + } + + private void setAlarmForCustomPlugin(CustomPlugin cp, Long historyId, long period) { + // 报警标记 + cp.setAlarmed(true); + // 报警数量 + Integer recent = cp.getRecentAlarm(); + if (recent == null) { + recent = 1; + cp.setRecentAlarm(recent); + } else { + cp.setRecentAlarm(recent + 1); + } + // 设置归档时间 + cp.setAlarmRrdTime(period); + // 报警历史 + if (recent != null && recent < 150) { + String alarmHistoryIdStr = cp.getRecentAlarmHistoryId(); + if (StringUtils.isBlank(alarmHistoryIdStr)) { + // 防止默认的null字符串 + alarmHistoryIdStr = String.valueOf(historyId); + } else { + alarmHistoryIdStr += "," + historyId; + } + cp.setRecentAlarmHistoryId(alarmHistoryIdStr); + } + } + + private Map getClearCustomPlugins(Collection customPlugins) { + Map ret = new HashMap<>(); + for (Long cpId : customPlugins) { + CustomPlugin cp = new CustomPlugin(); + cp.setId(cpId); + ret.put(cpId, cp); + } + return ret; + } + + // 包括产品的父目录以及它上面的所有父亲 + private Map getAllClearFolders(Collection fps) { + Map relatedFolderMap = new HashMap<>(); + for (FolderPaths fp : fps) { + List ps = fp.paths; + for (FolderPath p : ps) { + // 直接put,如果是同一个文件夹也无所谓 + Folder folder = new Folder(); + folder.setId(p.getId()); + relatedFolderMap.put(p.getId(), folder); + } + } + return relatedFolderMap; + } + + private Map buildFolderMap(Set folders) { + Map ret = new HashMap<>(); + for (Folder folder : folders) { + try { + if (folder.id == -1) { + // 非法的直接过 + continue; + } + folder = folderService.queryById(folder.id, folder.tenant, folder.workspace); + if (folder == null) { + // 不存在了,直接过 + continue; + } + FolderPath filePath = new FolderPath(folder.getId(), folder.getName(), FolderPath.FOLDER); + Long pfId = folder.getParentFolderId(); + // 从pfId 开始,往上一个个挨着撸,直到到达根目录 + FolderPaths fps = getAbsPath(pfId); + fps.paths.add(0, filePath); + ret.put(folder.id, fps); + } catch (Exception e) { + log.error("get folder abs path error, " + folder.id, e); + } + } + return ret; + } + + public FolderPaths getAbsPath(Long pfId) throws Exception { + FolderPaths fps = new FolderPaths(); + return gogo(pfId, fps); + } + + + private FolderPaths gogo(Long pfId, FolderPaths fps) throws Exception { + if (pfId == -1L) { + // 在根目录下, 到达递归终止条件 + return fps; + } + Folder f = folderService.getById(pfId); + if (f == null) { + throw new Exception("invalid folder id:" + pfId); + } + fps.paths.add(new FolderPath(f.getId(), f.getName())); + return gogo(f.getParentFolderId(), fps); + } + + + private Set fillParentFolderId(List acs, + Map customPlugins) { + Set folders = new HashSet<>(); + for (AlarmCountable ac : acs) { + Folder folder = new Folder(); + Long customPluginId = ac.getCustomPluginId(); + CustomPluginDTO cp = customPlugins.get(customPluginId); + if (cp == null) { + continue; + } + Long pfId = cp.getParentFolderId(); + if (pfId == null) { + continue; + } + folder.id = pfId; + folder.tenant = cp.tenant; + folder.workspace = cp.workspace; + folders.add(folder); + // folderIds.add(pfId); + ac.setParentFolderId(pfId); + } + return folders; + } + + private Map buildCustomPluginMap(Set customPluginIds) { + Map ret = new HashMap<>(); + List ids = new ArrayList<>(); + customPluginIds.forEach(id -> ids.add(id.toString())); + List cps = customPluginService.findByIds(ids); + for (CustomPluginDTO cp : cps) { + ret.put(cp.getId(), cp); + } + return ret; + } + + private Set fillCustomPluginId(List ahs, List acs) { + Set customPluginIds = new HashSet<>(); + + for (AlarmHistoryDetail ah : ahs) { + if (StringUtils.isEmpty(ah.getUniqueId())) { + continue; + } + String cacheKey = ALARM_RRD_TASK_GET_CUSTOM_PLUGIN + "@" + MD5Hash.getMD5(ah.getUniqueId()); + Object o = CommonLocalCache.get(cacheKey); + List customPluginIdList = new ArrayList<>(); + if (null != o) { + customPluginIdList = (List) o; + log.info("used cacheKey: " + cacheKey + "value: " + customPluginIdList); + customPluginIds = new HashSet<>(customPluginIdList); + } else { + Long ruleId = null; + if (ah.getUniqueId().contains("rule_")) { + ruleId = Long.valueOf(ah.getUniqueId().replace("rule_", "")); + } else if (ah.getUniqueId().contains("ai_")) { + ruleId = Long.valueOf(ah.getUniqueId().replace("ai_", "")); + } + if (null == ruleId) { + continue; + } + List metrics = + alarmMetricService.queryByRuleId(ruleId, ah.getTenant(), ah.getWorkspace()); + log.info("metrics size: " + metrics.size()); + for (AlarmMetric alarmMetric : metrics) { + MetricInfoDTO metricInfoDTO = metricInfoService.queryByMetric(alarmMetric.getTenant(), + alarmMetric.getWorkspace(), alarmMetric.getMetricTable()); + if (null == metricInfoDTO || StringUtils.isBlank(metricInfoDTO.getRef()) + || !LOG_METRIC_Type.contains(metricInfoDTO.getMetricType()) + || !metricInfoDTO.getRef().matches("-?\\d+")) { + continue; + } + log.info("metricInfoDTO getRef: " + metricInfoDTO.getRef()); + Long customPluginId = Long.valueOf(metricInfoDTO.getRef()); + customPluginIds.add(customPluginId); + customPluginIdList.add(customPluginId); + CommonLocalCache.put(cacheKey, customPluginIdList, 1, TimeUnit.HOURS); + } + } + customPluginIdList.forEach(customPluginId -> { + AlarmCountable ac = new AlarmCountable(); + ac.customPluginId = customPluginId; + ac.historyId = ah.getHistoryId(); + acs.add(ac); + }); + } + return customPluginIds; + } + + + +}