private void checkTTL(final NodeHealthStat nodeHealthStat) { if (debug) logger.debug("HealthService::checkTTL() {}", nodeHealthStat.getName()); if (!nodeHealthStat.isOk()) { return; } if (nodeHealthStat.isForever()) { return; } final long duration = super.time - nodeHealthStat.getLastCheckIn(); /* If the duration is greater than the ttl interval, then mark it as failed. */ if (duration > nodeHealthStat.getTtlInMS()) { logger.error("HealthService::checkTTL() {} FAILED TTL check, duration {}", nodeHealthStat.getName(), duration); nodeHealthStat.setReason(HealthFailReason.FAILED_TTL); nodeHealthStat.setStatus(HealthStatus.FAIL); onFail.ifPresent(checkIn -> checkIn.accept(BeanUtils.copy(nodeHealthStat))); } }
@Override public List<String> findAllNodesWithStatus(final HealthStatus queryStatus) { final List<String> names = new ArrayList<>(); serviceHealthStatMap.values() .stream() .filter(serviceHealthStat -> serviceHealthStat.getStatus() == queryStatus) .forEach(serviceHealthStat -> names.add(serviceHealthStat.getName())); return names; }
/** * Register method to register services / internal nodes. * * @param name name */ @Override public void registerNoTtl(final String name) { logger.info("HealthService::register() {} ", name); final NodeHealthStat nodeHealthStat = new NodeHealthStat(name); nodeHealthStat.setStatus(HealthStatus.PASS); serviceHealthStatMap.put(name, nodeHealthStat); super.incrementCount("nodes"); super.recordLevel("nodes", serviceHealthStatMap.size()); }
@Override public void warnWithError(final String name, final Throwable error) { logger.warn("HealthService::warn() {}", name); super.incrementCount("warn"); final NodeHealthStat nodeHealthStat = getServiceHealthStat(name); nodeHealthStat.setStatus(HealthStatus.WARN); nodeHealthStat.setReason(HealthFailReason.ERROR); nodeHealthStat.setLastCheckIn(super.time); nodeHealthStat.setError(error); onWarn.ifPresent(checkIn -> checkIn.accept(BeanUtils.copy(nodeHealthStat))); }
@Override public void warnWithReason(final String name, final HealthFailReason reason) { logger.warn("HealthService::warn() {}", name); super.incrementCount("warn"); final NodeHealthStat nodeHealthStat = getServiceHealthStat(name); nodeHealthStat.setStatus(HealthStatus.WARN); nodeHealthStat.setReason(reason); nodeHealthStat.setLastCheckIn(super.time); onWarn.ifPresent(checkIn -> checkIn.accept(BeanUtils.copy(nodeHealthStat))); }
@Test public void testWarn() throws Exception { healthService.register("foo", 1, TimeUnit.SECONDS); healthService.warnWithError("foo", new Exception("FOO")); assertFalse("foo is not found among the healthy ", healthService.findHealthyNodes().stream().anyMatch(s -> s.equals("foo"))); final List<NodeHealthStat> nodeHealthStats = healthService.loadNodes(); assertEquals(1, nodeHealthStats.size()); assertEquals("foo", nodeHealthStats.get(0).getName()); assertEquals(HealthStatus.WARN, nodeHealthStats.get(0).getStatus()); assertEquals(HealthFailReason.ERROR, nodeHealthStats.get(0).getReason()); assertEquals("FOO", nodeHealthStats.get(0).getError().get().getMessage()); }
@Override public boolean ok() { if (debug) logger.debug("HealthService::ok()"); boolean ok = serviceHealthStatMap.values() .stream() .allMatch(serviceHealthStat -> serviceHealthStat.getStatus() == HealthStatus.PASS); if (debug) logger.debug("HealthService::ok() was ok? {}", ok); return ok; }
@Override protected Object clone() throws CloneNotSupportedException { NodeHealthStat node = new NodeHealthStat(name, ttlInMS); node.reason = this.reason; node.error = this.error; node.status = this.status; return node; }
@Override public List<String> findAllNodes() { logger.info("HealthService::findAllNodes() called"); final List<String> names = new ArrayList<>(); serviceHealthStatMap.values() .stream() .forEach(serviceHealthStat -> names.add(serviceHealthStat.getName())); logger.info("HealthService::findAllNodes() called returns {}", names); return names; }
public void setStatus(HealthStatus status) { this.status = status; if (status == HealthStatus.PASS) { clearError(); } }
/** * Check in the service. * * @param name name */ @Override public void checkInOk(final String name) { if (debug) logger.debug("HealthService::checkInOk() {} ", name); final NodeHealthStat nodeHealthStat = getServiceHealthStat(name); nodeHealthStat.setLastCheckIn(super.time); nodeHealthStat.setReason(null); nodeHealthStat.setStatus(HealthStatus.PASS); super.incrementCount("checkin"); onCheckIn.ifPresent(checkIn -> checkIn.accept(BeanUtils.copy(nodeHealthStat))); }
/** * Fail the node for the service with a specific status. * * @param name name * @param error error */ @Override public void failWithError(final String name, final Throwable error) { logger.error("HealthService::fail() {}", name); super.incrementCount("fail"); final NodeHealthStat nodeHealthStat = getServiceHealthStat(name); nodeHealthStat.setStatus(HealthStatus.FAIL); nodeHealthStat.setReason(HealthFailReason.ERROR); nodeHealthStat.setLastCheckIn(super.time); nodeHealthStat.setError(error); onFail.ifPresent(checkIn -> checkIn.accept(BeanUtils.copy(nodeHealthStat))); }
@Test public void testWarnNoError() throws Exception { healthService.register("foo", 1, TimeUnit.SECONDS); healthService.warnWithReason("foo", HealthFailReason.TIMEOUT); assertFalse("foo is not found among the healthy ", healthService.findHealthyNodes().stream().anyMatch(s -> s.equals("foo"))); final List<NodeHealthStat> nodeHealthStats = healthService.loadNodes(); assertEquals(1, nodeHealthStats.size()); assertEquals("foo", nodeHealthStats.get(0).getName()); assertEquals(HealthStatus.WARN, nodeHealthStats.get(0).getStatus()); assertEquals(HealthFailReason.TIMEOUT, nodeHealthStats.get(0).getReason()); assertEquals(false, nodeHealthStats.get(0).getError().isPresent()); }
private void reportStatus(String name, NodeHealthStat currentHealth) { switch (currentHealth.getStatus()) { case PASS: if (debug) logger.debug("HEALTH PASS :: {} status check and got status {} ", name, currentHealth); onCheckIn.ifPresent(checkIn -> checkIn.accept(BeanUtils.copy(currentHealth))); super.incrementCount("pass"); break; case FAIL: logger.error("HEALTH FAIL :: {} status check and got status {} ", name, currentHealth); onFail.ifPresent(checkIn -> checkIn.accept(BeanUtils.copy(currentHealth))); super.incrementCount("fail"); break; case WARN: logger.warn("HEALTH WARNING :: {} status check and got status {} ", name, currentHealth); onWarn.ifPresent(checkIn -> checkIn.accept(BeanUtils.copy(currentHealth))); super.incrementCount("warn"); break; default: onCheckIn.ifPresent(checkIn -> checkIn.accept(BeanUtils.copy(currentHealth))); } }
/** * Register method to register services / internal nodes. * * @param name name * @param ttl ttl * @param timeUnit timeUnit */ @Override public void register(final String name, final long ttl, final TimeUnit timeUnit) { logger.info("HealthService::register() {} {} {}", name, ttl, timeUnit); final NodeHealthStat nodeHealthStat = new NodeHealthStat(name, timeUnit.toMillis(ttl)); serviceHealthStatMap.put(name, nodeHealthStat); super.incrementCount("nodes"); super.recordLevel("nodes", serviceHealthStatMap.size()); }
@Override public List<String> findAllNodes() { logger.info("HealthService::findAllNodes() called"); final List<String> names = new ArrayList<>(); serviceHealthStatMap.values() .stream() .forEach(serviceHealthStat -> names.add(serviceHealthStat.getName())); logger.info("HealthService::findAllNodes() called returns {}", names); return names; }
public void setStatus(HealthStatus status) { this.status = status; if (status == HealthStatus.PASS) { clearError(); } }
private void checkTTL(final NodeHealthStat nodeHealthStat) { if (debug) logger.debug("HealthService::checkTTL() {}", nodeHealthStat.getName()); if (!nodeHealthStat.isOk()) { return; } if (nodeHealthStat.isForever()) { return; } final long duration = super.time - nodeHealthStat.getLastCheckIn(); /* If the duration is greater than the ttl interval, then mark it as failed. */ if (duration > nodeHealthStat.getTtlInMS()) { logger.error("HealthService::checkTTL() {} FAILED TTL check, duration {}", nodeHealthStat.getName(), duration); nodeHealthStat.setReason(HealthFailReason.FAILED_TTL); nodeHealthStat.setStatus(HealthStatus.FAIL); onFail.ifPresent(checkIn -> checkIn.accept(BeanUtils.copy(nodeHealthStat))); } }
/** * Check in the service with a specific status. * * @param name name * @param reason reason */ @Override public void failWithReason(final String name, final HealthFailReason reason) { logger.error("HealthService::fail() {}", name); super.incrementCount("fail"); final NodeHealthStat nodeHealthStat = getServiceHealthStat(name); nodeHealthStat.setStatus(HealthStatus.FAIL); nodeHealthStat.setReason(reason); nodeHealthStat.setLastCheckIn(super.time); onFail.ifPresent(checkIn -> checkIn.accept(BeanUtils.copy(nodeHealthStat))); }
@Override public void warnWithError(final String name, final Throwable error) { logger.warn("HealthService::warn() {}", name); super.incrementCount("warn"); final NodeHealthStat nodeHealthStat = getServiceHealthStat(name); nodeHealthStat.setStatus(HealthStatus.WARN); nodeHealthStat.setReason(HealthFailReason.ERROR); nodeHealthStat.setLastCheckIn(super.time); nodeHealthStat.setError(error); onWarn.ifPresent(checkIn -> checkIn.accept(BeanUtils.copy(nodeHealthStat))); }