Provide the getGCTrend query.

This commit is contained in:
peng-yongsheng 2018-01-31 21:32:21 +08:00
parent 8585e42c86
commit 06d5b88ee1
7 changed files with 83 additions and 238 deletions

View File

@ -18,47 +18,16 @@
package org.apache.skywalking.apm.collector.storage.dao;
import com.google.gson.JsonObject;
import java.util.List;
import org.apache.skywalking.apm.collector.storage.base.dao.DAO;
import org.apache.skywalking.apm.collector.storage.ui.common.Step;
import org.apache.skywalking.apm.collector.storage.utils.DurationPoint;
/**
* @author peng-yongsheng
*/
public interface IGCMetricUIDAO extends DAO {
List<Integer> getYoungGCTrend(int instanceId, Step step, List<DurationPoint> durationPoints);
GCCount getGCCount(long[] timeBuckets, int instanceId);
JsonObject getMetric(int instanceId, long timeBucket);
JsonObject getMetric(int instanceId, long startTimeBucket, long endTimeBucket);
class GCCount {
private int young;
private int old;
private int full;
public int getYoung() {
return young;
}
public int getOld() {
return old;
}
public int getFull() {
return full;
}
public void setYoung(int young) {
this.young = young;
}
public void setOld(int old) {
this.old = old;
}
public void setFull(int full) {
this.full = full;
}
}
List<Integer> getOldGCTrend(int instanceId, Step step, List<DurationPoint> durationPoints);
}

View File

@ -26,4 +26,20 @@ import java.util.List;
public class GCTrend {
private List<Integer> youngGC;
private List<Integer> oldGC;
public List<Integer> getYoungGC() {
return youngGC;
}
public void setYoungGC(List<Integer> youngGC) {
this.youngGC = youngGC;
}
public List<Integer> getOldGC() {
return oldGC;
}
public void setOldGC(List<Integer> oldGC) {
this.oldGC = oldGC;
}
}

View File

@ -18,137 +18,59 @@
package org.apache.skywalking.apm.collector.storage.es.dao;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
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.IGCMetricUIDAO;
import org.apache.skywalking.apm.collector.storage.es.base.dao.EsDAO;
import org.apache.skywalking.apm.collector.storage.table.jvm.GCMetricTable;
import org.apache.skywalking.apm.collector.storage.ui.common.Step;
import org.apache.skywalking.apm.collector.storage.utils.DurationPoint;
import org.apache.skywalking.apm.collector.storage.utils.TimePyramidTableNameBuilder;
import org.apache.skywalking.apm.network.proto.GCPhrase;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.get.MultiGetItemResponse;
import org.elasticsearch.action.get.MultiGetRequestBuilder;
import org.elasticsearch.action.get.MultiGetResponse;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.SearchType;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.metrics.sum.Sum;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author peng-yongsheng
*/
public class GCMetricEsUIDAO extends EsDAO implements IGCMetricUIDAO {
private final Logger logger = LoggerFactory.getLogger(GCMetricEsUIDAO.class);
public GCMetricEsUIDAO(ElasticSearchClient client) {
super(client);
}
@Override public GCCount getGCCount(long[] timeBuckets, int instanceId) {
logger.debug("get gc count, timeBuckets: {}, instanceId: {}", timeBuckets, instanceId);
SearchRequestBuilder searchRequestBuilder = getClient().prepareSearch(GCMetricTable.TABLE);
searchRequestBuilder.setTypes(GCMetricTable.TABLE_TYPE);
searchRequestBuilder.setSearchType(SearchType.DFS_QUERY_THEN_FETCH);
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
boolQuery.must().add(QueryBuilders.termQuery(GCMetricTable.COLUMN_INSTANCE_ID, instanceId));
boolQuery.must().add(QueryBuilders.termsQuery(GCMetricTable.COLUMN_TIME_BUCKET, timeBuckets));
searchRequestBuilder.setQuery(boolQuery);
searchRequestBuilder.setSize(0);
searchRequestBuilder.addAggregation(
AggregationBuilders.terms(GCMetricTable.COLUMN_PHRASE).field(GCMetricTable.COLUMN_PHRASE)
.subAggregation(AggregationBuilders.sum(GCMetricTable.COLUMN_COUNT).field(GCMetricTable.COLUMN_COUNT)));
SearchResponse searchResponse = searchRequestBuilder.execute().actionGet();
GCCount gcCount = new GCCount();
Terms phraseAggregation = searchResponse.getAggregations().get(GCMetricTable.COLUMN_PHRASE);
for (Terms.Bucket phraseBucket : phraseAggregation.getBuckets()) {
int phrase = phraseBucket.getKeyAsNumber().intValue();
Sum sumAggregation = phraseBucket.getAggregations().get(GCMetricTable.COLUMN_COUNT);
int count = (int)sumAggregation.getValue();
if (phrase == GCPhrase.NEW_VALUE) {
gcCount.setYoung(count);
} else if (phrase == GCPhrase.OLD_VALUE) {
gcCount.setOld(count);
}
}
return gcCount;
@Override public List<Integer> getYoungGCTrend(int instanceId, Step step, List<DurationPoint> durationPoints) {
return getGCTrend(instanceId, step, durationPoints, GCPhrase.NEW_VALUE);
}
@Override public JsonObject getMetric(int instanceId, long timeBucket) {
JsonObject response = new JsonObject();
String youngId = timeBucket + Const.ID_SPLIT + GCPhrase.NEW_VALUE + instanceId;
GetResponse youngResponse = getClient().prepareGet(GCMetricTable.TABLE, youngId).get();
if (youngResponse.isExists()) {
response.addProperty("ygc", ((Number)youngResponse.getSource().get(GCMetricTable.COLUMN_COUNT)).intValue());
}
String oldId = timeBucket + Const.ID_SPLIT + GCPhrase.OLD_VALUE + instanceId;
GetResponse oldResponse = getClient().prepareGet(GCMetricTable.TABLE, oldId).get();
if (oldResponse.isExists()) {
response.addProperty("ogc", ((Number)oldResponse.getSource().get(GCMetricTable.COLUMN_COUNT)).intValue());
}
return response;
@Override public List<Integer> getOldGCTrend(int instanceId, Step step, List<DurationPoint> durationPoints) {
return getGCTrend(instanceId, step, durationPoints, GCPhrase.OLD_VALUE);
}
@Override public JsonObject getMetric(int instanceId, long startTimeBucket, long endTimeBucket) {
JsonObject response = new JsonObject();
private List<Integer> getGCTrend(int instanceId, Step step, List<DurationPoint> durationPoints, int gcPhrase) {
String tableName = TimePyramidTableNameBuilder.build(step, GCMetricTable.TABLE);
MultiGetRequestBuilder youngPrepareMultiGet = getClient().prepareMultiGet();
long timeBucket = startTimeBucket;
do {
// timeBucket = TimeBucketUtils.INSTANCE.addSecondForSecondTimeBucket(TimeBucketUtils.TimeBucketType.SECOND, timeBucket, 1);
String youngId = timeBucket + Const.ID_SPLIT + instanceId + Const.ID_SPLIT + GCPhrase.NEW_VALUE;
youngPrepareMultiGet.add(GCMetricTable.TABLE, GCMetricTable.TABLE_TYPE, youngId);
}
while (timeBucket <= endTimeBucket);
durationPoints.forEach(durationPoint -> {
String id = durationPoint.getPoint() + Const.ID_SPLIT + instanceId + Const.ID_SPLIT + gcPhrase;
youngPrepareMultiGet.add(tableName, GCMetricTable.TABLE_TYPE, id);
});
JsonArray youngArray = new JsonArray();
List<Integer> gcTrends = new LinkedList<>();
MultiGetResponse multiGetResponse = youngPrepareMultiGet.get();
for (MultiGetItemResponse itemResponse : multiGetResponse.getResponses()) {
if (itemResponse.getResponse().isExists()) {
youngArray.add(((Number)itemResponse.getResponse().getSource().get(GCMetricTable.COLUMN_COUNT)).intValue());
long count = ((Number)itemResponse.getResponse().getSource().get(GCMetricTable.COLUMN_COUNT)).longValue();
long times = ((Number)itemResponse.getResponse().getSource().get(GCMetricTable.COLUMN_TIMES)).intValue();
gcTrends.add((int)(count / times));
} else {
youngArray.add(0);
gcTrends.add(0);
}
}
response.add("ygc", youngArray);
MultiGetRequestBuilder oldPrepareMultiGet = getClient().prepareMultiGet();
timeBucket = startTimeBucket;
do {
// timeBucket = TimeBucketUtils.INSTANCE.addSecondForSecondTimeBucket(TimeBucketUtils.TimeBucketType.SECOND, timeBucket, 1);
String oldId = timeBucket + Const.ID_SPLIT + instanceId + Const.ID_SPLIT + GCPhrase.OLD_VALUE;
oldPrepareMultiGet.add(GCMetricTable.TABLE, GCMetricTable.TABLE_TYPE, oldId);
}
while (timeBucket <= endTimeBucket);
JsonArray oldArray = new JsonArray();
multiGetResponse = oldPrepareMultiGet.get();
for (MultiGetItemResponse itemResponse : multiGetResponse.getResponses()) {
if (itemResponse.getResponse().isExists()) {
oldArray.add(((Number)itemResponse.getResponse().getSource().get(GCMetricTable.COLUMN_COUNT)).intValue());
} else {
oldArray.add(0);
}
}
response.add("ogc", oldArray);
return response;
return gcTrends;
}
}

View File

@ -18,11 +18,9 @@
package org.apache.skywalking.apm.collector.storage.h2.dao;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
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;
@ -31,6 +29,9 @@ import org.apache.skywalking.apm.collector.storage.base.sql.SqlBuilder;
import org.apache.skywalking.apm.collector.storage.dao.IGCMetricUIDAO;
import org.apache.skywalking.apm.collector.storage.h2.base.dao.H2DAO;
import org.apache.skywalking.apm.collector.storage.table.jvm.GCMetricTable;
import org.apache.skywalking.apm.collector.storage.ui.common.Step;
import org.apache.skywalking.apm.collector.storage.utils.DurationPoint;
import org.apache.skywalking.apm.collector.storage.utils.TimePyramidTableNameBuilder;
import org.apache.skywalking.apm.network.proto.GCPhrase;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -41,119 +42,42 @@ import org.slf4j.LoggerFactory;
public class GCMetricH2UIDAO extends H2DAO implements IGCMetricUIDAO {
private final Logger logger = LoggerFactory.getLogger(GCMetricH2UIDAO.class);
private static final String GET_GC_COUNT_SQL = "select {1}, sum({0}) as cnt, {1} from {2} where {3} = ? and {4} in (";
private static final String GET_GC_METRIC_SQL = "select * from {0} where {1} = ?";
public GCMetricH2UIDAO(H2Client client) {
super(client);
}
@Override public GCCount getGCCount(long[] timeBuckets, int instanceId) {
GCCount gcCount = new GCCount();
H2Client client = getClient();
String sql = GET_GC_COUNT_SQL;
StringBuilder builder = new StringBuilder();
for (int i = 0; i < timeBuckets.length; i++) {
builder.append("?,");
}
builder.delete(builder.length() - 1, builder.length());
builder.append(")");
sql = sql + builder + " group by {1}";
sql = SqlBuilder.buildSql(sql, GCMetricTable.COLUMN_COUNT, GCMetricTable.COLUMN_PHRASE,
GCMetricTable.TABLE, GCMetricTable.COLUMN_INSTANCE_ID, GCMetricTable.COLUMN_ID);
Object[] params = new Object[timeBuckets.length + 1];
for (int i = 0; i < timeBuckets.length; i++) {
params[i + 1] = timeBuckets[i];
}
params[0] = instanceId;
try (ResultSet rs = client.executeQuery(sql, params)) {
if (rs.next()) {
int phrase = rs.getInt(GCMetricTable.COLUMN_PHRASE);
int count = rs.getInt("cnt");
if (phrase == GCPhrase.NEW_VALUE) {
gcCount.setYoung(count);
} else if (phrase == GCPhrase.OLD_VALUE) {
gcCount.setOld(count);
}
}
} catch (SQLException | H2ClientException e) {
logger.error(e.getMessage(), e);
}
return gcCount;
@Override public List<Integer> getYoungGCTrend(int instanceId, Step step, List<DurationPoint> durationPoints) {
return getGCTrend(instanceId, step, durationPoints, GCPhrase.NEW_VALUE);
}
@Override public JsonObject getMetric(int instanceId, long timeBucket) {
JsonObject response = new JsonObject();
H2Client client = getClient();
String sql = SqlBuilder.buildSql(GET_GC_METRIC_SQL, GCMetricTable.TABLE, GCMetricTable.COLUMN_ID);
String youngId = timeBucket + Const.ID_SPLIT + GCPhrase.NEW_VALUE + instanceId;
Object[] params = new Object[] {youngId};
try (ResultSet rs = client.executeQuery(sql, params)) {
if (rs.next()) {
response.addProperty("ygc", rs.getInt(GCMetricTable.COLUMN_COUNT));
}
} catch (SQLException | H2ClientException e) {
logger.error(e.getMessage(), e);
}
String oldId = timeBucket + Const.ID_SPLIT + GCPhrase.OLD_VALUE + instanceId;
Object[] params1 = new Object[] {oldId};
try (ResultSet rs = client.executeQuery(sql, params1)) {
if (rs.next()) {
response.addProperty("ogc", rs.getInt(GCMetricTable.COLUMN_COUNT));
}
} catch (SQLException | H2ClientException e) {
logger.error(e.getMessage(), e);
}
return response;
@Override public List<Integer> getOldGCTrend(int instanceId, Step step, List<DurationPoint> durationPoints) {
return getGCTrend(instanceId, step, durationPoints, GCPhrase.OLD_VALUE);
}
@Override public JsonObject getMetric(int instanceId, long startTimeBucket, long endTimeBucket) {
JsonObject response = new JsonObject();
private List<Integer> getGCTrend(int instanceId, Step step, List<DurationPoint> durationPoints, int gcPhrase) {
String tableName = TimePyramidTableNameBuilder.build(step, GCMetricTable.TABLE);
H2Client client = getClient();
String sql = SqlBuilder.buildSql(GET_GC_METRIC_SQL, GCMetricTable.TABLE, GCMetricTable.COLUMN_ID);
long timeBucket = startTimeBucket;
List<String> youngIdsList = new ArrayList<>();
do {
// timeBucket = TimeBucketUtils.INSTANCE.addSecondForSecondTimeBucket(TimeBucketUtils.TimeBucketType.SECOND, timeBucket, 1);
String youngId = timeBucket + Const.ID_SPLIT + instanceId + Const.ID_SPLIT + GCPhrase.NEW_VALUE;
youngIdsList.add(youngId);
}
while (timeBucket <= endTimeBucket);
String sql = SqlBuilder.buildSql(GET_GC_METRIC_SQL, tableName, GCMetricTable.COLUMN_ID);
JsonArray youngArray = new JsonArray();
forEachRs(client, youngIdsList, sql, youngArray);
response.add("ygc", youngArray);
List<String> oldIdsList = new ArrayList<>();
timeBucket = startTimeBucket;
do {
// timeBucket = TimeBucketUtils.INSTANCE.addSecondForSecondTimeBucket(TimeBucketUtils.TimeBucketType.SECOND, timeBucket, 1);
String oldId = timeBucket + Const.ID_SPLIT + instanceId + Const.ID_SPLIT + GCPhrase.OLD_VALUE;
oldIdsList.add(oldId);
}
while (timeBucket <= endTimeBucket);
JsonArray oldArray = new JsonArray();
forEachRs(client, oldIdsList, sql, oldArray);
response.add("ogc", oldArray);
return response;
}
private void forEachRs(H2Client client, List<String> idsList, String sql, JsonArray metricArray) {
idsList.forEach(id -> {
List<Integer> gcTrends = new LinkedList<>();
durationPoints.forEach(durationPoint -> {
String id = durationPoint.getPoint() + Const.ID_SPLIT + instanceId + Const.ID_SPLIT + gcPhrase;
try (ResultSet rs = client.executeQuery(sql, new String[] {id})) {
if (rs.next()) {
metricArray.add(rs.getInt(GCMetricTable.COLUMN_COUNT));
long count = rs.getLong(GCMetricTable.COLUMN_COUNT);
long times = rs.getLong(GCMetricTable.COLUMN_TIMES);
gcTrends.add((int)(count / times));
} else {
metricArray.add(0);
gcTrends.add(0);
}
} catch (SQLException | H2ClientException e) {
logger.error(e.getMessage(), e);
}
});
return gcTrends;
}
}

View File

@ -82,8 +82,10 @@ public class ServerQuery implements Query {
return getServerService().getCPUTrend(serverId, duration.getStep(), start, end);
}
public GCTrend getGCTrend(int serverId, Duration duration) {
return null;
public GCTrend getGCTrend(int serverId, Duration duration) throws ParseException {
long start = DurationUtils.INSTANCE.exchangeToTimeBucket(duration.getStart());
long end = DurationUtils.INSTANCE.exchangeToTimeBucket(duration.getEnd());
return getServerService().getGCTrend(serverId, duration.getStep(), start, end);
}
public MemoryTrend getMemoryTrend(int serverId, Duration duration) {

View File

@ -75,7 +75,6 @@ public class InstanceJVMService {
for (String metricType : metricTypes) {
if (metricType.toLowerCase().equals(MetricType.cpu.name())) {
} else if (metricType.toLowerCase().equals(MetricType.gc.name())) {
metrics.add(MetricType.gc.name(), gcMetricDAO.getMetric(instanceId, timeBucket));
} else if (metricType.toLowerCase().equals(MetricType.tps.name())) {
} else if (metricType.toLowerCase().equals(MetricType.resptime.name())) {
} else if (metricType.toLowerCase().equals(MetricType.heapmemory.name())) {
@ -105,7 +104,6 @@ public class InstanceJVMService {
for (String metricType : metricTypes) {
if (metricType.toLowerCase().equals(MetricType.cpu.name())) {
} else if (metricType.toLowerCase().equals(MetricType.gc.name())) {
metrics.add(MetricType.gc.name(), gcMetricDAO.getMetric(instanceId, startTimeBucket, endTimeBucket));
} else if (metricType.toLowerCase().equals(MetricType.tps.name())) {
} else if (metricType.toLowerCase().equals(MetricType.resptime.name())) {
} else if (metricType.toLowerCase().equals(MetricType.heapmemory.name())) {

View File

@ -29,6 +29,7 @@ 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.ICpuMetricUIDAO;
import org.apache.skywalking.apm.collector.storage.dao.IGCMetricUIDAO;
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;
@ -36,6 +37,7 @@ import org.apache.skywalking.apm.collector.storage.ui.common.Step;
import org.apache.skywalking.apm.collector.storage.ui.common.ThroughputTrend;
import org.apache.skywalking.apm.collector.storage.ui.server.AppServerInfo;
import org.apache.skywalking.apm.collector.storage.ui.server.CPUTrend;
import org.apache.skywalking.apm.collector.storage.ui.server.GCTrend;
import org.apache.skywalking.apm.collector.storage.utils.DurationPoint;
import org.apache.skywalking.apm.collector.ui.utils.DurationUtils;
@ -46,13 +48,15 @@ public class ServerService {
private final Gson gson = new Gson();
private final IInstanceUIDAO instanceUIDAO;
private final ICpuMetricUIDAO cpuMetricUIDAO;
private final IInstanceMetricUIDAO instanceMetricUIDAO;
private final ICpuMetricUIDAO cpuMetricUIDAO;
private final IGCMetricUIDAO gcMetricUIDAO;
public ServerService(ModuleManager moduleManager) {
this.instanceUIDAO = moduleManager.find(StorageModule.NAME).getService(IInstanceUIDAO.class);
this.cpuMetricUIDAO = moduleManager.find(StorageModule.NAME).getService(ICpuMetricUIDAO.class);
this.instanceMetricUIDAO = moduleManager.find(StorageModule.NAME).getService(IInstanceMetricUIDAO.class);
this.cpuMetricUIDAO = moduleManager.find(StorageModule.NAME).getService(ICpuMetricUIDAO.class);
this.gcMetricUIDAO = moduleManager.find(StorageModule.NAME).getService(IGCMetricUIDAO.class);
}
public List<AppServerInfo> searchServer(String keyword, long start, long end) {
@ -98,6 +102,16 @@ public class ServerService {
return cpuTrend;
}
public GCTrend getGCTrend(int instanceId, Step step, long start, long end) throws ParseException {
GCTrend gcTrend = new GCTrend();
List<DurationPoint> durationPoints = DurationUtils.INSTANCE.getDurationPoints(step, start, end);
List<Integer> youngGCTrend = gcMetricUIDAO.getYoungGCTrend(instanceId, step, durationPoints);
gcTrend.setYoungGC(youngGCTrend);
List<Integer> oldGCTrend = gcMetricUIDAO.getOldGCTrend(instanceId, step, durationPoints);
gcTrend.setOldGC(oldGCTrend);
return gcTrend;
}
private void buildAppServerInfo(List<AppServerInfo> serverInfos) {
serverInfos.forEach(serverInfo -> {
if (StringUtils.isNotEmpty(serverInfo.getOsInfo())) {