Search in sources :

Example 6 with TimeBucket

use of com.linkedin.thirdeye.dashboard.views.TimeBucket in project pinot by linkedin.

the class ContributorViewHandler method process.

@Override
public ContributorViewResponse process(ContributorViewRequest request) throws Exception {
    TimeOnTimeComparisonRequest comparisonRequest = generateTimeOnTimeComparisonRequest(request);
    TimeOnTimeComparisonHandler handler = new TimeOnTimeComparisonHandler(queryCache);
    TimeOnTimeComparisonResponse response = handler.handle(comparisonRequest);
    List<String> metricNames = new ArrayList<>(response.getMetrics());
    List<String> expressionNames = new ArrayList<>();
    for (MetricExpression expression : request.getMetricExpressions()) {
        expressionNames.add(expression.getExpressionName());
    }
    List<String> dimensions = new ArrayList<>(response.getDimensions());
    List<TimeBucket> timeBuckets = getTimeBuckets(response);
    Map<String, SortedSet<Row>> rows = getRowsSortedByTime(response);
    ContributorViewResponse contributorViewResponse = new ContributorViewResponse();
    contributorViewResponse.setMetrics(expressionNames);
    contributorViewResponse.setDimensions(dimensions);
    contributorViewResponse.setTimeBuckets(timeBuckets);
    GenericResponse genericResponse = new GenericResponse();
    Map<String, Double[]> runningTotalMap = new HashMap<>();
    // one view per <metric,dimensionName> combination
    Map<String, ContributionViewTableBuilder> contributionViewTableMap = new LinkedHashMap<>();
    Map<String, List<String>> dimensionValuesMap = new HashMap<>();
    for (Map.Entry<String, SortedSet<Row>> entry : rows.entrySet()) {
        for (Row row : entry.getValue()) {
            String dimensionName = row.getDimensionName();
            String dimensionValue = row.getDimensionValue();
            for (Metric metric : row.getMetrics()) {
                String metricName = metric.getMetricName();
                if (!expressionNames.contains(metricName)) {
                    continue;
                }
                Double baselineValue = metric.getBaselineValue();
                Double currentValue = metric.getCurrentValue();
                Double cumulativeBaselineValue;
                Double cumulativeCurrentValue;
                String metricDimensionNameString = metricName + "." + dimensionName;
                ContributionViewTableBuilder contributionViewTable = contributionViewTableMap.get(metricDimensionNameString);
                if (contributionViewTable == null) {
                    contributionViewTable = new ContributionViewTableBuilder(metricName, dimensionName);
                    contributionViewTableMap.put(metricDimensionNameString, contributionViewTable);
                }
                String rowKey = metricName + "." + dimensionName + "." + dimensionValue;
                if (runningTotalMap.containsKey(rowKey)) {
                    Double[] totalValues = runningTotalMap.get(rowKey);
                    cumulativeBaselineValue = totalValues[0] + baselineValue;
                    cumulativeCurrentValue = totalValues[1] + currentValue;
                } else {
                    cumulativeBaselineValue = baselineValue;
                    cumulativeCurrentValue = currentValue;
                }
                TimeBucket timeBucket = TimeBucket.fromRow(row);
                contributionViewTable.addEntry(dimensionValue, timeBucket, baselineValue, currentValue, cumulativeBaselineValue, cumulativeCurrentValue);
                List<String> dimensionValues = dimensionValuesMap.get(dimensionName);
                if (dimensionValues == null) {
                    dimensionValues = new ArrayList<>();
                    dimensionValuesMap.put(dimensionName, dimensionValues);
                }
                if (!dimensionValues.contains(dimensionValue)) {
                    dimensionValues.add(dimensionValue);
                }
                Double[] runningTotalPerMetric = new Double[] { cumulativeBaselineValue, cumulativeCurrentValue };
                runningTotalMap.put(rowKey, runningTotalPerMetric);
            }
        }
    }
    Map<String, List<Integer>> keyToRowIdListMapping = new TreeMap<>();
    List<String[]> rowData = new ArrayList<>();
    // for each metric, dimension pair compute the total value for each dimension. This will be used
    // to sort the dimension values
    Map<String, Map<String, Map<String, Double>>> baselineTotalMapPerDimensionValue = new HashMap<>();
    Map<String, Map<String, Map<String, Double>>> currentTotalMapPerDimensionValue = new HashMap<>();
    for (String metricDimensionNameString : contributionViewTableMap.keySet()) {
        ContributionViewTableBuilder contributionViewTable = contributionViewTableMap.get(metricDimensionNameString);
        ContributionViewTable table = contributionViewTable.build();
        List<ContributionCell> cells = table.getCells();
        for (ContributionCell cell : cells) {
            String metricName = table.getMetricName();
            String dimName = table.getDimensionName();
            String dimValue = cell.getDimensionValue();
            String key = metricName + "|" + dimName + "|" + dimValue;
            List<Integer> rowIdList = keyToRowIdListMapping.get(key);
            if (rowIdList == null) {
                rowIdList = new ArrayList<>();
                keyToRowIdListMapping.put(key, rowIdList);
            }
            rowIdList.add(rowData.size());
            rowData.add(cell.toArray());
            // update baseline
            updateTotalForDimensionValue(baselineTotalMapPerDimensionValue, metricName, dimName, dimValue, cell.getBaselineValue());
            // update current
            updateTotalForDimensionValue(currentTotalMapPerDimensionValue, metricName, dimName, dimValue, cell.getCurrentValue());
        }
    }
    genericResponse.setResponseData(rowData);
    genericResponse.setSchema(new ResponseSchema(ContributionCell.columns()));
    genericResponse.setKeyToRowIdMapping(keyToRowIdListMapping);
    Info summary = new Info();
    genericResponse.setSummary(summary);
    for (String dimensionName : dimensionValuesMap.keySet()) {
        List<String> dimensionValues = dimensionValuesMap.get(dimensionName);
        sort(expressionNames, dimensionName, dimensionValues, baselineTotalMapPerDimensionValue, currentTotalMapPerDimensionValue);
    }
    contributorViewResponse.setDimensionValuesMap(dimensionValuesMap);
    contributorViewResponse.setResponseData(genericResponse);
    contributorViewResponse.setCurrentTotalMapPerDimensionValue(currentTotalMapPerDimensionValue);
    contributorViewResponse.setBaselineTotalMapPerDimensionValue(baselineTotalMapPerDimensionValue);
    return contributorViewResponse;
}
Also used : HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) ArrayList(java.util.ArrayList) SortedSet(java.util.SortedSet) LinkedHashMap(java.util.LinkedHashMap) TimeOnTimeComparisonResponse(com.linkedin.thirdeye.client.comparison.TimeOnTimeComparisonResponse) ArrayList(java.util.ArrayList) List(java.util.List) GenericResponse(com.linkedin.thirdeye.dashboard.views.GenericResponse) TimeOnTimeComparisonHandler(com.linkedin.thirdeye.client.comparison.TimeOnTimeComparisonHandler) TimeBucket(com.linkedin.thirdeye.dashboard.views.TimeBucket) TimeOnTimeComparisonRequest(com.linkedin.thirdeye.client.comparison.TimeOnTimeComparisonRequest) MetricExpression(com.linkedin.thirdeye.client.MetricExpression) TreeMap(java.util.TreeMap) Info(com.linkedin.thirdeye.dashboard.views.GenericResponse.Info) ResponseSchema(com.linkedin.thirdeye.dashboard.views.GenericResponse.ResponseSchema) Metric(com.linkedin.thirdeye.client.comparison.Row.Metric) Row(com.linkedin.thirdeye.client.comparison.Row) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map) TreeMap(java.util.TreeMap)

Example 7 with TimeBucket

use of com.linkedin.thirdeye.dashboard.views.TimeBucket in project pinot by linkedin.

the class TabularViewHandler method getTimeBuckets.

private List<TimeBucket> getTimeBuckets(TimeOnTimeComparisonResponse response) {
    List<TimeBucket> timeBuckets = new ArrayList<>();
    int numRows = response.getNumRows();
    for (int i = 0; i < numRows; i++) {
        Row row = response.getRow(i);
        TimeBucket bucket = TimeBucket.fromRow(row);
        timeBuckets.add(bucket);
    }
    Collections.sort(timeBuckets);
    return timeBuckets;
}
Also used : ArrayList(java.util.ArrayList) TimeBucket(com.linkedin.thirdeye.dashboard.views.TimeBucket) Row(com.linkedin.thirdeye.client.comparison.Row)

Example 8 with TimeBucket

use of com.linkedin.thirdeye.dashboard.views.TimeBucket in project pinot by linkedin.

the class BaseAnomalyFunction method getTimeSeriesView.

/**
   * This method provides a view of current time series, i.e., no baseline time series.
   *
   * @param timeSeries the time series that contains the metric to be processed
   * @param bucketMillis the size of a bucket in milli-seconds
   * @param metric the metric name to retrieve the data from the given time series
   * @param viewWindowStartTime the start time bucket of current time series, inclusive
   * @param viewWindowEndTime the end time buckets of current time series, exclusive
   * @param knownAnomalies it is assumed to be null for presentational purpose.
   * @return
   */
@Override
public AnomalyTimelinesView getTimeSeriesView(MetricTimeSeries timeSeries, long bucketMillis, String metric, long viewWindowStartTime, long viewWindowEndTime, List<MergedAnomalyResultDTO> knownAnomalies) {
    AnomalyTimelinesView anomalyTimelinesView = new AnomalyTimelinesView();
    // Construct Week-over-Week AnomalyTimelinesView
    int bucketCount = (int) ((viewWindowEndTime - viewWindowStartTime) / bucketMillis);
    for (int i = 0; i < bucketCount; ++i) {
        long currentBucketMillis = viewWindowStartTime + i * bucketMillis;
        long baselineBucketMillis = currentBucketMillis - TimeUnit.DAYS.toMillis(7);
        TimeBucket timebucket = new TimeBucket(currentBucketMillis, currentBucketMillis + bucketMillis, baselineBucketMillis, baselineBucketMillis + bucketMillis);
        anomalyTimelinesView.addTimeBuckets(timebucket);
        anomalyTimelinesView.addCurrentValues(timeSeries.get(currentBucketMillis, metric).doubleValue());
        anomalyTimelinesView.addBaselineValues(timeSeries.get(baselineBucketMillis, metric).doubleValue());
    }
    return anomalyTimelinesView;
}
Also used : TimeBucket(com.linkedin.thirdeye.dashboard.views.TimeBucket) AnomalyTimelinesView(com.linkedin.thirdeye.anomaly.views.AnomalyTimelinesView)

Example 9 with TimeBucket

use of com.linkedin.thirdeye.dashboard.views.TimeBucket in project pinot by linkedin.

the class RatioOutlierFunction method getTimeSeriesView.

@Override
public AnomalyTimelinesView getTimeSeriesView(MetricTimeSeries timeSeries, long bucketMillis, String metric, long viewWindowStartTime, long viewWindowEndTime, List<MergedAnomalyResultDTO> knownAnomalies) {
    double min = 0.0d;
    try {
        // Parse function properties
        Properties props = getProperties();
        // Get min / max props
        if (props.containsKey(MIN_VAL)) {
            min = Double.valueOf(props.getProperty(MIN_VAL));
        }
    } catch (IOException e) {
        LOG.warn("Error extracting min value, using 0.0 instead");
    }
    String m_a = getSpec().getMetrics().get(0);
    String m_b = getSpec().getMetrics().get(1);
    AnomalyTimelinesView view = new AnomalyTimelinesView();
    int bucketCount = (int) ((viewWindowEndTime - viewWindowStartTime) / bucketMillis);
    for (int i = 0; i < bucketCount; ++i) {
        long currentBucketMillis = viewWindowStartTime + i * bucketMillis;
        long baselineBucketMillis = currentBucketMillis - TimeUnit.DAYS.toMillis(7);
        TimeBucket timebucket = new TimeBucket(currentBucketMillis, currentBucketMillis + bucketMillis, baselineBucketMillis, baselineBucketMillis + bucketMillis);
        view.addTimeBuckets(timebucket);
        double value_a = timeSeries.get(currentBucketMillis, m_a).doubleValue();
        double value_b = timeSeries.get(currentBucketMillis, m_b).doubleValue();
        if (value_b != 0.0d) {
            double ratio = value_a / value_b;
            view.addCurrentValues(ratio);
        } else {
            view.addCurrentValues(Double.NaN);
        }
        view.addBaselineValues(min);
    }
    return view;
}
Also used : TimeBucket(com.linkedin.thirdeye.dashboard.views.TimeBucket) IOException(java.io.IOException) AnomalyTimelinesView(com.linkedin.thirdeye.anomaly.views.AnomalyTimelinesView) Properties(java.util.Properties)

Example 10 with TimeBucket

use of com.linkedin.thirdeye.dashboard.views.TimeBucket in project pinot by linkedin.

the class TimeSeriesResource method getTabularData.

/**
   * used when dimension is not passed, i.e. data is requested for all dimensions.
   * @param metricId
   * @param currentStart
   * @param currentEnd
   * @param baselineStart
   * @param baselineEnd
   * @param filters
   * @param granularity
   * @return
   */
private TimeSeriesCompareMetricView getTabularData(long metricId, long currentStart, long currentEnd, long baselineStart, long baselineEnd, String filters, String granularity) {
    TimeSeriesCompareMetricView timeSeriesCompareView = new TimeSeriesCompareMetricView();
    try {
        MetricConfigDTO metricConfigDTO = metricConfigDAO.findById(metricId);
        if (metricConfigDTO != null) {
            String dataset = metricConfigDTO.getDataset();
            TabularViewRequest request = new TabularViewRequest();
            request.setCollection(dataset);
            MetricExpression metricExpression = ThirdEyeUtils.getMetricExpressionFromMetricConfig(metricConfigDTO);
            request.setMetricExpressions(Arrays.asList(metricExpression));
            DateTimeZone timeZoneForCollection = Utils.getDataTimeZone(dataset);
            request.setBaselineStart(new DateTime(baselineStart, timeZoneForCollection));
            request.setBaselineEnd(new DateTime(baselineEnd, timeZoneForCollection));
            request.setCurrentStart(new DateTime(currentStart, timeZoneForCollection));
            request.setCurrentEnd(new DateTime(currentEnd, timeZoneForCollection));
            request.setTimeGranularity(Utils.getAggregationTimeGranularity(granularity, dataset));
            if (filters != null && !filters.isEmpty()) {
                filters = URLDecoder.decode(filters, "UTF-8");
                request.setFilters(ThirdEyeUtils.convertToMultiMap(filters));
            }
            TabularViewHandler handler = new TabularViewHandler(queryCache);
            TabularViewResponse response = handler.process(request);
            timeSeriesCompareView.setStart(currentStart);
            timeSeriesCompareView.setEnd(currentEnd);
            timeSeriesCompareView.setMetricId(metricConfigDTO.getId());
            timeSeriesCompareView.setMetricName(metricConfigDTO.getName());
            List<Long> timeBucketsCurrent = new ArrayList<>();
            List<Long> timeBucketsBaseline = new ArrayList<>();
            int numTimeBuckets = response.getTimeBuckets().size();
            double[] currentValues = new double[numTimeBuckets];
            double[] baselineValues = new double[numTimeBuckets];
            String[] percentageChangeValues = new String[numTimeBuckets];
            double[] cumCurrentValues = new double[numTimeBuckets];
            double[] cumBaselineValues = new double[numTimeBuckets];
            String[] cumPercentageChangeValues = new String[numTimeBuckets];
            int currentValIndex = response.getData().get(metricConfigDTO.getName()).getSchema().getColumnsToIndexMapping().get("currentValue");
            int baselineValIndex = response.getData().get(metricConfigDTO.getName()).getSchema().getColumnsToIndexMapping().get("baselineValue");
            int percentageChangeIndex = response.getData().get(metricConfigDTO.getName()).getSchema().getColumnsToIndexMapping().get("ratio");
            int cumCurrentValIndex = response.getData().get(metricConfigDTO.getName()).getSchema().getColumnsToIndexMapping().get("cumulativeCurrentValue");
            int cumBaselineValIndex = response.getData().get(metricConfigDTO.getName()).getSchema().getColumnsToIndexMapping().get("cumulativeBaselineValue");
            int cumPercentageChangeIndex = response.getData().get(metricConfigDTO.getName()).getSchema().getColumnsToIndexMapping().get("cumulativeRatio");
            for (int i = 0; i < numTimeBuckets; i++) {
                TimeBucket tb = response.getTimeBuckets().get(i);
                timeBucketsCurrent.add(tb.getCurrentStart());
                timeBucketsBaseline.add(tb.getBaselineStart());
                currentValues[i] = Double.valueOf(response.getData().get(metricConfigDTO.getName()).getResponseData().get(i)[currentValIndex]);
                baselineValues[i] = Double.valueOf(response.getData().get(metricConfigDTO.getName()).getResponseData().get(i)[baselineValIndex]);
                percentageChangeValues[i] = response.getData().get(metricConfigDTO.getName()).getResponseData().get(i)[percentageChangeIndex];
                cumCurrentValues[i] = Double.valueOf(response.getData().get(metricConfigDTO.getName()).getResponseData().get(i)[cumCurrentValIndex]);
                cumBaselineValues[i] = Double.valueOf(response.getData().get(metricConfigDTO.getName()).getResponseData().get(i)[cumBaselineValIndex]);
                cumPercentageChangeValues[i] = response.getData().get(metricConfigDTO.getName()).getResponseData().get(i)[cumPercentageChangeIndex];
            }
            timeSeriesCompareView.setTimeBucketsCurrent(timeBucketsCurrent);
            timeSeriesCompareView.setTimeBucketsBaseline(timeBucketsBaseline);
            ValuesContainer values = new ValuesContainer();
            values.setCurrentValues(currentValues);
            values.setBaselineValues(baselineValues);
            values.setPercentageChange(percentageChangeValues);
            values.setCumulativeCurrentValues(cumCurrentValues);
            values.setCumulativeBaselineValues(cumBaselineValues);
            values.setCumulativePercentageChange(cumPercentageChangeValues);
            timeSeriesCompareView.setSubDimensionContributionMap(new LinkedHashMap<>());
            timeSeriesCompareView.getSubDimensionContributionMap().put(ALL, values);
        }
    } catch (Exception e) {
        LOG.error(e.getMessage(), e);
        throw new WebApplicationException(e);
    }
    return timeSeriesCompareView;
}
Also used : MetricConfigDTO(com.linkedin.thirdeye.datalayer.dto.MetricConfigDTO) WebApplicationException(javax.ws.rs.WebApplicationException) TimeSeriesCompareMetricView(com.linkedin.thirdeye.dashboard.resources.v2.pojo.TimeSeriesCompareMetricView) TabularViewHandler(com.linkedin.thirdeye.dashboard.views.tabular.TabularViewHandler) ArrayList(java.util.ArrayList) TimeBucket(com.linkedin.thirdeye.dashboard.views.TimeBucket) TabularViewResponse(com.linkedin.thirdeye.dashboard.views.tabular.TabularViewResponse) MetricExpression(com.linkedin.thirdeye.client.MetricExpression) DateTimeZone(org.joda.time.DateTimeZone) DateTime(org.joda.time.DateTime) WebApplicationException(javax.ws.rs.WebApplicationException) ValuesContainer(com.linkedin.thirdeye.dashboard.resources.v2.pojo.ValuesContainer) TabularViewRequest(com.linkedin.thirdeye.dashboard.views.tabular.TabularViewRequest)

Aggregations

TimeBucket (com.linkedin.thirdeye.dashboard.views.TimeBucket)12 ArrayList (java.util.ArrayList)6 AnomalyTimelinesView (com.linkedin.thirdeye.anomaly.views.AnomalyTimelinesView)4 MetricExpression (com.linkedin.thirdeye.client.MetricExpression)4 Row (com.linkedin.thirdeye.client.comparison.Row)4 MetricConfigDTO (com.linkedin.thirdeye.datalayer.dto.MetricConfigDTO)3 LinkedHashMap (java.util.LinkedHashMap)3 DateTime (org.joda.time.DateTime)3 MetricTimeSeries (com.linkedin.thirdeye.api.MetricTimeSeries)2 Metric (com.linkedin.thirdeye.client.comparison.Row.Metric)2 TimeOnTimeComparisonHandler (com.linkedin.thirdeye.client.comparison.TimeOnTimeComparisonHandler)2 TimeOnTimeComparisonRequest (com.linkedin.thirdeye.client.comparison.TimeOnTimeComparisonRequest)2 TimeOnTimeComparisonResponse (com.linkedin.thirdeye.client.comparison.TimeOnTimeComparisonResponse)2 TimeSeriesCompareMetricView (com.linkedin.thirdeye.dashboard.resources.v2.pojo.TimeSeriesCompareMetricView)2 ValuesContainer (com.linkedin.thirdeye.dashboard.resources.v2.pojo.ValuesContainer)2 GenericResponse (com.linkedin.thirdeye.dashboard.views.GenericResponse)2 ResponseSchema (com.linkedin.thirdeye.dashboard.views.GenericResponse.ResponseSchema)2 HashMap (java.util.HashMap)2 Properties (java.util.Properties)2 AnomalyDetectionInputContext (com.linkedin.thirdeye.anomaly.detection.AnomalyDetectionInputContext)1