Search in sources :

Example 6 with TimeSeriesMetric

use of com.linkedin.thirdeye.client.timeseries.TimeSeriesRow.TimeSeriesMetric in project pinot by linkedin.

the class TimeSeriesHandler method computeDerivedMetrics.

private void computeDerivedMetrics(TimeSeriesRequest timeSeriesRequest, List<TimeSeriesRow> rows) throws Exception {
    // compute list of derived expressions
    List<MetricFunction> metricFunctionsFromExpressions = Utils.computeMetricFunctionsFromExpressions(timeSeriesRequest.getMetricExpressions());
    Set<String> metricNameSet = new HashSet<>();
    for (MetricFunction function : metricFunctionsFromExpressions) {
        metricNameSet.add(function.getMetricName());
    }
    List<MetricExpression> derivedMetricExpressions = new ArrayList<>();
    for (MetricExpression expression : timeSeriesRequest.getMetricExpressions()) {
        if (!metricNameSet.contains(expression.getExpressionName())) {
            derivedMetricExpressions.add(expression);
        }
    }
    // add metric expressions
    if (derivedMetricExpressions.size() > 0) {
        Map<String, Double> valueContext = new HashMap<>();
        for (TimeSeriesRow row : rows) {
            valueContext.clear();
            List<TimeSeriesMetric> metrics = row.getMetrics();
            // baseline value
            for (TimeSeriesMetric metric : metrics) {
                valueContext.put(metric.getMetricName(), metric.getValue());
            }
            for (MetricExpression expression : derivedMetricExpressions) {
                String derivedMetricExpression = expression.getExpression();
                double derivedMetricValue = MetricExpression.evaluateExpression(derivedMetricExpression, valueContext);
                if (Double.isInfinite(derivedMetricValue) || Double.isNaN(derivedMetricValue)) {
                    derivedMetricValue = 0;
                }
                row.getMetrics().add(new TimeSeriesMetric(expression.getExpressionName(), derivedMetricValue));
            }
        }
    }
}
Also used : HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) MetricExpression(com.linkedin.thirdeye.client.MetricExpression) MetricFunction(com.linkedin.thirdeye.client.MetricFunction) TimeSeriesMetric(com.linkedin.thirdeye.client.timeseries.TimeSeriesRow.TimeSeriesMetric) HashSet(java.util.HashSet)

Example 7 with TimeSeriesMetric

use of com.linkedin.thirdeye.client.timeseries.TimeSeriesRow.TimeSeriesMetric in project pinot by linkedin.

the class TimeSeriesResponseConverter method toMap.

/**
   * Convert the response to a Map<DimensionKey, MetricTimeSeries>. DimensionKey is generated based
   * off of schemaDimensions, while the MetricTimeSeries objects are generated based on the rows
   * within the response input. The metrics returned in the MetricTimeSeries instances correspond to
   * the metric names as opposed to the full metric function (eg __COUNT instead of SUM(__COUNT))
   */
public static Map<DimensionKey, MetricTimeSeries> toMap(TimeSeriesResponse response, List<String> schemaDimensions) {
    DimensionKeyGenerator dimensionKeyGenerator = new DimensionKeyGenerator(schemaDimensions);
    List<String> metrics = new ArrayList<>(response.getMetrics());
    Set<String> metricSet = new HashSet<>(metrics);
    List<MetricType> types = Collections.nCopies(metrics.size(), MetricType.DOUBLE);
    MetricSchema metricSchema = new MetricSchema(metrics, types);
    SetMultimap<DimensionKey, TimeSeriesRow> dimensionKeyToRows = HashMultimap.create();
    // group the rows by their dimension key
    for (int i = 0; i < response.getNumRows(); i++) {
        TimeSeriesRow row = response.getRow(i);
        DimensionKey dimensionKey = dimensionKeyGenerator.get(row.getDimensionNames(), row.getDimensionValues());
        dimensionKeyToRows.put(dimensionKey, row);
    }
    Map<DimensionKey, MetricTimeSeries> result = new HashMap<>();
    for (Entry<DimensionKey, Collection<TimeSeriesRow>> entry : dimensionKeyToRows.asMap().entrySet()) {
        DimensionKey key = entry.getKey();
        MetricTimeSeries metricTimeSeries = new MetricTimeSeries(metricSchema);
        result.put(key, metricTimeSeries);
        for (TimeSeriesRow timeSeriesRow : entry.getValue()) {
            long timestamp = timeSeriesRow.getStart();
            for (TimeSeriesMetric metric : timeSeriesRow.getMetrics()) {
                String metricName = metric.getMetricName();
                // contain additional info, eg the raw metrics required for calculating derived ones.
                if (metricSet.contains(metricName)) {
                    Double value = metric.getValue();
                    metricTimeSeries.increment(timestamp, metricName, value);
                }
            }
        }
    }
    return result;
}
Also used : MetricSchema(com.linkedin.thirdeye.api.MetricSchema) HashMap(java.util.HashMap) MetricType(com.linkedin.thirdeye.api.MetricType) ArrayList(java.util.ArrayList) MetricTimeSeries(com.linkedin.thirdeye.api.MetricTimeSeries) DimensionKey(com.linkedin.thirdeye.api.DimensionKey) TimeSeriesMetric(com.linkedin.thirdeye.client.timeseries.TimeSeriesRow.TimeSeriesMetric) Collection(java.util.Collection) HashSet(java.util.HashSet)

Example 8 with TimeSeriesMetric

use of com.linkedin.thirdeye.client.timeseries.TimeSeriesRow.TimeSeriesMetric in project pinot by linkedin.

the class DashboardResource method getTimeSeriesData.

@GET
@Path(value = "/data/timeseries")
@Produces(MediaType.APPLICATION_JSON)
public String getTimeSeriesData(@QueryParam("dataset") String collection, @QueryParam("filters") String filterJson, @QueryParam("timeZone") @DefaultValue(DEFAULT_TIMEZONE_ID) String timeZone, @QueryParam("currentStart") Long start, @QueryParam("currentEnd") Long end, @QueryParam("aggTimeGranularity") String aggTimeGranularity, @QueryParam("metrics") String metricsJson, @QueryParam("dimensions") String groupByDimensions) throws Exception {
    TimeSeriesRequest request = new TimeSeriesRequest();
    request.setCollectionName(collection);
    // See {@link #getDashboardData} for the reason that the start and end time are stored in a
    // DateTime object with data's timezone.
    DateTimeZone timeZoneForCollection = Utils.getDataTimeZone(collection);
    request.setStart(new DateTime(start, timeZoneForCollection));
    request.setEnd(new DateTime(end, timeZoneForCollection));
    if (groupByDimensions != null && !groupByDimensions.isEmpty()) {
        request.setGroupByDimensions(Arrays.asList(groupByDimensions.trim().split(",")));
    }
    if (filterJson != null && !filterJson.isEmpty()) {
        filterJson = URLDecoder.decode(filterJson, "UTF-8");
        request.setFilterSet(ThirdEyeUtils.convertToMultiMap(filterJson));
    }
    List<MetricExpression> metricExpressions = Utils.convertToMetricExpressions(metricsJson, MetricAggFunction.SUM, collection);
    request.setMetricExpressions(metricExpressions);
    request.setAggregationTimeGranularity(Utils.getAggregationTimeGranularity(aggTimeGranularity, collection));
    DatasetConfigDTO datasetConfig = CACHE_REGISTRY_INSTANCE.getDatasetConfigCache().get(collection);
    TimeSpec timespec = ThirdEyeUtils.getTimeSpecFromDatasetConfig(datasetConfig);
    if (!request.getAggregationTimeGranularity().getUnit().equals(TimeUnit.DAYS) || !StringUtils.isBlank(timespec.getFormat())) {
        request.setEndDateInclusive(true);
    }
    TimeSeriesHandler handler = new TimeSeriesHandler(queryCache);
    String jsonResponse = "";
    try {
        TimeSeriesResponse response = handler.handle(request);
        JSONObject timeseriesMap = new JSONObject();
        JSONArray timeValueArray = new JSONArray();
        TreeSet<String> keys = new TreeSet<>();
        TreeSet<Long> times = new TreeSet<>();
        for (int i = 0; i < response.getNumRows(); i++) {
            TimeSeriesRow timeSeriesRow = response.getRow(i);
            times.add(timeSeriesRow.getStart());
        }
        for (Long time : times) {
            timeValueArray.put(time);
        }
        timeseriesMap.put("time", timeValueArray);
        for (int i = 0; i < response.getNumRows(); i++) {
            TimeSeriesRow timeSeriesRow = response.getRow(i);
            for (TimeSeriesMetric metricTimeSeries : timeSeriesRow.getMetrics()) {
                String key = metricTimeSeries.getMetricName();
                if (timeSeriesRow.getDimensionNames() != null && timeSeriesRow.getDimensionNames().size() > 0) {
                    StringBuilder sb = new StringBuilder(key);
                    for (int idx = 0; idx < timeSeriesRow.getDimensionNames().size(); ++idx) {
                        sb.append("||").append(timeSeriesRow.getDimensionNames().get(idx));
                        sb.append("|").append(timeSeriesRow.getDimensionValues().get(idx));
                    }
                    key = sb.toString();
                }
                JSONArray valueArray;
                if (!timeseriesMap.has(key)) {
                    valueArray = new JSONArray();
                    timeseriesMap.put(key, valueArray);
                    keys.add(key);
                } else {
                    valueArray = timeseriesMap.getJSONArray(key);
                }
                valueArray.put(metricTimeSeries.getValue());
            }
        }
        JSONObject summaryMap = new JSONObject();
        summaryMap.put("currentStart", start);
        summaryMap.put("currentEnd", end);
        JSONObject jsonResponseObject = new JSONObject();
        jsonResponseObject.put("timeSeriesData", timeseriesMap);
        jsonResponseObject.put("keys", new JSONArray(keys));
        jsonResponseObject.put("summary", summaryMap);
        jsonResponse = jsonResponseObject.toString();
    } catch (Exception e) {
        throw e;
    }
    LOG.info("Response:{}", jsonResponse);
    return jsonResponse;
}
Also used : TimeSeriesRow(com.linkedin.thirdeye.client.timeseries.TimeSeriesRow) TimeSeriesResponse(com.linkedin.thirdeye.client.timeseries.TimeSeriesResponse) JSONArray(org.json.JSONArray) MetricExpression(com.linkedin.thirdeye.client.MetricExpression) DateTimeZone(org.joda.time.DateTimeZone) DateTime(org.joda.time.DateTime) JSONException(org.json.JSONException) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException) TimeSpec(com.linkedin.thirdeye.api.TimeSpec) DatasetConfigDTO(com.linkedin.thirdeye.datalayer.dto.DatasetConfigDTO) JSONObject(org.json.JSONObject) TimeSeriesHandler(com.linkedin.thirdeye.client.timeseries.TimeSeriesHandler) TreeSet(java.util.TreeSet) TimeSeriesMetric(com.linkedin.thirdeye.client.timeseries.TimeSeriesRow.TimeSeriesMetric) TimeSeriesRequest(com.linkedin.thirdeye.client.timeseries.TimeSeriesRequest) Path(javax.ws.rs.Path) Produces(javax.ws.rs.Produces) GET(javax.ws.rs.GET)

Aggregations

TimeSeriesMetric (com.linkedin.thirdeye.client.timeseries.TimeSeriesRow.TimeSeriesMetric)8 ArrayList (java.util.ArrayList)4 DateTime (org.joda.time.DateTime)4 MetricExpression (com.linkedin.thirdeye.client.MetricExpression)3 HashSet (java.util.HashSet)3 TimeSpec (com.linkedin.thirdeye.api.TimeSpec)2 MetricFunction (com.linkedin.thirdeye.client.MetricFunction)2 TimeSeriesHandler (com.linkedin.thirdeye.client.timeseries.TimeSeriesHandler)2 TimeSeriesRequest (com.linkedin.thirdeye.client.timeseries.TimeSeriesRequest)2 TimeSeriesResponse (com.linkedin.thirdeye.client.timeseries.TimeSeriesResponse)2 TimeSeriesRow (com.linkedin.thirdeye.client.timeseries.TimeSeriesRow)2 DatasetConfigDTO (com.linkedin.thirdeye.datalayer.dto.DatasetConfigDTO)2 IOException (java.io.IOException)2 HashMap (java.util.HashMap)2 TreeSet (java.util.TreeSet)2 ExecutionException (java.util.concurrent.ExecutionException)2 DateTimeZone (org.joda.time.DateTimeZone)2 JSONArray (org.json.JSONArray)2 JSONException (org.json.JSONException)2 JSONObject (org.json.JSONObject)2