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;
}
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;
}
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;
}
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;
}
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;
}
Aggregations