in hertzbeat-manager/src/main/java/org/apache/hertzbeat/manager/component/status/CalculateStatus.java [162:237]
private void startCombineHistory() {
ThreadFactory threadFactory = new ThreadFactoryBuilder()
.setUncaughtExceptionHandler((thread, throwable) -> {
log.error("History combine has uncaughtException.");
log.error(throwable.getMessage(), throwable);
})
.setDaemon(true)
.setNameFormat("status-page-calculate-%d")
.build();
ScheduledExecutorService scheduledExecutor = Executors.newSingleThreadScheduledExecutor(threadFactory);
// combine history every day at 1:00 AM
LocalDateTime now = LocalDateTime.now();
LocalDateTime nextRun = now.withHour(1).withMinute(0).withSecond(0);
if (now.isAfter(nextRun)) {
nextRun = nextRun.plusDays(1);
}
long delay = Duration.between(now, nextRun).toMillis();
scheduledExecutor.scheduleAtFixedRate(() -> {
try {
// combine pre day status history to one record
LocalDateTime nowTime = LocalDateTime.now();
ZoneOffset zoneOffset = ZoneId.systemDefault().getRules().getOffset(Instant.now());
LocalDateTime midnight = nowTime.withHour(0).withMinute(0).withSecond(0).withNano(0);
LocalDateTime preNight = midnight.minusDays(1);
long midnightTimestamp = midnight.toInstant(zoneOffset).toEpochMilli();
long preNightTimestamp = preNight.toInstant(zoneOffset).toEpochMilli();
List<StatusPageHistory> statusPageHistoryList = statusPageHistoryDao
.findStatusPageHistoriesByTimestampBetween(preNightTimestamp, midnightTimestamp);
Map<Long, StatusPageHistory> statusPageHistoryMap = new HashMap<>(8);
for (StatusPageHistory statusPageHistory : statusPageHistoryList) {
statusPageHistory.setNormal(0);
statusPageHistory.setAbnormal(0);
statusPageHistory.setUnknowing(0);
if (statusPageHistoryMap.containsKey(statusPageHistory.getComponentId())) {
StatusPageHistory history = statusPageHistoryMap.get(statusPageHistory.getComponentId());
if (statusPageHistory.getState() == CommonConstants.STATUS_PAGE_COMPONENT_STATE_ABNORMAL) {
history.setAbnormal(history.getAbnormal() + intervals);
} else if (statusPageHistory.getState() == CommonConstants.STATUS_PAGE_COMPONENT_STATE_UNKNOWN) {
history.setUnknowing(history.getUnknowing() + intervals);
} else {
history.setNormal(history.getNormal() + intervals);
}
statusPageHistoryMap.put(statusPageHistory.getComponentId(), history);
} else {
if (statusPageHistory.getState() == CommonConstants.STATUS_PAGE_COMPONENT_STATE_ABNORMAL) {
statusPageHistory.setAbnormal(intervals);
} else if (statusPageHistory.getState() == CommonConstants.STATUS_PAGE_COMPONENT_STATE_UNKNOWN) {
statusPageHistory.setUnknowing(intervals);
} else {
statusPageHistory.setNormal(intervals);
}
statusPageHistoryMap.put(statusPageHistory.getComponentId(), statusPageHistory);
}
}
statusPageHistoryDao.deleteAll(statusPageHistoryList);
for (StatusPageHistory history : statusPageHistoryMap.values()) {
double total = history.getNormal() + history.getAbnormal() + history.getUnknowing();
double uptime = 0;
if (total > 0) {
uptime = (double) history.getNormal() / total;
}
history.setUptime(uptime);
if (history.getAbnormal() > 0) {
history.setState(CommonConstants.STATUS_PAGE_COMPONENT_STATE_ABNORMAL);
} else if (history.getNormal() > 0) {
history.setState(CommonConstants.STATUS_PAGE_COMPONENT_STATE_NORMAL);
} else {
history.setState(CommonConstants.STATUS_PAGE_COMPONENT_STATE_UNKNOWN);
}
statusPageHistoryDao.save(history);
}
} catch (Exception e) {
log.error("status page combine history error: {}", e.getMessage(), e);
}
}, delay, TimeUnit.DAYS.toMillis(1), TimeUnit.MILLISECONDS);
}