public void calculate()

in hertzbeat-alerter/src/main/java/org/apache/hertzbeat/alert/calculate/PeriodicAlertCalculator.java [57:110]


    public void calculate(AlertDefine rule) {
        if (!rule.isEnable() || StringUtils.isEmpty(rule.getExpr())) {
            log.error("Periodic rule {} is disabled or expression is empty", rule.getName());
            return;
        }
        long currentTimeMilli = System.currentTimeMillis();
        try {
            // for prometheus is instant promql query, for db is sql query
            // result: [{'value': 100, 'timestamp': 1343554, 'instance': 'node1'},{'value': 200, 'timestamp': 1343555, 'instance': 'node2'}]
            // the return result should be matched with threshold
            try {
                List<Map<String, Object>> results = dataSourceService.calculate(
                        rule.getDatasource(),
                        rule.getExpr()
                );
                // if no match the expr threshold, the results item map {'value': null} should be null and others field keep
                // if results has multi list, should trigger multi alert
                if (CollectionUtils.isEmpty(results)) {
                    return;
                }
                for (Map<String, Object> result : results) {
                    Map<String, String> fingerPrints = new HashMap<>(8);
                    // here use the alert name as finger, not care the alert name may be changed
                    fingerPrints.put(CommonConstants.LABEL_ALERT_NAME, rule.getName());
                    fingerPrints.putAll(rule.getLabels());
                    for (Map.Entry<String, Object> entry : result.entrySet()) {
                        if (entry.getValue() != null && !VALUE.equals(entry.getKey())
                                && !TIMESTAMP.equals(entry.getKey())) {
                            fingerPrints.put(entry.getKey(), entry.getValue().toString());
                        }
                    }
                    if (result.get(VALUE) == null) {
                        // recovery the alert
                        handleRecoveredAlert(fingerPrints);
                        continue;
                    }
                    Map<String, Object> fieldValueMap = new HashMap<>(8);
                    fieldValueMap.putAll(rule.getLabels());
                    fieldValueMap.put(CommonConstants.LABEL_ALERT_NAME, rule.getName());
                    for (Map.Entry<String, Object> entry : result.entrySet()) {
                        if (entry.getValue() != null) {
                            fieldValueMap.put(entry.getKey(), entry.getValue());
                        }
                    }
                    afterThresholdRuleMatch(currentTimeMilli, fingerPrints, fieldValueMap, rule);
                }
            } catch (Exception ignored) {
                // ignore the query exception eg: no result, timeout, etc
                return;
            }
        } catch (Exception e) {
            log.error("Calculate periodic rule {} failed: {}", rule.getName(), e.getMessage());
        }
    }