Provide the getResponseTimeTrend query.
This commit is contained in:
parent
0ee4b1c30d
commit
4a933e1832
|
|
@ -19,7 +19,9 @@
|
|||
package org.apache.skywalking.apm.collector.storage.dao;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import java.util.List;
|
||||
import org.apache.skywalking.apm.collector.storage.base.dao.DAO;
|
||||
import org.apache.skywalking.apm.collector.storage.ui.common.Step;
|
||||
|
||||
/**
|
||||
* @author peng-yongsheng
|
||||
|
|
@ -33,7 +35,7 @@ public interface IInstanceMetricUIDAO extends DAO {
|
|||
|
||||
long getRespTimeMetric(int instanceId, long timeBucket);
|
||||
|
||||
JsonArray getRespTimeMetric(int instanceId, long startTimeBucket, long endTimeBucket);
|
||||
List<Integer> getResponseTimeTrend(int instanceId, Step step, Long[] timeBuckets);
|
||||
|
||||
class InstanceMetric {
|
||||
private final int instanceId;
|
||||
|
|
|
|||
|
|
@ -25,4 +25,12 @@ import java.util.List;
|
|||
*/
|
||||
public class ResponseTimeTrend {
|
||||
private List<Integer> trendList;
|
||||
|
||||
public List<Integer> getTrendList() {
|
||||
return trendList;
|
||||
}
|
||||
|
||||
public void setTrendList(List<Integer> trendList) {
|
||||
this.trendList = trendList;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,11 +19,16 @@
|
|||
package org.apache.skywalking.apm.collector.storage.es.dao;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import org.apache.skywalking.apm.collector.client.elasticsearch.ElasticSearchClient;
|
||||
import org.apache.skywalking.apm.collector.core.util.Const;
|
||||
import org.apache.skywalking.apm.collector.storage.dao.IInstanceMetricUIDAO;
|
||||
import org.apache.skywalking.apm.collector.storage.es.base.dao.EsDAO;
|
||||
import org.apache.skywalking.apm.collector.storage.table.MetricSource;
|
||||
import org.apache.skywalking.apm.collector.storage.table.instance.InstanceMetricTable;
|
||||
import org.apache.skywalking.apm.collector.storage.ui.common.Step;
|
||||
import org.apache.skywalking.apm.collector.storage.utils.TimePyramidTableNameBuilder;
|
||||
import org.elasticsearch.action.get.GetResponse;
|
||||
import org.elasticsearch.action.get.MultiGetItemResponse;
|
||||
import org.elasticsearch.action.get.MultiGetRequestBuilder;
|
||||
|
|
@ -113,30 +118,28 @@ public class InstanceMetricEsUIDAO extends EsDAO implements IInstanceMetricUIDAO
|
|||
return 0;
|
||||
}
|
||||
|
||||
@Override public JsonArray getRespTimeMetric(int instanceId, long startTimeBucket, long endTimeBucket) {
|
||||
@Override public List<Integer> getResponseTimeTrend(int instanceId, Step step, Long[] timeBuckets) {
|
||||
MultiGetRequestBuilder prepareMultiGet = getClient().prepareMultiGet();
|
||||
String tableName = TimePyramidTableNameBuilder.build(step, InstanceMetricTable.TABLE);
|
||||
|
||||
int i = 0;
|
||||
long timeBucket = 0;
|
||||
do {
|
||||
// timeBucket = TimeBucketUtils.INSTANCE.addSecondForSecondTimeBucket(TimeBucketUtils.TimeBucketType.SECOND, startTimeBucket, i);
|
||||
String id = timeBucket + Const.ID_SPLIT + instanceId;
|
||||
prepareMultiGet.add(InstanceMetricTable.TABLE, InstanceMetricTable.TABLE_TYPE, id);
|
||||
i++;
|
||||
for (long timeBucket : timeBuckets) {
|
||||
String id = timeBucket + Const.ID_SPLIT + instanceId + Const.ID_SPLIT + MetricSource.Callee.getValue();
|
||||
prepareMultiGet.add(tableName, InstanceMetricTable.TABLE_TYPE, id);
|
||||
}
|
||||
while (timeBucket <= endTimeBucket);
|
||||
|
||||
JsonArray metrics = new JsonArray();
|
||||
List<Integer> responseTimeTrends = new LinkedList<>();
|
||||
MultiGetResponse multiGetResponse = prepareMultiGet.get();
|
||||
for (MultiGetItemResponse response : multiGetResponse.getResponses()) {
|
||||
if (response.getResponse().isExists()) {
|
||||
long callTimes = ((Number)response.getResponse().getSource().get(InstanceMetricTable.COLUMN_TRANSACTION_CALLS)).longValue();
|
||||
long costTotal = ((Number)response.getResponse().getSource().get(InstanceMetricTable.COLUMN_TRANSACTION_DURATION_SUM)).longValue();
|
||||
metrics.add(costTotal / callTimes);
|
||||
long errorCallTimes = ((Number)response.getResponse().getSource().get(InstanceMetricTable.COLUMN_TRANSACTION_ERROR_CALLS)).longValue();
|
||||
long durationSum = ((Number)response.getResponse().getSource().get(InstanceMetricTable.COLUMN_TRANSACTION_DURATION_SUM)).longValue();
|
||||
long errorDurationSum = ((Number)response.getResponse().getSource().get(InstanceMetricTable.COLUMN_BUSINESS_TRANSACTION_ERROR_DURATION_SUM)).longValue();
|
||||
responseTimeTrends.add((int)((durationSum - errorDurationSum) / (callTimes - errorCallTimes)));
|
||||
} else {
|
||||
metrics.add(0);
|
||||
responseTimeTrends.add(0);
|
||||
}
|
||||
}
|
||||
return metrics;
|
||||
return responseTimeTrends;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import com.google.gson.JsonArray;
|
|||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import org.apache.skywalking.apm.collector.client.h2.H2Client;
|
||||
import org.apache.skywalking.apm.collector.client.h2.H2ClientException;
|
||||
|
|
@ -29,7 +30,10 @@ import org.apache.skywalking.apm.collector.core.util.Const;
|
|||
import org.apache.skywalking.apm.collector.storage.base.sql.SqlBuilder;
|
||||
import org.apache.skywalking.apm.collector.storage.dao.IInstanceMetricUIDAO;
|
||||
import org.apache.skywalking.apm.collector.storage.h2.base.dao.H2DAO;
|
||||
import org.apache.skywalking.apm.collector.storage.table.MetricSource;
|
||||
import org.apache.skywalking.apm.collector.storage.table.instance.InstanceMetricTable;
|
||||
import org.apache.skywalking.apm.collector.storage.ui.common.Step;
|
||||
import org.apache.skywalking.apm.collector.storage.utils.TimePyramidTableNameBuilder;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
|
@ -135,33 +139,29 @@ public class InstanceMetricH2UIDAO extends H2DAO implements IInstanceMetricUIDAO
|
|||
return 0;
|
||||
}
|
||||
|
||||
@Override public JsonArray getRespTimeMetric(int instanceId, long startTimeBucket, long endTimeBucket) {
|
||||
@Override public List<Integer> getResponseTimeTrend(int instanceId, Step step, Long[] timeBuckets) {
|
||||
H2Client client = getClient();
|
||||
String sql = SqlBuilder.buildSql(GET_TPS_METRIC_SQL, InstanceMetricTable.TABLE, InstanceMetricTable.COLUMN_ID);
|
||||
|
||||
long timeBucket = startTimeBucket;
|
||||
List<String> idList = new ArrayList<>();
|
||||
do {
|
||||
String id = timeBucket + Const.ID_SPLIT + instanceId;
|
||||
// timeBucket = TimeBucketUtils.INSTANCE.addSecondForSecondTimeBucket(TimeBucketUtils.TimeBucketType.SECOND, timeBucket, 1);
|
||||
idList.add(id);
|
||||
}
|
||||
while (timeBucket <= endTimeBucket);
|
||||
String tableName = TimePyramidTableNameBuilder.build(step, InstanceMetricTable.TABLE);
|
||||
String sql = SqlBuilder.buildSql(GET_TPS_METRIC_SQL, tableName, InstanceMetricTable.COLUMN_ID);
|
||||
|
||||
JsonArray metrics = new JsonArray();
|
||||
idList.forEach(id -> {
|
||||
List<Integer> responseTimeTrends = new LinkedList<>();
|
||||
for (long timeBucket : timeBuckets) {
|
||||
String id = timeBucket + Const.ID_SPLIT + instanceId + Const.ID_SPLIT + MetricSource.Callee.getValue();
|
||||
try (ResultSet rs = client.executeQuery(sql, new Object[] {id})) {
|
||||
if (rs.next()) {
|
||||
long callTimes = rs.getLong(InstanceMetricTable.COLUMN_TRANSACTION_CALLS);
|
||||
long costTotal = rs.getLong(InstanceMetricTable.COLUMN_TRANSACTION_DURATION_SUM);
|
||||
metrics.add(costTotal / callTimes);
|
||||
long errorCallTimes = rs.getLong(InstanceMetricTable.COLUMN_TRANSACTION_ERROR_CALLS);
|
||||
long durationSum = rs.getLong(InstanceMetricTable.COLUMN_TRANSACTION_DURATION_SUM);
|
||||
long errorDurationSum = rs.getLong(InstanceMetricTable.COLUMN_BUSINESS_TRANSACTION_ERROR_DURATION_SUM);
|
||||
responseTimeTrends.add((int)((durationSum - errorDurationSum) / (callTimes - errorCallTimes)));
|
||||
} else {
|
||||
metrics.add(0);
|
||||
responseTimeTrends.add(0);
|
||||
}
|
||||
} catch (SQLException | H2ClientException e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
}
|
||||
});
|
||||
return metrics;
|
||||
}
|
||||
return responseTimeTrends;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,8 +64,10 @@ public class ServerQuery implements Query {
|
|||
return getServerService().getAllServer(applicationId, start, end);
|
||||
}
|
||||
|
||||
public ResponseTimeTrend getServerResponseTimeTrend(int serverId, Duration duration) {
|
||||
return null;
|
||||
public ResponseTimeTrend getServerResponseTimeTrend(int serverId, Duration duration) throws ParseException {
|
||||
long start = DurationUtils.INSTANCE.exchangeToTimeBucket(duration.getStart());
|
||||
long end = DurationUtils.INSTANCE.exchangeToTimeBucket(duration.getEnd());
|
||||
return getServerService().getServerResponseTimeTrend(serverId, duration.getStep(), start, end);
|
||||
}
|
||||
|
||||
public ThroughputTrend getServerTPSTrend(int serverId, Duration duration) {
|
||||
|
|
|
|||
|
|
@ -114,7 +114,6 @@ public class InstanceJVMService {
|
|||
} else if (metricType.toLowerCase().equals(MetricType.tps.name())) {
|
||||
metrics.add(MetricType.tps.name(), instanceMetricUIDAO.getTpsMetric(instanceId, startTimeBucket, endTimeBucket));
|
||||
} else if (metricType.toLowerCase().equals(MetricType.resptime.name())) {
|
||||
metrics.add(MetricType.resptime.name(), instanceMetricUIDAO.getRespTimeMetric(instanceId, startTimeBucket, endTimeBucket));
|
||||
} else if (metricType.toLowerCase().equals(MetricType.heapmemory.name())) {
|
||||
metrics.add(MetricType.heapmemory.name(), memoryMetricDAO.getMetric(instanceId, startTimeBucket, endTimeBucket, true));
|
||||
} else if (metricType.toLowerCase().equals(MetricType.nonheapmemory.name())) {
|
||||
|
|
|
|||
|
|
@ -21,14 +21,19 @@ package org.apache.skywalking.apm.collector.ui.service;
|
|||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
import java.text.ParseException;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import org.apache.skywalking.apm.collector.core.module.ModuleManager;
|
||||
import org.apache.skywalking.apm.collector.core.util.Const;
|
||||
import org.apache.skywalking.apm.collector.core.util.StringUtils;
|
||||
import org.apache.skywalking.apm.collector.storage.StorageModule;
|
||||
import org.apache.skywalking.apm.collector.storage.dao.IInstanceMetricUIDAO;
|
||||
import org.apache.skywalking.apm.collector.storage.dao.IInstanceUIDAO;
|
||||
import org.apache.skywalking.apm.collector.storage.ui.common.ResponseTimeTrend;
|
||||
import org.apache.skywalking.apm.collector.storage.ui.common.Step;
|
||||
import org.apache.skywalking.apm.collector.storage.ui.server.AppServerInfo;
|
||||
import org.apache.skywalking.apm.collector.ui.utils.DurationUtils;
|
||||
|
||||
/**
|
||||
* @author peng-yongsheng
|
||||
|
|
@ -37,9 +42,11 @@ public class ServerService {
|
|||
|
||||
private final Gson gson = new Gson();
|
||||
private final IInstanceUIDAO instanceDAO;
|
||||
private final IInstanceMetricUIDAO instanceMetricUIDAO;
|
||||
|
||||
public ServerService(ModuleManager moduleManager) {
|
||||
this.instanceDAO = moduleManager.find(StorageModule.NAME).getService(IInstanceUIDAO.class);
|
||||
this.instanceMetricUIDAO = moduleManager.find(StorageModule.NAME).getService(IInstanceMetricUIDAO.class);
|
||||
}
|
||||
|
||||
public List<AppServerInfo> searchServer(String keyword, long start, long end) {
|
||||
|
|
@ -49,7 +56,7 @@ public class ServerService {
|
|||
serverInfos.remove(serverInfo);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
buildAppServerInfo(serverInfos);
|
||||
return serverInfos;
|
||||
}
|
||||
|
|
@ -60,6 +67,15 @@ public class ServerService {
|
|||
return serverInfos;
|
||||
}
|
||||
|
||||
public ResponseTimeTrend getServerResponseTimeTrend(int instanceId, Step step, long start,
|
||||
long end) throws ParseException {
|
||||
ResponseTimeTrend responseTimeTrend = new ResponseTimeTrend();
|
||||
Long[] timeBuckets = DurationUtils.INSTANCE.getDurationPoints(step, start, end);
|
||||
List<Integer> trends = instanceMetricUIDAO.getResponseTimeTrend(instanceId, step, timeBuckets);
|
||||
responseTimeTrend.setTrendList(trends);
|
||||
return responseTimeTrend;
|
||||
}
|
||||
|
||||
private void buildAppServerInfo(List<AppServerInfo> serverInfos) {
|
||||
serverInfos.forEach(serverInfo -> {
|
||||
if (StringUtils.isNotEmpty(serverInfo.getOsInfo())) {
|
||||
|
|
|
|||
|
|
@ -20,6 +20,9 @@ package org.apache.skywalking.apm.collector.ui.utils;
|
|||
|
||||
import java.text.ParseException;
|
||||
import java.util.Date;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import org.apache.skywalking.apm.collector.core.UnexpectedException;
|
||||
import org.apache.skywalking.apm.collector.core.util.Const;
|
||||
import org.apache.skywalking.apm.collector.core.util.TimeBucketUtils;
|
||||
import org.apache.skywalking.apm.collector.storage.ui.common.Step;
|
||||
|
|
@ -88,4 +91,78 @@ public enum DurationUtils {
|
|||
|
||||
return Seconds.secondsBetween(new DateTime(startDate), new DateTime(endDate)).getSeconds();
|
||||
}
|
||||
|
||||
public DateTime parseToDateTime(Step step, long time) throws ParseException {
|
||||
DateTime dateTime = null;
|
||||
|
||||
switch (step) {
|
||||
case MONTH:
|
||||
Date date = TimeBucketUtils.MONTH_DATE_FORMAT.parse(String.valueOf(time));
|
||||
dateTime = new DateTime(date);
|
||||
break;
|
||||
case DAY:
|
||||
date = TimeBucketUtils.DAY_DATE_FORMAT.parse(String.valueOf(time));
|
||||
dateTime = new DateTime(date);
|
||||
break;
|
||||
case HOUR:
|
||||
date = TimeBucketUtils.HOUR_DATE_FORMAT.parse(String.valueOf(time));
|
||||
dateTime = new DateTime(date);
|
||||
break;
|
||||
case MINUTE:
|
||||
date = TimeBucketUtils.MINUTE_DATE_FORMAT.parse(String.valueOf(time));
|
||||
dateTime = new DateTime(date);
|
||||
break;
|
||||
case SECOND:
|
||||
date = TimeBucketUtils.SECOND_DATE_FORMAT.parse(String.valueOf(time));
|
||||
dateTime = new DateTime(date);
|
||||
break;
|
||||
}
|
||||
|
||||
return dateTime;
|
||||
}
|
||||
|
||||
public Long[] getDurationPoints(Step step, long start, long end) throws ParseException {
|
||||
DateTime dateTime = parseToDateTime(step, start);
|
||||
|
||||
List<Long> durations = new LinkedList<>();
|
||||
durations.add(start);
|
||||
|
||||
int i = 0;
|
||||
do {
|
||||
switch (step) {
|
||||
case MONTH:
|
||||
dateTime = dateTime.plusMonths(1);
|
||||
String timeBucket = TimeBucketUtils.MONTH_DATE_FORMAT.format(dateTime.toDate());
|
||||
durations.add(Long.valueOf(timeBucket));
|
||||
break;
|
||||
case DAY:
|
||||
dateTime = dateTime.plusDays(1);
|
||||
timeBucket = TimeBucketUtils.DAY_DATE_FORMAT.format(dateTime.toDate());
|
||||
durations.add(Long.valueOf(timeBucket));
|
||||
break;
|
||||
case HOUR:
|
||||
dateTime = dateTime.plusHours(1);
|
||||
timeBucket = TimeBucketUtils.HOUR_DATE_FORMAT.format(dateTime.toDate());
|
||||
durations.add(Long.valueOf(timeBucket));
|
||||
break;
|
||||
case MINUTE:
|
||||
dateTime = dateTime.plusMinutes(1);
|
||||
timeBucket = TimeBucketUtils.MINUTE_DATE_FORMAT.format(dateTime.toDate());
|
||||
durations.add(Long.valueOf(timeBucket));
|
||||
break;
|
||||
case SECOND:
|
||||
dateTime = dateTime.plusSeconds(1);
|
||||
timeBucket = TimeBucketUtils.SECOND_DATE_FORMAT.format(dateTime.toDate());
|
||||
durations.add(Long.valueOf(timeBucket));
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
if (i > 500) {
|
||||
throw new UnexpectedException("Duration data error, step: " + step.name() + ", start: " + start + ", end: " + end);
|
||||
}
|
||||
}
|
||||
while (end != durations.get(durations.size() - 1));
|
||||
|
||||
return durations.toArray(new Long[durations.size()]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.apm.collector.ui.utils;
|
||||
|
||||
import java.text.ParseException;
|
||||
import org.apache.skywalking.apm.collector.core.UnexpectedException;
|
||||
import org.apache.skywalking.apm.collector.storage.ui.common.Step;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* @author peng-yongsheng
|
||||
*/
|
||||
public class DurationUtilsTestCase {
|
||||
|
||||
@Test
|
||||
public void test() throws ParseException {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetDurationPoints() throws ParseException {
|
||||
Long[] durationPoints = DurationUtils.INSTANCE.getDurationPoints(Step.MONTH, 201710, 201803);
|
||||
Assert.assertArrayEquals(new Long[] {201710L, 201711L, 201712L, 201801L, 201802L, 201803L}, durationPoints);
|
||||
|
||||
durationPoints = DurationUtils.INSTANCE.getDurationPoints(Step.DAY, 20180129, 20180202);
|
||||
Assert.assertArrayEquals(new Long[] {20180129L, 20180130L, 20180131L, 20180201L, 20180202L}, durationPoints);
|
||||
|
||||
durationPoints = DurationUtils.INSTANCE.getDurationPoints(Step.HOUR, 2018012922, 2018013002);
|
||||
Assert.assertArrayEquals(new Long[] {2018012922L, 2018012923L, 2018013000L, 2018013001L, 2018013002L}, durationPoints);
|
||||
|
||||
durationPoints = DurationUtils.INSTANCE.getDurationPoints(Step.MINUTE, 201801292258L, 201801292302L);
|
||||
Assert.assertArrayEquals(new Long[] {201801292258L, 201801292259L, 201801292300L, 201801292301L, 201801292302L}, durationPoints);
|
||||
|
||||
durationPoints = DurationUtils.INSTANCE.getDurationPoints(Step.SECOND, 20180129225858L, 20180129225902L);
|
||||
Assert.assertArrayEquals(new Long[] {20180129225858L, 20180129225859L, 20180129225900L, 20180129225901L, 20180129225902L}, durationPoints);
|
||||
}
|
||||
|
||||
@Test(expected = UnexpectedException.class)
|
||||
public void testGetDurationPointsErrorDuration() throws ParseException {
|
||||
DurationUtils.INSTANCE.getDurationPoints(Step.MONTH, 20171001, 20180301);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue