diff --git a/alerter/src/main/java/org/dromara/hertzbeat/alert/calculate/CalculateAlarm.java b/alerter/src/main/java/org/dromara/hertzbeat/alert/calculate/CalculateAlarm.java index 135a8b05406..dc611a4be03 100644 --- a/alerter/src/main/java/org/dromara/hertzbeat/alert/calculate/CalculateAlarm.java +++ b/alerter/src/main/java/org/dromara/hertzbeat/alert/calculate/CalculateAlarm.java @@ -23,7 +23,9 @@ import com.googlecode.aviator.exception.ExpressionRuntimeException; import com.googlecode.aviator.exception.ExpressionSyntaxErrorException; import org.dromara.hertzbeat.alert.AlerterWorkerPool; +import org.dromara.hertzbeat.alert.dao.AlertDao; import org.dromara.hertzbeat.alert.reduce.AlarmCommonReduce; +import org.dromara.hertzbeat.alert.service.AlertService; import org.dromara.hertzbeat.common.queue.CommonDataQueue; import org.dromara.hertzbeat.alert.dao.AlertMonitorDao; import org.dromara.hertzbeat.common.entity.alerter.Alert; @@ -37,16 +39,21 @@ import org.dromara.hertzbeat.common.util.ResourceBundleUtil; import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Configuration; +import org.springframework.data.jpa.domain.Specification; +import javax.persistence.criteria.Predicate; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; +import static org.dromara.hertzbeat.common.constants.CommonConstants.ALERT_STATUS_CODE_PENDING; +import static org.dromara.hertzbeat.common.constants.CommonConstants.ALERT_STATUS_CODE_SOLVED; + /** * Calculate alarms based on the alarm definition rules and collected data * 根据告警定义规则和采集数据匹配计算告警 - * @author tom * + * @author tom */ @Configuration @Slf4j @@ -65,14 +72,16 @@ public class CalculateAlarm { private final AlertDefineService alertDefineService; private final AlarmCommonReduce alarmCommonReduce; private final ResourceBundle bundle; + private final AlertService alertService; - public CalculateAlarm (AlerterWorkerPool workerPool, CommonDataQueue dataQueue, - AlertDefineService alertDefineService, AlertMonitorDao monitorDao, - AlarmCommonReduce alarmCommonReduce) { + public CalculateAlarm(AlerterWorkerPool workerPool, CommonDataQueue dataQueue, + AlertDefineService alertDefineService, AlertMonitorDao monitorDao, + AlarmCommonReduce alarmCommonReduce, AlertService alertService) { this.workerPool = workerPool; this.dataQueue = dataQueue; this.alarmCommonReduce = alarmCommonReduce; this.alertDefineService = alertDefineService; + this.alertService = alertService; this.bundle = ResourceBundleUtil.getBundle("alerter"); this.triggeredAlertMap = new ConcurrentHashMap<>(128); this.unAvailableMonitors = Collections.synchronizedSet(new HashSet<>(16)); @@ -154,7 +163,8 @@ private void calculate(CollectRep.MetricsData metricsData) { try { Expression expression = AviatorEvaluator.compile(expr, true); match = (Boolean) expression.execute(fieldValueMap); - } catch (CompileExpressionErrorException | ExpressionSyntaxErrorException compileException) { + } catch (CompileExpressionErrorException | + ExpressionSyntaxErrorException compileException) { log.error("Alert Define Rule: {} Compile Error: {}.", expr, compileException.getMessage()); } catch (ExpressionRuntimeException expressionRuntimeException) { log.error("Alert Define Rule: {} Run Error: {}.", expr, expressionRuntimeException.getMessage()); @@ -188,7 +198,7 @@ private void calculate(CollectRep.MetricsData metricsData) { .tags(tags) .alertDefineId(define.getId()) .priority(define.getPriority()) - .status(CommonConstants.ALERT_STATUS_CODE_PENDING) + .status(ALERT_STATUS_CODE_PENDING) .target(app + "." + metrics + "." + define.getField()) .triggerTimes(1) .firstAlarmTime(currentTimeMilli) @@ -263,6 +273,10 @@ private void handlerAvailableMetrics(long monitorId, String app, String metrics, .triggerTimes(1) .build(); alarmCommonReduce.reduceAndSendAlarm(resumeAlert); + Runnable updateStatusJob = () -> { + updateAvailabilityAlertStatus(monitorId, resumeAlert); + }; + workerPool.executeJob(updateStatusJob); } } } @@ -285,7 +299,7 @@ private void handlerMonitorAvailableAlert(long monitorId, String app, CollectRep Alert.AlertBuilder alertBuilder = Alert.builder() .tags(tags) .priority(CommonConstants.ALERT_PRIORITY_CODE_EMERGENCY) - .status(CommonConstants.ALERT_STATUS_CODE_PENDING) + .status(ALERT_STATUS_CODE_PENDING) .target(CommonConstants.AVAILABILITY) .content(AlertTemplateUtil.render(avaAlertDefine.getTemplate(), valueMap)) .firstAlarmTime(currentTimeMill) @@ -300,7 +314,7 @@ private void handlerMonitorAvailableAlert(long monitorId, String app, CollectRep triggeredAlertMap.put(String.valueOf(monitorId), alertBuilder.build()); } else { int times = preAlert.getTriggerTimes() + 1; - if (preAlert.getStatus() == CommonConstants.ALERT_STATUS_CODE_PENDING) { + if (preAlert.getStatus() == ALERT_STATUS_CODE_PENDING) { times = 1; preAlert.setContent(AlertTemplateUtil.render(avaAlertDefine.getTemplate(), valueMap)); preAlert.setTags(tags); @@ -310,7 +324,7 @@ private void handlerMonitorAvailableAlert(long monitorId, String app, CollectRep preAlert.setLastAlarmTime(currentTimeMill); int defineTimes = avaAlertDefine.getTimes() == null ? 1 : avaAlertDefine.getTimes(); if (times >= defineTimes) { - preAlert.setStatus(CommonConstants.ALERT_STATUS_CODE_PENDING); + preAlert.setStatus(ALERT_STATUS_CODE_PENDING); alarmCommonReduce.reduceAndSendAlarm(preAlert.clone()); unAvailableMonitors.add(monitorId); } else { @@ -318,4 +332,38 @@ private void handlerMonitorAvailableAlert(long monitorId, String app, CollectRep } } } + + + private void updateAvailabilityAlertStatus(long monitorId, Alert restoreAlert) { + List availabilityAlerts = queryAvailabilityAlerts(monitorId, restoreAlert); + availabilityAlerts.stream().parallel().forEach(alert -> { + log.info("updating alert id:{}",alert.getId()); + alertService.editAlertStatus(ALERT_STATUS_CODE_SOLVED, List.of(alert.getId())); + }); + } + + private List queryAvailabilityAlerts(long monitorId, Alert restoreAlert) { + //create query condition + Specification specification = (root, query, criteriaBuilder) -> { + List andList = new ArrayList<>(); + + Predicate predicateTags = criteriaBuilder.like(root.get("tags").as(String.class), "%" + monitorId + "%"); + andList.add(predicateTags); + + Predicate predicatePriority = criteriaBuilder.equal(root.get("priority"), CommonConstants.ALERT_PRIORITY_CODE_EMERGENCY); + andList.add(predicatePriority); + + Predicate predicateStatus = criteriaBuilder.equal(root.get("status"), ALERT_STATUS_CODE_PENDING); + andList.add(predicateStatus); + + Predicate predicateAlertTime = criteriaBuilder.lessThanOrEqualTo(root.get("lastAlarmTime"), restoreAlert.getLastAlarmTime()); + andList.add(predicateAlertTime); + + Predicate[] predicates = new Predicate[andList.size()]; + return criteriaBuilder.and(andList.toArray(predicates)); + }; + + //query results + return alertService.getAlerts(specification); + } } diff --git a/alerter/src/main/java/org/dromara/hertzbeat/alert/service/AlertService.java b/alerter/src/main/java/org/dromara/hertzbeat/alert/service/AlertService.java index 2231acba4d3..ff678d91e41 100644 --- a/alerter/src/main/java/org/dromara/hertzbeat/alert/service/AlertService.java +++ b/alerter/src/main/java/org/dromara/hertzbeat/alert/service/AlertService.java @@ -91,4 +91,14 @@ public interface AlertService { */ void addNewAlertReport(AlertReport alertReport); + /** + * Dynamic conditional query + * 动态条件查询 + * + * @param specification Query conditions 查询条件 + * @return search result 查询结果 + */ + List getAlerts(Specification specification); + + } diff --git a/alerter/src/main/java/org/dromara/hertzbeat/alert/service/impl/AlertServiceImpl.java b/alerter/src/main/java/org/dromara/hertzbeat/alert/service/impl/AlertServiceImpl.java index 189d0672ef6..dde8b982acf 100644 --- a/alerter/src/main/java/org/dromara/hertzbeat/alert/service/impl/AlertServiceImpl.java +++ b/alerter/src/main/java/org/dromara/hertzbeat/alert/service/impl/AlertServiceImpl.java @@ -133,6 +133,12 @@ public void addNewAlertReport(AlertReport alertReport) { alarmCommonReduce.reduceAndSendAlarm(buildAlertData(alertReport)); } + @Override + public List getAlerts(Specification specification) { + + return alertDao.findAll(specification); + } + /** * The external alarm information is converted to Alert 对外告警信息 转换为Alert * @param alertReport 对外告警信息