package com.linkedin.thirdeye.anomaly.alert.util;
import com.linkedin.thirdeye.datalayer.dto.AnomalyFunctionDTO;
import com.linkedin.thirdeye.datalayer.dto.MergedAnomalyResultDTO;
import com.linkedin.thirdeye.detector.email.filter.AlertFilter;
import com.linkedin.thirdeye.detector.email.filter.AlertFilterFactory;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class AlertFilterHelper {
private static final Logger LOG = LoggerFactory.getLogger(AlertFilterHelper.class);
/**
* Each function has a filtration rule which let alert module decide if an anomaly should be
* included in the alert email. This method applies respective filtration rule on list of
* anomalies.
*
* @param results
*
* @return
*/
public static List<MergedAnomalyResultDTO> applyFiltrationRule(List<MergedAnomalyResultDTO> results, AlertFilterFactory alertFilterFactory){
if (results.size() == 0) {
return results;
}
// Function ID to Alert Filter
Map<Long, AlertFilter> functionAlertFilter = new HashMap<>();
List<MergedAnomalyResultDTO> qualifiedAnomalies = new ArrayList<>();
for (MergedAnomalyResultDTO result : results) {
// Lazy initiates alert filter for anomalies of the same anomaly function
AnomalyFunctionDTO anomalyFunctionSpec = result.getFunction();
long functionId = anomalyFunctionSpec.getId();
AlertFilter alertFilter = functionAlertFilter.get(functionId);
if (alertFilter == null) {
// Get filtration rule from anomaly function configuration
alertFilter = alertFilterFactory.fromSpec(anomalyFunctionSpec.getAlertFilter());
functionAlertFilter.put(functionId, alertFilter);
LOG.info("Using filter {} for anomaly function {} (dataset: {}, topic metric: {})", alertFilter,
functionId, anomalyFunctionSpec.getCollection(), anomalyFunctionSpec.getTopicMetric());
}
if (alertFilter.isQualified(result)) {
qualifiedAnomalies.add(result);
}
}
LOG.info(
"Found [{}] anomalies qualified to alert after applying filtration rule on [{}] anomalies",
qualifiedAnomalies.size(), results.size());
return qualifiedAnomalies;
}
}