From 31cf3e0fcfa17d6a0a0523e6d31e4ae1eab4746e Mon Sep 17 00:00:00 2001 From: pvallet Date: Tue, 22 Dec 2015 16:56:22 +0100 Subject: [PATCH] Filter each interesting alerts matching each subscriptions level instead of sending all alerts to the subscritpion matching the worst case --- .../core/service/schedule/CheckRunner.java | 80 +++++++++++-------- 1 file changed, 47 insertions(+), 33 deletions(-) diff --git a/seyren-core/src/main/java/com/seyren/core/service/schedule/CheckRunner.java b/seyren-core/src/main/java/com/seyren/core/service/schedule/CheckRunner.java index ec4a8ec8..bf6cce37 100644 --- a/seyren-core/src/main/java/com/seyren/core/service/schedule/CheckRunner.java +++ b/seyren-core/src/main/java/com/seyren/core/service/schedule/CheckRunner.java @@ -15,10 +15,14 @@ import java.math.BigDecimal; import java.util.ArrayList; +import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Map.Entry; +import com.google.common.base.Predicate; +import com.google.common.collect.Collections2; +import com.google.common.collect.Lists; import org.joda.time.DateTime; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -35,16 +39,16 @@ import com.seyren.core.store.ChecksStore; public class CheckRunner implements Runnable { - + private static final Logger LOGGER = LoggerFactory.getLogger(CheckRunner.class); - + private final Check check; private final AlertsStore alertsStore; private final ChecksStore checksStore; private final TargetChecker targetChecker; private final ValueChecker valueChecker; private final Iterable notificationServices; - + public CheckRunner(Check check, AlertsStore alertsStore, ChecksStore checksStore, TargetChecker targetChecker, ValueChecker valueChecker, Iterable notificationServices) { this.check = check; @@ -54,73 +58,73 @@ public CheckRunner(Check check, AlertsStore alertsStore, ChecksStore checksStore this.valueChecker = valueChecker; this.notificationServices = notificationServices; } - + @Override public final void run() { if (!check.isEnabled()) { return; } - + try { Map> targetValues = targetChecker.check(check); - + DateTime now = new DateTime(); BigDecimal warn = check.getWarn(); BigDecimal error = check.getError(); - + AlertType worstState; - + if (check.isAllowNoData()) { worstState = AlertType.OK; } else { worstState = AlertType.UNKNOWN; } - + List interestingAlerts = new ArrayList(); - + for (Entry> entry : targetValues.entrySet()) { - + String target = entry.getKey(); Optional value = entry.getValue(); - + if (!value.isPresent()) { LOGGER.warn("No value present for {}", target); continue; } - + BigDecimal currentValue = value.get(); - + Alert lastAlert = alertsStore.getLastAlertForTargetOfCheck(target, check.getId()); - + AlertType lastState; - + if (lastAlert == null) { lastState = AlertType.OK; } else { lastState = lastAlert.getToType(); } - + AlertType currentState = valueChecker.checkValue(currentValue, warn, error); - + if (currentState.isWorseThan(worstState)) { worstState = currentState; } - + if (isStillOk(lastState, currentState)) { continue; } - + Alert alert = createAlert(target, currentValue, warn, error, lastState, currentState, now); - + alertsStore.createAlert(check.getId(), alert); - + // Only notify if the alert has changed state if (stateIsTheSame(lastState, currentState)) { continue; } - + interestingAlerts.add(alert); - + } Check updatedCheck = checksStore.updateStateAndLastCheck(check.getId(), worstState, DateTime.now()); @@ -128,36 +132,38 @@ public final void run() { if (interestingAlerts.isEmpty()) { return; } - + for (Subscription subscription : updatedCheck.getSubscriptions()) { - if (!subscription.shouldNotify(now, worstState)) { + Collection matchingToSubscription = Collections2.filter(interestingAlerts, isMatchingAlertToSubscription(now, subscription)); + + if (matchingToSubscription.isEmpty()) { continue; } - + for (NotificationService notificationService : notificationServices) { if (notificationService.canHandle(subscription.getType())) { try { - notificationService.sendNotification(updatedCheck, subscription, interestingAlerts); + notificationService.sendNotification(updatedCheck, subscription, Lists.newArrayList(matchingToSubscription)); } catch (Exception e) { LOGGER.warn("Notifying {} by {} failed.", subscription.getTarget(), subscription.getType(), e); } } } } - + } catch (Exception e) { LOGGER.warn("{} failed", check.getName(), e); } } - + private boolean isStillOk(AlertType last, AlertType current) { return last == AlertType.OK && current == AlertType.OK; } - + private boolean stateIsTheSame(AlertType last, AlertType current) { return last == current; } - + private Alert createAlert(String target, BigDecimal value, BigDecimal warn, BigDecimal error, AlertType from, AlertType to, DateTime now) { return new Alert() .withTarget(target) @@ -168,5 +174,13 @@ private Alert createAlert(String target, BigDecimal value, BigDecimal warn, BigD .withToType(to) .withTimestamp(now); } - + + private static Predicate isMatchingAlertToSubscription(final DateTime date,final Subscription subscription) { + return new Predicate() { + @Override + public boolean apply(final Alert input) { + return subscription.shouldNotify(date, input.getToType()); + } + }; + } }