AlertService { Result check(Alert alert, LocalDateTime now) { if (ignoredErrors.matches(alert)) return new Result(false, -1); if (criticalErrors.matches(alert)) return new Result(true, -1); String key = alertKey(alert); synchronized (stats) { AlertStat stat = stats.get(key); if (stat == null) { stats.put(key, new AlertStat(now)); return new Result(true, -1); } else if (Duration.between(stat.lastSentDate, now).toMinutes() >= timespanInMinutes) { stats.put(key, new AlertStat(now)); return new Result(true, stat.alertCountSinceLastSent); } else { stat.alertCountSinceLastSent++; return new Result(false, -1); } } } AlertService(AlertConfig config); void process(Alert alert);  }
@Test void check() { assertThat(service.check(alert(Severity.ERROR, "CRITICAL_ERROR", "trace"), LocalDateTime.now()).notify).isTrue(); assertThat(service.check(alert(Severity.WARN, "SLOW_SQL", "trace"), LocalDateTime.now()).notify).isTrue(); Alert alert = alert(Severity.ERROR, "ERROR", "trace"); LocalDateTime date = LocalDateTime.now(); AlertService.Result result = service.check(alert, date); assertThat(result).matches(r -> r.notify && r.alertCountSinceLastSent == -1); result = service.check(alert, date.plusMinutes(30)); assertThat(result).matches(r -> !r.notify); result = service.check(alert, date.plusHours(4)); assertThat(result).matches(r -> r.notify && r.alertCountSinceLastSent == 1); }