use of com.linkedin.thirdeye.client.MetricExpression in project pinot by linkedin.
the class EmailHelper method getData.
/**
* Generate and send request to retrieve chart data. If the request window is too small, the graph
* data retrieved has default window sizes based on time granularity and ending at the defined
* endpoint: <br/> <ul> <li>DAYS: 7</li> <li>HOURS: 24</li> </ul>
*
* @param bucketGranularity
*
* @throws JobExecutionException
*/
public static TimeOnTimeComparisonResponse getData(TimeOnTimeComparisonHandler timeOnTimeComparisonHandler, EmailConfigurationDTO config, DateTime start, final DateTime end, long baselinePeriodMillis, TimeGranularity bucketGranularity) throws JobExecutionException {
start = calculateGraphDataStart(start, end, bucketGranularity);
try {
TimeOnTimeComparisonRequest comparisonRequest = new TimeOnTimeComparisonRequest();
comparisonRequest.setCollectionName(config.getCollection());
comparisonRequest.setBaselineStart(start.minus(baselinePeriodMillis));
comparisonRequest.setBaselineEnd(end.minus(baselinePeriodMillis));
comparisonRequest.setCurrentStart(start);
comparisonRequest.setCurrentEnd(end);
comparisonRequest.setEndDateInclusive(true);
List<MetricExpression> metricExpressions = new ArrayList<>();
MetricExpression expression = new MetricExpression(config.getMetric());
metricExpressions.add(expression);
comparisonRequest.setMetricExpressions(metricExpressions);
comparisonRequest.setAggregationTimeGranularity(bucketGranularity);
LOG.debug("Starting...");
TimeOnTimeComparisonResponse response = timeOnTimeComparisonHandler.handle(comparisonRequest);
LOG.debug("Done!");
return response;
} catch (Exception e) {
throw new JobExecutionException(e);
}
}
use of com.linkedin.thirdeye.client.MetricExpression in project pinot by linkedin.
the class TimeOnTimeComparisonHandler method computeDerivedMetrics.
private void computeDerivedMetrics(TimeOnTimeComparisonRequest comparisonRequest, List<Row> rows) throws Exception {
// compute list of derived expressions
List<MetricFunction> metricFunctionsFromExpressions = Utils.computeMetricFunctionsFromExpressions(comparisonRequest.getMetricExpressions());
Set<String> metricNameSet = new HashSet<>();
for (MetricFunction function : metricFunctionsFromExpressions) {
metricNameSet.add(function.getMetricName());
}
List<MetricExpression> derivedMetricExpressions = new ArrayList<>();
for (MetricExpression expression : comparisonRequest.getMetricExpressions()) {
if (!metricNameSet.contains(expression.getExpressionName())) {
derivedMetricExpressions.add(expression);
}
}
// add metric expressions
if (derivedMetricExpressions.size() > 0) {
Map<String, Double> baselineValueContext = new HashMap<>();
Map<String, Double> currentValueContext = new HashMap<>();
for (Row row : rows) {
baselineValueContext.clear();
currentValueContext.clear();
List<Metric> metrics = row.getMetrics();
// baseline value
for (Metric metric : metrics) {
baselineValueContext.put(metric.getMetricName(), metric.getBaselineValue());
currentValueContext.put(metric.getMetricName(), metric.getCurrentValue());
}
for (MetricExpression expression : derivedMetricExpressions) {
String derivedMetricExpression = expression.getExpression();
double derivedMetricBaselineValue = MetricExpression.evaluateExpression(derivedMetricExpression, baselineValueContext);
if (Double.isInfinite(derivedMetricBaselineValue) || Double.isNaN(derivedMetricBaselineValue)) {
derivedMetricBaselineValue = 0;
}
double currentMetricBaselineValue = MetricExpression.evaluateExpression(derivedMetricExpression, currentValueContext);
if (Double.isInfinite(currentMetricBaselineValue) || Double.isNaN(currentMetricBaselineValue)) {
currentMetricBaselineValue = 0;
}
row.getMetrics().add(new Metric(expression.getExpressionName(), derivedMetricBaselineValue, currentMetricBaselineValue));
}
}
}
}
use of com.linkedin.thirdeye.client.MetricExpression in project pinot by linkedin.
the class AnomaliesResource method getTimeSeriesData.
/**
* Get timeseries for metric
* @param collection
* @param filters
* @param start
* @param end
* @param aggTimeGranularity
* @param metric
* @return
* @throws Exception
*/
private JSONObject getTimeSeriesData(String collection, Multimap<String, String> filters, Long start, Long end, String aggTimeGranularity, String metric) throws Exception {
TimeSeriesRequest request = new TimeSeriesRequest();
request.setCollectionName(collection);
DateTimeZone timeZoneForCollection = Utils.getDataTimeZone(collection);
request.setStart(new DateTime(start, timeZoneForCollection));
request.setEnd(new DateTime(end, timeZoneForCollection));
request.setFilterSet(filters);
List<MetricExpression> metricExpressions = Utils.convertToMetricExpressions(metric, MetricAggFunction.SUM, collection);
request.setMetricExpressions(metricExpressions);
request.setAggregationTimeGranularity(Utils.getAggregationTimeGranularity(aggTimeGranularity, collection));
DatasetConfigDTO datasetConfig = CACHE_REGISTRY.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(CACHE_REGISTRY.getQueryCache());
JSONObject jsonResponseObject = new JSONObject();
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();
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);
jsonResponseObject.put("timeSeriesData", timeseriesMap);
jsonResponseObject.put("keys", new JSONArray(keys));
jsonResponseObject.put("summary", summaryMap);
} catch (Exception e) {
throw e;
}
LOG.info("Response:{}", jsonResponseObject);
return jsonResponseObject;
}
use of com.linkedin.thirdeye.client.MetricExpression in project pinot by linkedin.
the class Utils method convertToMetricExpressions.
public static List<MetricExpression> convertToMetricExpressions(String metricsJson, MetricAggFunction aggFunction, String collection) throws ExecutionException {
List<MetricExpression> metricExpressions = new ArrayList<>();
if (metricsJson == null) {
return metricExpressions;
}
ArrayList<String> metricExpressionNames;
try {
TypeReference<ArrayList<String>> valueTypeRef = new TypeReference<ArrayList<String>>() {
};
metricExpressionNames = OBJECT_MAPPER.readValue(metricsJson, valueTypeRef);
} catch (Exception e) {
LOG.warn("Expected json expression for metric [{}], adding as it is. Error in json parsing : [{}]", metricsJson, e.getMessage());
metricExpressionNames = new ArrayList<>();
String[] metrics = metricsJson.split(",");
for (String metric : metrics) {
metricExpressionNames.add(metric.trim());
}
}
for (String metricExpressionName : metricExpressionNames) {
String derivedMetricExpression = ThirdEyeUtils.getDerivedMetricExpression(metricExpressionName, collection);
MetricExpression metricExpression = new MetricExpression(metricExpressionName, derivedMetricExpression, aggFunction);
metricExpressions.add(metricExpression);
}
return metricExpressions;
}
use of com.linkedin.thirdeye.client.MetricExpression in project pinot by linkedin.
the class DashboardResource method getDashboardData.
@GET
@Path(value = "/data/customDashboard")
@Produces(MediaType.APPLICATION_JSON)
public String getDashboardData(@QueryParam("dataset") String collection, @QueryParam("dashboard") String dashboardName, @QueryParam("filters") String filterJson, @QueryParam("timeZone") @DefaultValue(DEFAULT_TIMEZONE_ID) String timeZone, @QueryParam("baselineStart") Long baselineStart, @QueryParam("baselineEnd") Long baselineEnd, @QueryParam("currentStart") Long currentStart, @QueryParam("currentEnd") Long currentEnd, @QueryParam("compareMode") String compareMode, @QueryParam("aggTimeGranularity") String aggTimeGranularity) {
try {
TabularViewRequest request = new TabularViewRequest();
request.setCollection(collection);
List<MetricExpression> metricExpressions = new ArrayList<>();
DashboardConfigDTO dashboardConfig = dashboardConfigDAO.findByName(dashboardName);
List<Long> metricIds = dashboardConfig.getMetricIds();
for (Long metricId : metricIds) {
MetricConfigDTO metricConfig = metricConfigDAO.findById(metricId);
MetricExpression metricExpression = ThirdEyeUtils.getMetricExpressionFromMetricConfig(metricConfig);
metricExpressions.add(metricExpression);
}
request.setMetricExpressions(metricExpressions);
long maxDataTime = collectionMaxDataTimeCache.get(collection);
if (currentEnd > maxDataTime) {
long delta = currentEnd - maxDataTime;
currentEnd = currentEnd - delta;
baselineEnd = baselineEnd - delta;
}
// The input start and end time (i.e., currentStart, currentEnd, baselineStart, and
// baselineEnd) are given in millisecond since epoch, which is timezone insensitive. On the
// other hand, the start and end time of the request to be sent to backend database (e.g.,
// Pinot) could be converted to SimpleDateFormat, which is timezone sensitive. Therefore,
// we need to store user's start and end time in DateTime objects with data's timezone
// in order to ensure that the conversion to SimpleDateFormat is always correct regardless
// user and server's timezone, including daylight saving time.
DateTimeZone timeZoneForCollection = Utils.getDataTimeZone(collection);
request.setBaselineStart(new DateTime(baselineStart, timeZoneForCollection));
request.setBaselineEnd(new DateTime(baselineEnd, timeZoneForCollection));
request.setCurrentStart(new DateTime(currentStart, timeZoneForCollection));
request.setCurrentEnd(new DateTime(currentEnd, timeZoneForCollection));
if (filterJson != null && !filterJson.isEmpty()) {
filterJson = URLDecoder.decode(filterJson, "UTF-8");
request.setFilters(ThirdEyeUtils.convertToMultiMap(filterJson));
}
request.setTimeGranularity(Utils.getAggregationTimeGranularity(aggTimeGranularity, collection));
TabularViewHandler handler = new TabularViewHandler(queryCache);
String jsonResponse = null;
TabularViewResponse response = handler.process(request);
jsonResponse = OBJECT_MAPPER.enable(SerializationFeature.INDENT_OUTPUT).writeValueAsString(response);
LOG.debug("customDashboard response {}", jsonResponse);
return jsonResponse;
} catch (Exception e) {
LOG.error("Exception while processing /data/tabular call", e);
return "{\"ERROR\": + " + e.getMessage() + "}";
}
}
Aggregations