Search in sources :

Example 11 with AnomalyFunctionDTO

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

the class AnomalyResource method viewRawAnomaliesInRange.

//View raw anomalies for collection
@GET
@Path("/raw-anomalies/view")
@Produces(MediaType.APPLICATION_JSON)
public String viewRawAnomaliesInRange(@QueryParam("functionId") String functionId, @QueryParam("dataset") String dataset, @QueryParam("startTimeIso") String startTimeIso, @QueryParam("endTimeIso") String endTimeIso, @QueryParam("metric") String metric) throws JsonProcessingException {
    if (StringUtils.isBlank(functionId) && StringUtils.isBlank(dataset)) {
        throw new IllegalArgumentException("must provide dataset or functionId");
    }
    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<RawAnomalyResultDTO> rawAnomalyResults = new ArrayList<>();
    if (StringUtils.isNotBlank(functionId)) {
        rawAnomalyResults = rawAnomalyResultDAO.findAllByTimeAndFunctionId(startTime.getMillis(), endTime.getMillis(), Long.valueOf(functionId));
    } else if (StringUtils.isNotBlank(dataset)) {
        List<AnomalyFunctionDTO> anomalyFunctions = anomalyFunctionDAO.findAllByCollection(dataset);
        List<Long> functionIds = new ArrayList<>();
        for (AnomalyFunctionDTO anomalyFunction : anomalyFunctions) {
            if (StringUtils.isNotBlank(metric) && !anomalyFunction.getTopicMetric().equals(metric)) {
                continue;
            }
            functionIds.add(anomalyFunction.getId());
        }
        for (Long id : functionIds) {
            rawAnomalyResults.addAll(rawAnomalyResultDAO.findAllByTimeAndFunctionId(startTime.getMillis(), endTime.getMillis(), id));
        }
    }
    String response = new ObjectMapper().writerWithDefaultPrettyPrinter().writeValueAsString(rawAnomalyResults);
    return response;
}
Also used : RawAnomalyResultDTO(com.linkedin.thirdeye.datalayer.dto.RawAnomalyResultDTO) ArrayList(java.util.ArrayList) List(java.util.List) ArrayList(java.util.ArrayList) AnomalyFunctionDTO(com.linkedin.thirdeye.datalayer.dto.AnomalyFunctionDTO) DateTime(org.joda.time.DateTime) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper) Path(javax.ws.rs.Path) Produces(javax.ws.rs.Produces) GET(javax.ws.rs.GET)

Example 12 with AnomalyFunctionDTO

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

the class AnomalyResource method getAnomalyMergedResultTimeSeries.

/**
   * Returns the time series for the given anomaly.
   *
   * If viewWindowStartTime and/or viewWindowEndTime is not given, then a window is padded automatically. The padded
   * windows is half of the anomaly window size. For instance, if the anomaly lasts for 4 hours, then the pad window
   * size is 2 hours. The max padding size is 1 day.
   *
   * @param anomalyResultId the id of the given anomaly
   * @param viewWindowStartTime start time of the time series, inclusive
   * @param viewWindowEndTime end time of the time series, inclusive
   * @return the time series of the given anomaly
   * @throws Exception when it fails to retrieve collection, i.e., dataset, information
   */
@GET
@Path("/anomaly-merged-result/timeseries/{anomaly_merged_result_id}")
public AnomalyTimelinesView getAnomalyMergedResultTimeSeries(@NotNull @PathParam("anomaly_merged_result_id") long anomalyResultId, @NotNull @QueryParam("aggTimeGranularity") String aggTimeGranularity, @QueryParam("start") long viewWindowStartTime, @QueryParam("end") long viewWindowEndTime) throws Exception {
    boolean loadRawAnomalies = false;
    MergedAnomalyResultDTO anomalyResult = anomalyMergedResultDAO.findById(anomalyResultId, loadRawAnomalies);
    DimensionMap dimensions = anomalyResult.getDimensions();
    AnomalyFunctionDTO anomalyFunctionSpec = anomalyResult.getFunction();
    BaseAnomalyFunction anomalyFunction = anomalyFunctionFactory.fromSpec(anomalyFunctionSpec);
    // By default, the padding window size is half of the anomaly window.
    if (viewWindowStartTime == 0 || viewWindowEndTime == 0) {
        long anomalyWindowStartTime = anomalyResult.getStartTime();
        long anomalyWindowEndTime = anomalyResult.getEndTime();
        long bucketMillis = TimeUnit.MILLISECONDS.convert(anomalyFunctionSpec.getBucketSize(), anomalyFunctionSpec.getBucketUnit());
        long bucketCount = (anomalyWindowEndTime - anomalyWindowStartTime) / bucketMillis;
        long paddingMillis = Math.max(1, (bucketCount / 2)) * bucketMillis;
        if (paddingMillis > TimeUnit.DAYS.toMillis(1)) {
            paddingMillis = TimeUnit.DAYS.toMillis(1);
        }
        if (viewWindowStartTime == 0) {
            viewWindowStartTime = anomalyWindowStartTime - paddingMillis;
        }
        if (viewWindowEndTime == 0) {
            viewWindowEndTime = anomalyWindowEndTime + paddingMillis;
        }
    }
    TimeGranularity timeGranularity = Utils.getAggregationTimeGranularity(aggTimeGranularity, anomalyFunctionSpec.getCollection());
    long bucketMillis = timeGranularity.toMillis();
    // ThirdEye backend is end time exclusive, so one more bucket is appended to make end time inclusive for frontend.
    viewWindowEndTime += bucketMillis;
    long maxDataTime = collectionMaxDataTimeCache.get(anomalyResult.getCollection());
    if (viewWindowEndTime > maxDataTime) {
        viewWindowEndTime = (anomalyResult.getEndTime() > maxDataTime) ? anomalyResult.getEndTime() : maxDataTime;
    }
    AnomalyDetectionInputContext adInputContext = TimeBasedAnomalyMerger.fetchDataByDimension(viewWindowStartTime, viewWindowEndTime, dimensions, anomalyFunction, anomalyMergedResultDAO, overrideConfigDAO, false);
    MetricTimeSeries metricTimeSeries = adInputContext.getDimensionKeyMetricTimeSeriesMap().get(dimensions);
    if (metricTimeSeries == null) {
        // the timeseries for the given anomaly
        return new AnomalyTimelinesView();
    }
    // Transform time series with scaling factor
    List<ScalingFactor> scalingFactors = adInputContext.getScalingFactors();
    if (CollectionUtils.isNotEmpty(scalingFactors)) {
        Properties properties = anomalyFunction.getProperties();
        MetricTransfer.rescaleMetric(metricTimeSeries, viewWindowStartTime, scalingFactors, anomalyFunctionSpec.getTopicMetric(), properties);
    }
    List<MergedAnomalyResultDTO> knownAnomalies = adInputContext.getKnownMergedAnomalies().get(dimensions);
    // Known anomalies are ignored (the null parameter) because 1. we can reduce users' waiting time and 2. presentation
    // data does not need to be as accurate as the one used for detecting anomalies
    AnomalyTimelinesView anomalyTimelinesView = anomalyFunction.getTimeSeriesView(metricTimeSeries, bucketMillis, anomalyFunctionSpec.getTopicMetric(), viewWindowStartTime, viewWindowEndTime, knownAnomalies);
    // Generate summary for frontend
    List<TimeBucket> timeBuckets = anomalyTimelinesView.getTimeBuckets();
    if (timeBuckets.size() > 0) {
        TimeBucket firstBucket = timeBuckets.get(0);
        anomalyTimelinesView.addSummary("currentStart", Long.toString(firstBucket.getCurrentStart()));
        anomalyTimelinesView.addSummary("baselineStart", Long.toString(firstBucket.getBaselineStart()));
        TimeBucket lastBucket = timeBuckets.get(timeBuckets.size() - 1);
        anomalyTimelinesView.addSummary("currentEnd", Long.toString(lastBucket.getCurrentStart()));
        anomalyTimelinesView.addSummary("baselineEnd", Long.toString(lastBucket.getBaselineEnd()));
    }
    return anomalyTimelinesView;
}
Also used : BaseAnomalyFunction(com.linkedin.thirdeye.detector.function.BaseAnomalyFunction) TimeBucket(com.linkedin.thirdeye.dashboard.views.TimeBucket) MetricTimeSeries(com.linkedin.thirdeye.api.MetricTimeSeries) ScalingFactor(com.linkedin.thirdeye.detector.metric.transfer.ScalingFactor) AnomalyTimelinesView(com.linkedin.thirdeye.anomaly.views.AnomalyTimelinesView) Properties(java.util.Properties) AnomalyDetectionInputContext(com.linkedin.thirdeye.anomaly.detection.AnomalyDetectionInputContext) MergedAnomalyResultDTO(com.linkedin.thirdeye.datalayer.dto.MergedAnomalyResultDTO) TimeGranularity(com.linkedin.thirdeye.api.TimeGranularity) DimensionMap(com.linkedin.thirdeye.api.DimensionMap) AnomalyFunctionDTO(com.linkedin.thirdeye.datalayer.dto.AnomalyFunctionDTO) Path(javax.ws.rs.Path) GET(javax.ws.rs.GET)

Example 13 with AnomalyFunctionDTO

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

the class AnomalyResource method viewAnomalyFunctions.

/************* CRUD for anomaly functions of collection **********************************************/
// View all anomaly functions
@GET
@Path("/anomaly-function/view")
public List<AnomalyFunctionDTO> viewAnomalyFunctions(@NotNull @QueryParam("dataset") String dataset, @QueryParam("metric") String metric) {
    if (StringUtils.isBlank(dataset)) {
        throw new IllegalArgumentException("dataset is a required query param");
    }
    List<AnomalyFunctionDTO> anomalyFunctionSpecs = anomalyFunctionDAO.findAllByCollection(dataset);
    List<AnomalyFunctionDTO> anomalyFunctions = anomalyFunctionSpecs;
    if (StringUtils.isNotEmpty(metric)) {
        anomalyFunctions = new ArrayList<>();
        for (AnomalyFunctionDTO anomalyFunctionSpec : anomalyFunctionSpecs) {
            if (metric.equals(anomalyFunctionSpec.getTopicMetric())) {
                anomalyFunctions.add(anomalyFunctionSpec);
            }
        }
    }
    return anomalyFunctions;
}
Also used : AnomalyFunctionDTO(com.linkedin.thirdeye.datalayer.dto.AnomalyFunctionDTO) Path(javax.ws.rs.Path) GET(javax.ws.rs.GET)

Example 14 with AnomalyFunctionDTO

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

the class EmailResource method removeFunctionFromEmail.

@POST
@Path("{emailId}/delete/{functionId}")
public void removeFunctionFromEmail(@PathParam("emailId") Long emailId, @PathParam("functionId") Long functionId) {
    AnomalyFunctionDTO function = functionDAO.findById(functionId);
    EmailConfigurationDTO emailConfiguration = emailDAO.findById(emailId);
    if (function != null && emailConfiguration != null) {
        if (emailConfiguration.getFunctions().contains(function)) {
            emailConfiguration.getFunctions().remove(function);
            emailDAO.update(emailConfiguration);
        }
    }
}
Also used : AnomalyFunctionDTO(com.linkedin.thirdeye.datalayer.dto.AnomalyFunctionDTO) EmailConfigurationDTO(com.linkedin.thirdeye.datalayer.dto.EmailConfigurationDTO) Path(javax.ws.rs.Path) POST(javax.ws.rs.POST)

Example 15 with AnomalyFunctionDTO

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

the class EmailResource method addFunctionInEmail.

@POST
@Path("{emailId}/add/{functionId}")
public void addFunctionInEmail(@PathParam("emailId") Long emailId, @PathParam("functionId") Long functionId) {
    AnomalyFunctionDTO function = functionDAO.findById(functionId);
    EmailConfigurationDTO emailConfiguration = emailDAO.findById(emailId);
    List<EmailConfigurationDTO> emailConfigurationsWithFunction = emailDAO.findByFunctionId(functionId);
    for (EmailConfigurationDTO emailConfigurationDTO : emailConfigurationsWithFunction) {
        emailConfigurationDTO.getFunctions().remove(function);
        emailDAO.update(emailConfigurationDTO);
    }
    if (function != null && emailConfiguration != null) {
        if (!emailConfiguration.getFunctions().contains(function)) {
            emailConfiguration.getFunctions().add(function);
            emailDAO.update(emailConfiguration);
        }
    } else {
        throw new IllegalArgumentException("function or email not found for email : " + emailId + " function : " + functionId);
    }
}
Also used : AnomalyFunctionDTO(com.linkedin.thirdeye.datalayer.dto.AnomalyFunctionDTO) EmailConfigurationDTO(com.linkedin.thirdeye.datalayer.dto.EmailConfigurationDTO) Path(javax.ws.rs.Path) POST(javax.ws.rs.POST)

Aggregations

AnomalyFunctionDTO (com.linkedin.thirdeye.datalayer.dto.AnomalyFunctionDTO)74 ArrayList (java.util.ArrayList)23 DateTime (org.joda.time.DateTime)20 RawAnomalyResultDTO (com.linkedin.thirdeye.datalayer.dto.RawAnomalyResultDTO)19 MergedAnomalyResultDTO (com.linkedin.thirdeye.datalayer.dto.MergedAnomalyResultDTO)17 Test (org.testng.annotations.Test)16 Path (javax.ws.rs.Path)11 DatasetConfigDTO (com.linkedin.thirdeye.datalayer.dto.DatasetConfigDTO)9 POST (javax.ws.rs.POST)8 AnomalyDetectionContext (com.linkedin.thirdeye.anomalydetection.context.AnomalyDetectionContext)7 TimeGranularity (com.linkedin.thirdeye.api.TimeGranularity)7 EmailConfigurationDTO (com.linkedin.thirdeye.datalayer.dto.EmailConfigurationDTO)7 AnomalyFunctionBean (com.linkedin.thirdeye.datalayer.pojo.AnomalyFunctionBean)6 Interval (org.joda.time.Interval)6 MetricTimeSeries (com.linkedin.thirdeye.api.MetricTimeSeries)5 AnomalyFeedbackDTO (com.linkedin.thirdeye.datalayer.dto.AnomalyFeedbackDTO)5 DetectionStatusDTO (com.linkedin.thirdeye.datalayer.dto.DetectionStatusDTO)5 ScalingFactor (com.linkedin.thirdeye.detector.metric.transfer.ScalingFactor)5 HashMap (java.util.HashMap)5 NullArgumentException (org.apache.commons.lang.NullArgumentException)5