Search in sources :

Example 51 with MergedAnomalyResultDTO

use of com.linkedin.thirdeye.datalayer.dto.MergedAnomalyResultDTO in project pinot by linkedin.

the class AnomalyResource method viewMergedAnomaliesInRange.

// View merged anomalies for collection
@GET
@Path("/anomalies/view")
public List<MergedAnomalyResultDTO> viewMergedAnomaliesInRange(@NotNull @QueryParam("dataset") String dataset, @QueryParam("startTimeIso") String startTimeIso, @QueryParam("endTimeIso") String endTimeIso, @QueryParam("metric") String metric, @QueryParam("dimensions") String exploredDimensions, @DefaultValue("true") @QueryParam("applyAlertFilter") boolean applyAlertFiler) {
    if (StringUtils.isBlank(dataset)) {
        throw new IllegalArgumentException("dataset is a required query param");
    }
    DateTime endTime = DateTime.now();
    if (StringUtils.isNotEmpty(endTimeIso)) {
        endTime = ISODateTimeFormat.dateTimeParser().parseDateTime(endTimeIso);
    }
    DateTime startTime = endTime.minusDays(7);
    if (StringUtils.isNotEmpty(startTimeIso)) {
        startTime = ISODateTimeFormat.dateTimeParser().parseDateTime(startTimeIso);
    }
    List<MergedAnomalyResultDTO> anomalyResults = new ArrayList<>();
    try {
        if (StringUtils.isNotBlank(exploredDimensions)) {
            // Decode dimensions map from request, which may contain encode symbols such as "%20D", etc.
            exploredDimensions = URLDecoder.decode(exploredDimensions, UTF8);
            try {
                // Ensure the dimension names are sorted in order to match the string in backend database
                DimensionMap sortedDimensions = OBJECT_MAPPER.readValue(exploredDimensions, DimensionMap.class);
                exploredDimensions = OBJECT_MAPPER.writeValueAsString(sortedDimensions);
            } catch (IOException e) {
                LOG.warn("exploreDimensions may not be sorted because failed to read it as a json string: {}", e.toString());
            }
        }
        boolean loadRawAnomalies = false;
        if (StringUtils.isNotBlank(metric)) {
            if (StringUtils.isNotBlank(exploredDimensions)) {
                anomalyResults = anomalyMergedResultDAO.findByCollectionMetricDimensionsTime(dataset, metric, exploredDimensions, startTime.getMillis(), endTime.getMillis(), loadRawAnomalies);
            } else {
                anomalyResults = anomalyMergedResultDAO.findByCollectionMetricTime(dataset, metric, startTime.getMillis(), endTime.getMillis(), loadRawAnomalies);
            }
        } else {
            anomalyResults = anomalyMergedResultDAO.findByCollectionTime(dataset, startTime.getMillis(), endTime.getMillis(), loadRawAnomalies);
        }
    } catch (Exception e) {
        LOG.error("Exception in fetching anomalies", e);
    }
    if (applyAlertFiler) {
        // TODO: why need try catch?
        try {
            anomalyResults = AlertFilterHelper.applyFiltrationRule(anomalyResults, alertFilterFactory);
        } catch (Exception e) {
            LOG.warn("Failed to apply alert filters on anomalies for dataset:{}, metric:{}, start:{}, end:{}, exception:{}", dataset, metric, startTimeIso, endTimeIso, e);
        }
    }
    return anomalyResults;
}
Also used : MergedAnomalyResultDTO(com.linkedin.thirdeye.datalayer.dto.MergedAnomalyResultDTO) ArrayList(java.util.ArrayList) DimensionMap(com.linkedin.thirdeye.api.DimensionMap) IOException(java.io.IOException) DateTime(org.joda.time.DateTime) IOException(java.io.IOException) JsonProcessingException(com.fasterxml.jackson.core.JsonProcessingException) Path(javax.ws.rs.Path) GET(javax.ws.rs.GET)

Example 52 with MergedAnomalyResultDTO

use of com.linkedin.thirdeye.datalayer.dto.MergedAnomalyResultDTO in project pinot by linkedin.

the class OnboardResource method cloneAnomalyInstances.

/**
   * Clone merged anomaly instances of one function to another
   *   1. get all merged anomaly instances with AnomalyFunctionId = srcId
   *   2. set the associated anomalyFunctionId = destId
   *   3. save the modified anomaly instances
   * @param srcId the source function Id with anomalies to be cloned.
   * @param destId the destination function Id which source anomalies to be cloned to.
   * @return boolean to indicate if the clone is success or not
   */
public Boolean cloneAnomalyInstances(Long srcId, Long destId) {
    // make sure both function can be identified by IDs
    AnomalyFunctionDTO srcAnomalyFunction = anomalyFunctionDAO.findById(srcId);
    // if cannot find then return
    if (srcAnomalyFunction == null) {
        // LOG and exit
        LOG.error("Source Anomaly Function With id [{}] does not found", srcId);
        return false;
    }
    AnomalyFunctionDTO destAnomalyFunction = anomalyFunctionDAO.findById(destId);
    // if cannot find then return
    if (destAnomalyFunction == null) {
        // LOG and exit
        LOG.error("Destination Anomaly Function With id [{}] does not found", destId);
        return false;
    }
    LOG.info("clone merged anomaly results from source anomaly function id {} to id {}", srcId, destId);
    List<MergedAnomalyResultDTO> mergedAnomalyResultDTOs = mergedAnomalyResultDAO.findByFunctionId(srcId);
    if (mergedAnomalyResultDTOs == null || mergedAnomalyResultDTOs.isEmpty()) {
        LOG.error("No merged anomaly results found for anomaly function Id: {}", srcId);
        return false;
    }
    for (MergedAnomalyResultDTO mergedAnomalyResultDTO : mergedAnomalyResultDTOs) {
        long oldId = mergedAnomalyResultDTO.getId();
        // clean the Id, then will create a new Id when save
        mergedAnomalyResultDTO.setId(null);
        mergedAnomalyResultDTO.setRawAnomalyIdList(null);
        mergedAnomalyResultDTO.setFunctionId(destId);
        mergedAnomalyResultDTO.setFunction(destAnomalyFunction);
        long newId = mergedAnomalyResultDAO.save(mergedAnomalyResultDTO);
        LOG.debug("clone merged anomaly {} to {}", oldId, newId);
    }
    return true;
}
Also used : MergedAnomalyResultDTO(com.linkedin.thirdeye.datalayer.dto.MergedAnomalyResultDTO) AnomalyFunctionDTO(com.linkedin.thirdeye.datalayer.dto.AnomalyFunctionDTO)

Example 53 with MergedAnomalyResultDTO

use of com.linkedin.thirdeye.datalayer.dto.MergedAnomalyResultDTO in project pinot by linkedin.

the class AnomaliesResource method updateAnomalyMergedResultFeedback.

/**
   * Update anomaly feedback
   * @param mergedAnomalyId : mergedAnomalyId
   * @param payload         : Json payload containing feedback @see com.linkedin.thirdeye.constant.AnomalyFeedbackType
   *                        eg. payload
   *                        <p/>
   *                        { "feedbackType": "NOT_ANOMALY", "comment": "this is not an anomaly" }
   */
@POST
@Path(value = "/updateFeedback/{mergedAnomalyId}")
public void updateAnomalyMergedResultFeedback(@PathParam("mergedAnomalyId") long mergedAnomalyId, String payload) {
    try {
        MergedAnomalyResultDTO result = mergedAnomalyResultDAO.findById(mergedAnomalyId);
        if (result == null) {
            throw new IllegalArgumentException("AnomalyResult not found with id " + mergedAnomalyId);
        }
        AnomalyFeedbackDTO feedback = result.getFeedback();
        if (feedback == null) {
            feedback = new AnomalyFeedbackDTO();
            result.setFeedback(feedback);
        }
        AnomalyFeedbackDTO feedbackRequest = new ObjectMapper().readValue(payload, AnomalyFeedbackDTO.class);
        if (feedbackRequest.getStatus() == null) {
            feedback.setStatus(FeedbackStatus.NEW);
        } else {
            feedback.setStatus(feedbackRequest.getStatus());
        }
        feedback.setComment(feedbackRequest.getComment());
        feedback.setFeedbackType(feedbackRequest.getFeedbackType());
        mergedAnomalyResultDAO.updateAnomalyFeedback(result);
    } catch (IOException e) {
        throw new IllegalArgumentException("Invalid payload " + payload, e);
    }
}
Also used : MergedAnomalyResultDTO(com.linkedin.thirdeye.datalayer.dto.MergedAnomalyResultDTO) AnomalyFeedbackDTO(com.linkedin.thirdeye.datalayer.dto.AnomalyFeedbackDTO) IOException(java.io.IOException) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper) Path(javax.ws.rs.Path) POST(javax.ws.rs.POST)

Example 54 with MergedAnomalyResultDTO

use of com.linkedin.thirdeye.datalayer.dto.MergedAnomalyResultDTO in project pinot by linkedin.

the class OnboardResource method getExistingMergedAnomalies.

/**
   * Show the content of raw anomalies whose start time is located in the given time ranges
   *
   * @param monitoringWindowStartTime The start time of the monitoring window (in milli-second)
   * @param monitoringWindowEndTime The start time of the monitoring window (in milli-second)
   */
@POST
@Path("function/{id}/getExistingMergedAnomalies")
public List<MergedAnomalyResultDTO> getExistingMergedAnomalies(@PathParam("id") String id, @QueryParam("start") long monitoringWindowStartTime, @QueryParam("end") long monitoringWindowEndTime) {
    LOG.info("Retrieving merged anomaly results in the time range: {} -- {}", new DateTime(monitoringWindowStartTime), new DateTime(monitoringWindowEndTime));
    List<MergedAnomalyResultDTO> mergedResults = null;
    long functionId = Long.valueOf(id);
    AnomalyFunctionDTO anomalyFunction = anomalyFunctionDAO.findById(functionId);
    if (anomalyFunction == null) {
        LOG.info("Anomaly functionId {} is not found", functionId);
        return mergedResults;
    }
    mergedResults = mergedAnomalyResultDAO.findByStartTimeInRangeAndFunctionId(monitoringWindowStartTime, monitoringWindowEndTime, functionId);
    return mergedResults;
}
Also used : MergedAnomalyResultDTO(com.linkedin.thirdeye.datalayer.dto.MergedAnomalyResultDTO) AnomalyFunctionDTO(com.linkedin.thirdeye.datalayer.dto.AnomalyFunctionDTO) DateTime(org.joda.time.DateTime)

Example 55 with MergedAnomalyResultDTO

use of com.linkedin.thirdeye.datalayer.dto.MergedAnomalyResultDTO in project pinot by linkedin.

the class EmailResource method generateAndSendAlertForMetrics.

@GET
@Path("generate/metrics/{startTime}/{endTime}")
public Response generateAndSendAlertForMetrics(@PathParam("startTime") Long startTime, @PathParam("endTime") Long endTime, @QueryParam("metrics") String metrics, @QueryParam("from") String fromAddr, @QueryParam("to") String toAddr, @QueryParam("subject") String subject, @QueryParam("includeSentAnomaliesOnly") boolean includeSentAnomaliesOnly, @QueryParam("teHost") String teHost, @QueryParam("smtpHost") String smtpHost, @QueryParam("smtpPort") int smtpPort, @QueryParam("phantomJsPath") String phantomJsPath) {
    if (Strings.isNullOrEmpty(metrics)) {
        throw new WebApplicationException("metrics null or empty: " + metrics);
    }
    String[] metricsArr = metrics.split(",");
    if (metricsArr.length == 0) {
        throw new WebApplicationException("metrics empty : " + metricsArr);
    }
    if (Strings.isNullOrEmpty(toAddr)) {
        throw new WebApplicationException("Empty : list of recipients" + toAddr);
    }
    if (Strings.isNullOrEmpty(teHost)) {
        throw new WebApplicationException("Invalid TE host" + teHost);
    }
    if (Strings.isNullOrEmpty(smtpHost)) {
        throw new WebApplicationException("invalid smtp host" + smtpHost);
    }
    AnomalyReportGenerator anomalyReportGenerator = AnomalyReportGenerator.getInstance();
    List<MergedAnomalyResultDTO> anomalies = anomalyReportGenerator.getAnomaliesForMetrics(Arrays.asList(metricsArr), startTime, endTime);
    ThirdEyeAnomalyConfiguration configuration = new ThirdEyeAnomalyConfiguration();
    SmtpConfiguration smtpConfiguration = new SmtpConfiguration();
    smtpConfiguration.setSmtpHost(smtpHost);
    smtpConfiguration.setSmtpPort(smtpPort);
    configuration.setSmtpConfiguration(smtpConfiguration);
    configuration.setDashboardHost(teHost);
    configuration.setPhantomJsPath(phantomJsPath);
    String emailSub = Strings.isNullOrEmpty(subject) ? "Thirdeye Anomaly Report" : subject;
    anomalyReportGenerator.buildReport(startTime, endTime, anomalies, emailSub, configuration, includeSentAnomaliesOnly, toAddr, fromAddr, "Thirdeye Anomaly Report", true);
    return Response.ok().build();
}
Also used : WebApplicationException(javax.ws.rs.WebApplicationException) MergedAnomalyResultDTO(com.linkedin.thirdeye.datalayer.dto.MergedAnomalyResultDTO) SmtpConfiguration(com.linkedin.thirdeye.anomaly.SmtpConfiguration) AnomalyReportGenerator(com.linkedin.thirdeye.anomaly.alert.util.AnomalyReportGenerator) ThirdEyeAnomalyConfiguration(com.linkedin.thirdeye.anomaly.ThirdEyeAnomalyConfiguration) Path(javax.ws.rs.Path) GET(javax.ws.rs.GET)

Aggregations

MergedAnomalyResultDTO (com.linkedin.thirdeye.datalayer.dto.MergedAnomalyResultDTO)61 ArrayList (java.util.ArrayList)24 AnomalyFunctionDTO (com.linkedin.thirdeye.datalayer.dto.AnomalyFunctionDTO)17 RawAnomalyResultDTO (com.linkedin.thirdeye.datalayer.dto.RawAnomalyResultDTO)17 Path (javax.ws.rs.Path)16 DimensionMap (com.linkedin.thirdeye.api.DimensionMap)11 GET (javax.ws.rs.GET)10 AnomalyFeedbackDTO (com.linkedin.thirdeye.datalayer.dto.AnomalyFeedbackDTO)9 HashMap (java.util.HashMap)9 DateTime (org.joda.time.DateTime)9 MetricTimeSeries (com.linkedin.thirdeye.api.MetricTimeSeries)8 IOException (java.io.IOException)8 ScalingFactor (com.linkedin.thirdeye.detector.metric.transfer.ScalingFactor)7 ExecutionException (java.util.concurrent.ExecutionException)7 TimeoutException (java.util.concurrent.TimeoutException)6 TimeGranularity (com.linkedin.thirdeye.api.TimeGranularity)5 POST (javax.ws.rs.POST)5 Pair (com.linkedin.pinot.pql.parsers.utils.Pair)4 AnomalyDetectionInputContext (com.linkedin.thirdeye.anomaly.detection.AnomalyDetectionInputContext)4 AnomaliesWrapper (com.linkedin.thirdeye.dashboard.resources.v2.pojo.AnomaliesWrapper)4