You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@skywalking.apache.org by wu...@apache.org on 2020/04/18 14:49:55 UTC
[skywalking] branch metrics updated: Finish some metrics query.
This is an automated email from the ASF dual-hosted git repository.
wusheng pushed a commit to branch metrics
in repository https://gitbox.apache.org/repos/asf/skywalking.git
The following commit(s) were added to refs/heads/metrics by this push:
new 8c1bd71 Finish some metrics query.
8c1bd71 is described below
commit 8c1bd713b24e05ffc10bc0e74e84706049ba2304
Author: Wu Sheng <wu...@foxmail.com>
AuthorDate: Sat Apr 18 22:49:04 2020 +0800
Finish some metrics query.
---
.../skywalking/oal/rt/parser/AnalysisResult.java | 4 +-
.../oal/rt/parser/PersistenceColumns.java | 8 +-
.../code-templates/metrics/deserialize.ftl | 10 +-
.../resources/code-templates/metrics/serialize.ftl | 12 +-
.../skywalking/oap/server/core/CoreModule.java | 4 +-
.../oap/server/core/CoreModuleProvider.java | 4 +-
.../oap/server/core/analysis/IDManager.java | 4 +-
.../server/core/analysis/metrics/DataTable.java | 107 +++++++++
.../server/core/analysis/metrics/GroupMetrics.java | 32 ---
...modynamicMetrics.java => HistogramMetrics.java} | 62 +++---
.../core/analysis/metrics/IntKeyLongValue.java | 96 --------
.../analysis/metrics/IntKeyLongValueHashMap.java | 77 -------
.../core/analysis/metrics/PercentileMetrics.java | 59 ++---
.../server/core/analysis/metrics/PxxMetrics.java | 38 ++--
.../oap/server/core/query/DurationUtils.java | 52 ++---
.../oap/server/core/query/MetricQueryService.java | 138 ------------
.../oap/server/core/query/MetricsQueryService.java | 85 +++++++
.../query/{DurationPoint.java => PointOfTime.java} | 36 +--
.../oap/server/core/query/StepToDownSampling.java | 39 ----
.../oap/server/core/query/input/Duration.java | 9 +
.../oap/server/core/query/input/Entity.java | 48 +++-
.../server/core/query/input/MetricsCondition.java | 5 +
.../oap/server/core/query/type/Bucket.java | 16 +-
.../oap/server/core/query/type/HeatMap.java | 75 ++++++-
.../oap/server/core/query/type/IntValues.java | 19 +-
.../oap/server/core/query/type/Thermodynamic.java | 4 +
.../oap/server/core/storage/annotation/Column.java | 5 +
.../storage/annotation/ValueColumnMetadata.java | 16 +-
.../oap/server/core/storage/model/ModelColumn.java | 4 +-
.../core/storage/query/IMetricsQueryDAO.java | 32 +--
.../storage/type/StorageDataComplexObject.java | 4 +-
.../server-core/src/main/proto/RemoteService.proto | 10 -
...HashMapTestCase.java => DataTableTestCase.java} | 38 ++--
...cMetricsTest.java => HistogramMetricsTest.java} | 14 +-
.../core/analysis/metrics/PxxMetricsTest.java | 2 +-
.../server/core/storage/model/ModelColumnTest.java | 4 +-
.../oap/query/graphql/resolver/MetricQuery.java | 142 ++++++++----
.../oap/query/graphql/resolver/MetricsQuery.java | 24 +-
.../src/main/resources/query-protocol | 2 +-
.../elasticsearch/base/ColumnTypeEsMapping.java | 4 +-
.../elasticsearch/query/MetricsQueryEsDAO.java | 31 ++-
.../plugin/influxdb/query/MetricsQuery.java | 14 +-
.../plugin/jdbc/h2/dao/H2MetricsQueryDAO.java | 244 ++++++++++-----------
.../plugin/jdbc/h2/dao/H2TableInstaller.java | 4 +-
.../plugin/jdbc/mysql/MySQLTableInstaller.java | 4 +-
.../tool/profile/core/MockCoreModuleProvider.java | 4 +-
46 files changed, 815 insertions(+), 830 deletions(-)
diff --git a/oap-server/oal-rt/src/main/java/org/apache/skywalking/oal/rt/parser/AnalysisResult.java b/oap-server/oal-rt/src/main/java/org/apache/skywalking/oal/rt/parser/AnalysisResult.java
index b55796f..05419b8 100644
--- a/oap-server/oal-rt/src/main/java/org/apache/skywalking/oal/rt/parser/AnalysisResult.java
+++ b/oap-server/oal-rt/src/main/java/org/apache/skywalking/oal/rt/parser/AnalysisResult.java
@@ -140,8 +140,8 @@ public class AnalysisResult {
case "long":
serializeFields.addLongField(column.getFieldName());
break;
- case "IntKeyLongValueHashMap":
- serializeFields.addIntKeyLongValueHashMapField(column.getFieldName());
+ case "DataTable":
+ serializeFields.addDataTableField(column.getFieldName());
break;
default:
throw new IllegalStateException("Unexpected field type [" + type + "] of persistence column [" + column
diff --git a/oap-server/oal-rt/src/main/java/org/apache/skywalking/oal/rt/parser/PersistenceColumns.java b/oap-server/oal-rt/src/main/java/org/apache/skywalking/oal/rt/parser/PersistenceColumns.java
index d47b7e0..bdb43d6 100644
--- a/oap-server/oal-rt/src/main/java/org/apache/skywalking/oal/rt/parser/PersistenceColumns.java
+++ b/oap-server/oal-rt/src/main/java/org/apache/skywalking/oal/rt/parser/PersistenceColumns.java
@@ -26,7 +26,7 @@ public class PersistenceColumns {
private List<PersistenceField> longFields = new LinkedList<>();
private List<PersistenceField> doubleFields = new LinkedList<>();
private List<PersistenceField> intFields = new LinkedList<>();
- private List<PersistenceField> intKeyLongValueHashMap = new LinkedList<>();
+ private List<PersistenceField> dataTableFields = new LinkedList<>();
public void addStringField(String fieldName) {
stringFields.add(new PersistenceField(fieldName));
@@ -44,8 +44,8 @@ public class PersistenceColumns {
intFields.add(new PersistenceField(fieldName));
}
- public void addIntKeyLongValueHashMapField(String fieldName) {
- intKeyLongValueHashMap.add(new PersistenceField(fieldName));
+ public void addDataTableField(String fieldName) {
+ dataTableFields.add(new PersistenceField(fieldName));
}
public List<PersistenceField> getStringFields() {
@@ -65,6 +65,6 @@ public class PersistenceColumns {
}
public List<PersistenceField> getIntKeyLongValueHashMapFields() {
- return intKeyLongValueHashMap;
+ return dataTableFields;
}
}
diff --git a/oap-server/oal-rt/src/main/resources/code-templates/metrics/deserialize.ftl b/oap-server/oal-rt/src/main/resources/code-templates/metrics/deserialize.ftl
index de5c4d0..7814056 100644
--- a/oap-server/oal-rt/src/main/resources/code-templates/metrics/deserialize.ftl
+++ b/oap-server/oal-rt/src/main/resources/code-templates/metrics/deserialize.ftl
@@ -15,12 +15,8 @@ public void deserialize(org.apache.skywalking.oap.server.core.remote.grpc.proto.
${field.setter}(remoteData.getDataIntegers(${field?index}));
</#list>
-java.util.Iterator iterator;
-<#list serializeFields.intKeyLongValueHashMapFields as field>
- iterator = remoteData.getDataLists(${field?index}).getValueList().iterator();
- while (iterator.hasNext()) {
- org.apache.skywalking.oap.server.core.remote.grpc.proto.IntKeyLongValuePair element = (org.apache.skywalking.oap.server.core.remote.grpc.proto.IntKeyLongValuePair)(iterator.next());
- super.${field.getter}().put(new Integer(element.getKey()), new org.apache.skywalking.oap.server.core.analysis.metrics.IntKeyLongValue(element.getKey(), element.getValue()));
- }
+<#list serializeFields.dataTableFields as field>
+ ${field.setter}(new org.apache.skywalking.oap.server.core.analysis.metrics.DataTable(remoteData.getDataStrings(${field?index})));
</#list>
+
}
\ No newline at end of file
diff --git a/oap-server/oal-rt/src/main/resources/code-templates/metrics/serialize.ftl b/oap-server/oal-rt/src/main/resources/code-templates/metrics/serialize.ftl
index 731f292..d44eedd 100644
--- a/oap-server/oal-rt/src/main/resources/code-templates/metrics/serialize.ftl
+++ b/oap-server/oal-rt/src/main/resources/code-templates/metrics/serialize.ftl
@@ -15,15 +15,9 @@ org.apache.skywalking.oap.server.core.remote.grpc.proto.RemoteData.Builder remot
<#list serializeFields.intFields as field>
remoteBuilder.addDataIntegers(${field.getter}());
</#list>
-java.util.Iterator iterator;
-org.apache.skywalking.oap.server.core.remote.grpc.proto.DataIntLongPairList.Builder pairListBuilder;
-<#list serializeFields.intKeyLongValueHashMapFields as field>
- iterator = super.${field.getter}().values().iterator();
- pairListBuilder = org.apache.skywalking.oap.server.core.remote.grpc.proto.DataIntLongPairList.newBuilder();
- while (iterator.hasNext()) {
- pairListBuilder.addValue(((org.apache.skywalking.oap.server.core.analysis.metrics.IntKeyLongValue)(iterator.next())).serialize());
- }
- remoteBuilder.addDataLists(pairListBuilder);
+
+<#list serializeFields.dataTableFields as field>
+ remoteBuilder.addDataStrings(${field.getter}().serialize());
</#list>
return remoteBuilder;
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/CoreModule.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/CoreModule.java
index 37bc7c8..82450bb 100755
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/CoreModule.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/CoreModule.java
@@ -32,7 +32,7 @@ import org.apache.skywalking.oap.server.core.query.AggregationQueryService;
import org.apache.skywalking.oap.server.core.query.AlarmQueryService;
import org.apache.skywalking.oap.server.core.query.LogQueryService;
import org.apache.skywalking.oap.server.core.query.MetadataQueryService;
-import org.apache.skywalking.oap.server.core.query.MetricQueryService;
+import org.apache.skywalking.oap.server.core.query.MetricsQueryService;
import org.apache.skywalking.oap.server.core.query.ProfileTaskQueryService;
import org.apache.skywalking.oap.server.core.query.TopNRecordsQueryService;
import org.apache.skywalking.oap.server.core.query.TopologyQueryService;
@@ -90,7 +90,7 @@ public class CoreModule extends ModuleDefine {
private void addQueryService(List<Class> classes) {
classes.add(TopologyQueryService.class);
- classes.add(MetricQueryService.class);
+ classes.add(MetricsQueryService.class);
classes.add(TraceQueryService.class);
classes.add(LogQueryService.class);
classes.add(MetadataQueryService.class);
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/CoreModuleProvider.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/CoreModuleProvider.java
index c23255c..03a1be7 100755
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/CoreModuleProvider.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/CoreModuleProvider.java
@@ -48,7 +48,7 @@ import org.apache.skywalking.oap.server.core.query.AggregationQueryService;
import org.apache.skywalking.oap.server.core.query.AlarmQueryService;
import org.apache.skywalking.oap.server.core.query.LogQueryService;
import org.apache.skywalking.oap.server.core.query.MetadataQueryService;
-import org.apache.skywalking.oap.server.core.query.MetricQueryService;
+import org.apache.skywalking.oap.server.core.query.MetricsQueryService;
import org.apache.skywalking.oap.server.core.query.ProfileTaskQueryService;
import org.apache.skywalking.oap.server.core.query.TopNRecordsQueryService;
import org.apache.skywalking.oap.server.core.query.TopologyQueryService;
@@ -213,7 +213,7 @@ public class CoreModuleProvider extends ModuleProvider {
NetworkAddressAliasCache.class, new NetworkAddressAliasCache(moduleConfig));
this.registerServiceImplementation(TopologyQueryService.class, new TopologyQueryService(getManager()));
- this.registerServiceImplementation(MetricQueryService.class, new MetricQueryService(getManager()));
+ this.registerServiceImplementation(MetricsQueryService.class, new MetricsQueryService(getManager()));
this.registerServiceImplementation(TraceQueryService.class, new TraceQueryService(getManager()));
this.registerServiceImplementation(LogQueryService.class, new LogQueryService(getManager()));
this.registerServiceImplementation(MetadataQueryService.class, new MetadataQueryService(getManager()));
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/IDManager.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/IDManager.java
index 67e2b91..ccd3670 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/IDManager.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/IDManager.java
@@ -160,11 +160,11 @@ public class IDManager {
@EqualsAndHashCode
public static class ServiceInstanceRelationDefine {
/**
- * Built by {@link ServiceID#buildId(String, NodeType)}
+ * Built by {@link ServiceInstanceID#buildId(String, String)}
*/
private final String sourceId;
/**
- * Built by {@link ServiceID#buildId(String, NodeType)}
+ * Built by {@link ServiceInstanceID#buildId(String, String)}
*/
private final String destId;
}
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/DataTable.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/DataTable.java
new file mode 100644
index 0000000..dc677b8
--- /dev/null
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/DataTable.java
@@ -0,0 +1,107 @@
+/*
+ * 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.oap.server.core.analysis.metrics;
+
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.stream.Collectors;
+import org.apache.skywalking.oap.server.core.Const;
+import org.apache.skywalking.oap.server.core.storage.type.StorageDataComplexObject;
+
+/**
+ * DataTable includes a hashmap to store string key and long value. It enhanced the serialization capability.
+ */
+public class DataTable implements StorageDataComplexObject<DataTable> {
+ private HashMap<String, Long> data;
+
+ public DataTable() {
+ data = new HashMap<>();
+ }
+
+ public DataTable(int initialCapacity) {
+ data = new HashMap<>(initialCapacity);
+ }
+
+ public DataTable(String data) {
+ this();
+ toObject(data);
+ }
+
+ public Long get(String key) {
+ return data.get(key);
+ }
+
+ public void put(String key, Long value) {
+ data.put(key, value);
+ }
+
+ public long sumOfValues() {
+ return data.values().stream().mapToLong(element -> element).sum();
+ }
+
+ public List<String> sortedKeys(Comparator<String> keyComparator) {
+ return data.keySet().stream().sorted(keyComparator).collect(Collectors.toList());
+ }
+
+ public List<Long> sortedValues(Comparator<String> keyComparator) {
+ final List<String> collect = data.keySet().stream().sorted(keyComparator).collect(Collectors.toList());
+ List<Long> values = new ArrayList<>(collect.size());
+ collect.forEach(key -> values.add(data.get(key)));
+ return values;
+ }
+
+ public boolean hasData() {
+ return !data.isEmpty();
+ }
+
+ public int size() {
+ return data.size();
+ }
+
+ @Override
+ public String toStorageData() {
+ StringBuilder builder = new StringBuilder();
+
+ this.data.forEach((key, value) -> {
+ if (builder.length() != 0) {
+ // For the first element.
+ builder.append(Const.ARRAY_SPLIT);
+ }
+ builder.append(key).append(Const.KEY_VALUE_SPLIT).append(value);
+ });
+ return builder.toString();
+ }
+
+ @Override
+ public void toObject(String data) {
+ String[] keyValues = data.split(Const.ARRAY_PARSER_SPLIT);
+ for (String keyValue : keyValues) {
+ final String[] keyValuePair = keyValue.split(Const.KEY_VALUE_SPLIT);
+ if (keyValuePair.length == 2) {
+ this.data.put(keyValuePair[0], Long.parseLong(keyValuePair[1]));
+ }
+ }
+ }
+
+ @Override
+ public void append(DataTable dataTable) {
+ dataTable.data.forEach(this.data::put);
+ }
+}
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/GroupMetrics.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/GroupMetrics.java
deleted file mode 100644
index c1b818d..0000000
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/GroupMetrics.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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.oap.server.core.analysis.metrics;
-
-public abstract class GroupMetrics extends Metrics {
-
- protected void combine(IntKeyLongValueHashMap source, IntKeyLongValueHashMap target) {
- source.forEach((key, element) -> {
- IntKeyLongValue existingElement = target.get(key);
- if (existingElement == null) {
- target.put(key, new IntKeyLongValue(key, element.getValue()));
- } else {
- existingElement.addValue(element.getValue());
- }
- });
- }
-}
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/ThermodynamicMetrics.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/HistogramMetrics.java
similarity index 59%
rename from oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/ThermodynamicMetrics.java
rename to oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/HistogramMetrics.java
index 967f594..fd58da7 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/ThermodynamicMetrics.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/HistogramMetrics.java
@@ -27,73 +27,67 @@ import org.apache.skywalking.oap.server.core.analysis.metrics.annotation.SourceF
import org.apache.skywalking.oap.server.core.storage.annotation.Column;
/**
- * Thermodynamic metrics represents the calculator for heat map.
+ * Histogram metrics represents the calculator for heat map.
* <p>
* It groups the given collection of values by the given step and number of steps.
* <p>
* A heat map (or heatmap) is a graphical representation of data where the individual values contained in a matrix are
* represented as colors.
*/
-@MetricsFunction(functionName = "thermodynamic")
-public abstract class ThermodynamicMetrics extends GroupMetrics {
+@MetricsFunction(functionName = "histogram")
+public abstract class HistogramMetrics extends Metrics {
- public static final String DETAIL_GROUP = "detail_group";
- public static final String STEP = "step";
- public static final String NUM_OF_STEPS = "num_of_steps";
+ public static final String DATASET = "dataset";
- @Getter
- @Setter
- @Column(columnName = STEP, storageOnly = true)
- private int step = 0;
- @Getter
- @Setter
- @Column(columnName = NUM_OF_STEPS, storageOnly = true)
- private int numOfSteps = 0;
/**
- * The special case when the column is isValue = true, but storageOnly = true, because it is {@link
- * IntKeyLongValueHashMap} type, this column can't be query by the aggregation way.
+ * The special case when the column is isValue = true, but storageOnly = true, because it is {@link DataTable} type,
+ * this column can't be query by the aggregation way.
*/
@Getter
@Setter
- @Column(columnName = DETAIL_GROUP, isValue = true, storageOnly = true)
- private IntKeyLongValueHashMap detailGroup = new IntKeyLongValueHashMap(30);
+ @Column(columnName = DATASET, isValue = true, storageOnly = true)
+ private DataTable dataset = new DataTable(30);
/**
* Data will be grouped in
- * <p>
- * [0, step), [step, step * 2), ..., [step * (maxNumOfSteps - 1), step * maxNumOfSteps), [step * maxNumOfSteps,
- * MAX)
+ * <pre>
+ * key = 100, represents [0, 100), value = count of requests in the latency range.
+ * key = 200, represents [100, 200), value = count of requests in the latency range.
+ * ...
+ * key = step * maxNumOfSteps, represents [step * maxNumOfSteps, MAX)
+ * </pre>
*
* @param step the size of each step. A positive integer.
* @param maxNumOfSteps Steps are used to group incoming value.
*/
@Entrance
public final void combine(@SourceFrom int value, @Arg int step, @Arg int maxNumOfSteps) {
- if (this.step == 0) {
- this.step = step;
- }
- if (this.numOfSteps == 0) {
- this.numOfSteps = maxNumOfSteps;
+ if (!dataset.hasData()) {
+ for (int i = 1; i <= maxNumOfSteps; i++) {
+ String key = String.valueOf(i * step);
+ dataset.put(key, 0L);
+ }
}
- int index = value / step;
+ int index = value / step + 1;
if (index > maxNumOfSteps) {
- index = numOfSteps;
+ index = maxNumOfSteps;
}
+ String idx = String.valueOf(index * step);
- IntKeyLongValue element = detailGroup.get(index);
+ Long element = dataset.get(idx);
if (element == null) {
- element = new IntKeyLongValue(index, 1);
- detailGroup.put(element.getKey(), element);
+ element = 1L;
} else {
- element.addValue(1);
+ element++;
}
+ dataset.put(idx, element);
}
@Override
public void combine(Metrics metrics) {
- ThermodynamicMetrics thermodynamicMetrics = (ThermodynamicMetrics) metrics;
- combine(thermodynamicMetrics.getDetailGroup(), this.detailGroup);
+ HistogramMetrics histogramMetrics = (HistogramMetrics) metrics;
+ this.dataset.append(histogramMetrics.dataset);
}
/**
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/IntKeyLongValue.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/IntKeyLongValue.java
deleted file mode 100644
index c7fb477..0000000
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/IntKeyLongValue.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * 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.oap.server.core.analysis.metrics;
-
-import java.util.Objects;
-import lombok.Getter;
-import lombok.Setter;
-import org.apache.skywalking.oap.server.core.Const;
-import org.apache.skywalking.oap.server.core.remote.grpc.proto.IntKeyLongValuePair;
-import org.apache.skywalking.oap.server.core.storage.type.StorageDataComplexObject;
-
-/**
- * IntKeyLongValue is a common bean, with key in Int and value in Long
- */
-@Setter
-@Getter
-public class IntKeyLongValue implements Comparable<IntKeyLongValue>, StorageDataComplexObject {
- private int key;
- private long value;
-
- public IntKeyLongValue() {
- }
-
- public IntKeyLongValue(int key, long value) {
- this.key = key;
- this.value = value;
- }
-
- public void addValue(long value) {
- this.value += value;
- }
-
- @Override
- public int compareTo(IntKeyLongValue o) {
- return key - o.key;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o)
- return true;
- if (o == null || getClass() != o.getClass())
- return false;
- IntKeyLongValue value = (IntKeyLongValue) o;
- return key == value.key;
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(key);
- }
-
- public IntKeyLongValuePair serialize() {
- return IntKeyLongValuePair.newBuilder().setKey(key).setValue(value).build();
- }
-
- public void deserialize(IntKeyLongValuePair pair) {
- this.key = pair.getKey();
- this.value = pair.getValue();
- }
-
- @Override
- public String toStorageData() {
- return key + Const.KEY_VALUE_SPLIT + value;
- }
-
- @Override
- public void toObject(String data) {
- String[] keyValue = data.split(Const.KEY_VALUE_SPLIT);
- this.key = Integer.parseInt(keyValue[0]);
- this.value = Long.parseLong(keyValue[1]);
- }
-
- @Override
- public void copyFrom(Object source) {
- IntKeyLongValue value = (IntKeyLongValue) source;
- this.key = value.key;
- this.value = value.value;
- }
-}
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/IntKeyLongValueHashMap.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/IntKeyLongValueHashMap.java
deleted file mode 100644
index a7ed6db..0000000
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/IntKeyLongValueHashMap.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * 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.oap.server.core.analysis.metrics;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import org.apache.skywalking.oap.server.core.Const;
-import org.apache.skywalking.oap.server.core.storage.type.StorageDataComplexObject;
-
-public class IntKeyLongValueHashMap extends HashMap<Integer, IntKeyLongValue> implements StorageDataComplexObject {
-
- public IntKeyLongValueHashMap() {
- super();
- }
-
- public IntKeyLongValueHashMap(int initialCapacity) {
- super(initialCapacity);
- }
-
- public IntKeyLongValueHashMap(String data) {
- super();
- toObject(data);
- }
-
- @Override
- public String toStorageData() {
- StringBuilder data = new StringBuilder();
-
- List<Map.Entry<Integer, IntKeyLongValue>> list = new ArrayList<>(this.entrySet());
-
- for (int i = 0; i < list.size(); i++) {
- if (i == 0) {
- data.append(list.get(i).getValue().toStorageData());
- } else {
- data.append(Const.ARRAY_SPLIT).append(list.get(i).getValue().toStorageData());
- }
- }
- return data.toString();
- }
-
- @Override
- public void toObject(String data) {
- String[] keyValues = data.split(Const.ARRAY_PARSER_SPLIT);
- for (String keyValue : keyValues) {
- IntKeyLongValue value = new IntKeyLongValue();
- value.toObject(keyValue);
- this.put(value.getKey(), value);
- }
- }
-
- @Override
- public void copyFrom(Object source) {
- IntKeyLongValueHashMap intKeyLongValueHashMap = (IntKeyLongValueHashMap) source;
- intKeyLongValueHashMap.values().forEach(value -> {
- IntKeyLongValue newValue = new IntKeyLongValue();
- newValue.copyFrom(value);
- this.put(newValue.getKey(), newValue);
- });
- }
-}
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/PercentileMetrics.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/PercentileMetrics.java
index 8c8962b..f2ede3a 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/PercentileMetrics.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/PercentileMetrics.java
@@ -19,6 +19,8 @@
package org.apache.skywalking.oap.server.core.analysis.metrics;
import java.util.Comparator;
+import java.util.List;
+import java.util.stream.IntStream;
import lombok.Getter;
import lombok.Setter;
import org.apache.skywalking.oap.server.core.analysis.metrics.annotation.Arg;
@@ -32,7 +34,7 @@ import org.apache.skywalking.oap.server.core.storage.annotation.Column;
* multiple P50/75/90/95/99 values once for all.
*/
@MetricsFunction(functionName = "percentile")
-public abstract class PercentileMetrics extends GroupMetrics implements MultiIntValuesHolder {
+public abstract class PercentileMetrics extends Metrics implements MultiIntValuesHolder {
protected static final String DATASET = "dataset";
protected static final String VALUE = "value";
protected static final String PRECISION = "precision";
@@ -46,13 +48,13 @@ public abstract class PercentileMetrics extends GroupMetrics implements MultiInt
};
/**
- * The special case when the column is isValue = true, but storageOnly = true, because it is {@link
- * IntKeyLongValueHashMap} type, this column can't be query by the aggregation way.
+ * The special case when the column is isValue = true, but storageOnly = true, because it is {@link DataTable} type,
+ * this column can't be query by the aggregation way.
*/
@Getter
@Setter
@Column(columnName = VALUE, isValue = true, storageOnly = true)
- private IntKeyLongValueHashMap percentileValues;
+ private DataTable percentileValues;
@Getter
@Setter
@Column(columnName = PRECISION, storageOnly = true)
@@ -60,13 +62,13 @@ public abstract class PercentileMetrics extends GroupMetrics implements MultiInt
@Getter
@Setter
@Column(columnName = DATASET, storageOnly = true)
- private IntKeyLongValueHashMap dataset;
+ private DataTable dataset;
private boolean isCalculated;
public PercentileMetrics() {
- percentileValues = new IntKeyLongValueHashMap(RANKS.length);
- dataset = new IntKeyLongValueHashMap(30);
+ percentileValues = new DataTable(RANKS.length);
+ dataset = new DataTable(30);
}
@Entrance
@@ -74,14 +76,14 @@ public abstract class PercentileMetrics extends GroupMetrics implements MultiInt
this.isCalculated = false;
this.precision = precision;
- int index = value / precision;
- IntKeyLongValue element = dataset.get(index);
+ String index = String.valueOf(value / precision);
+ Long element = dataset.get(index);
if (element == null) {
- element = new IntKeyLongValue(index, 1);
- dataset.put(element.getKey(), element);
+ element = 1L;
} else {
- element.addValue(1);
+ element++;
}
+ dataset.put(index, element);
}
@Override
@@ -89,34 +91,34 @@ public abstract class PercentileMetrics extends GroupMetrics implements MultiInt
this.isCalculated = false;
PercentileMetrics percentileMetrics = (PercentileMetrics) metrics;
- combine(percentileMetrics.getDataset(), this.dataset);
+ this.dataset.append(percentileMetrics.dataset);
}
@Override
public final void calculate() {
if (!isCalculated) {
- int total = dataset.values().stream().mapToInt(element -> (int) element.getValue()).sum();
+ long total = dataset.sumOfValues();
- int index = 0;
int[] roofs = new int[RANKS.length];
for (int i = 0; i < RANKS.length; i++) {
roofs[i] = Math.round(total * RANKS[i] * 1.0f / 100);
}
int count = 0;
- IntKeyLongValue[] sortedData = dataset.values()
- .stream()
- .sorted(Comparator.comparingInt(IntKeyLongValue::getKey))
- .toArray(IntKeyLongValue[]::new);
- for (IntKeyLongValue element : sortedData) {
- count += element.getValue();
- for (int i = index; i < roofs.length; i++) {
+ final List<String> sortedKeys = dataset.sortedKeys(Comparator.comparingInt(Integer::parseInt));
+
+ int loopIndex = 0;
+ for (String index : sortedKeys) {
+ final Long value = dataset.get(index);
+
+ count += value;
+ for (int i = loopIndex; i < roofs.length; i++) {
int roof = roofs[i];
if (count >= roof) {
- percentileValues.put(index, new IntKeyLongValue(index, element.getKey() * precision));
- index++;
+ percentileValues.put(index, Long.parseLong(index) * precision);
+ loopIndex++;
} else {
break;
}
@@ -126,10 +128,9 @@ public abstract class PercentileMetrics extends GroupMetrics implements MultiInt
}
public int[] getValues() {
- int[] values = new int[percentileValues.size()];
- for (int i = 0; i < values.length; i++) {
- values[i] = (int) percentileValues.get(i).getValue();
- }
- return values;
+ return percentileValues.sortedValues(Comparator.comparingInt(Integer::parseInt))
+ .stream()
+ .flatMapToInt(l -> IntStream.of(l.intValue()))
+ .toArray();
}
}
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/PxxMetrics.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/PxxMetrics.java
index 9674eec..1f4f5c5 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/PxxMetrics.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/PxxMetrics.java
@@ -19,6 +19,7 @@
package org.apache.skywalking.oap.server.core.analysis.metrics;
import java.util.Comparator;
+import java.util.List;
import lombok.Getter;
import lombok.Setter;
import org.apache.skywalking.oap.server.core.analysis.metrics.annotation.Arg;
@@ -34,7 +35,7 @@ import org.apache.skywalking.oap.server.core.storage.annotation.Column;
* observations in a group of observations fall. For example, the 20th percentile is the value (or score) below which
* 20% of the observations may be found.
*/
-public abstract class PxxMetrics extends GroupMetrics implements IntValueHolder {
+public abstract class PxxMetrics extends Metrics implements IntValueHolder {
protected static final String DETAIL_GROUP = "detail_group";
protected static final String VALUE = "value";
@@ -51,14 +52,14 @@ public abstract class PxxMetrics extends GroupMetrics implements IntValueHolder
@Getter
@Setter
@Column(columnName = DETAIL_GROUP, storageOnly = true)
- private IntKeyLongValueHashMap detailGroup;
+ private DataTable detailGroup;
private final int percentileRank;
private boolean isCalculated;
public PxxMetrics(int percentileRank) {
this.percentileRank = percentileRank;
- detailGroup = new IntKeyLongValueHashMap(30);
+ detailGroup = new DataTable(30);
}
@Entrance
@@ -66,14 +67,14 @@ public abstract class PxxMetrics extends GroupMetrics implements IntValueHolder
this.isCalculated = false;
this.precision = precision;
- int index = value / precision;
- IntKeyLongValue element = detailGroup.get(index);
+ String index = String.valueOf(value / precision);
+ Long element = detailGroup.get(index);
if (element == null) {
- element = new IntKeyLongValue(index, 1);
- detailGroup.put(element.getKey(), element);
+ element = 1L;
} else {
- element.addValue(1);
+ element++;
}
+ detailGroup.put(index, element);
}
@Override
@@ -81,27 +82,24 @@ public abstract class PxxMetrics extends GroupMetrics implements IntValueHolder
this.isCalculated = false;
PxxMetrics pxxMetrics = (PxxMetrics) metrics;
- combine(pxxMetrics.getDetailGroup(), this.detailGroup);
+ this.detailGroup.append(pxxMetrics.detailGroup);
}
@Override
public final void calculate() {
if (!isCalculated) {
- int total = detailGroup.values().stream().mapToInt(element -> (int) element.getValue()).sum();
+ long total = detailGroup.sumOfValues();
int roof = Math.round(total * percentileRank * 1.0f / 100);
- int count = 0;
- IntKeyLongValue[] sortedData = detailGroup.values().stream().sorted(new Comparator<IntKeyLongValue>() {
- @Override
- public int compare(IntKeyLongValue o1, IntKeyLongValue o2) {
- return o1.getKey() - o2.getKey();
- }
- }).toArray(IntKeyLongValue[]::new);
- for (IntKeyLongValue element : sortedData) {
- count += element.getValue();
+ long count = 0;
+ final List<String> sortedKeys = detailGroup.sortedKeys(Comparator.comparingInt(Integer::parseInt));
+
+ for (String index : sortedKeys) {
+ final Long value = detailGroup.get(index);
+ count += value;
if (count >= roof) {
- value = element.getKey() * precision;
+ this.value = Integer.parseInt(index) * precision;
return;
}
}
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/DurationUtils.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/DurationUtils.java
index 76ba1bb..b1959bc 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/DurationUtils.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/DurationUtils.java
@@ -141,50 +141,40 @@ public enum DurationUtils {
}
}
- public List<DurationPoint> getDurationPoints(DownSampling downsampling, long startTimeBucket, long endTimeBucket) {
- DateTime dateTime = parseToDateTime(downsampling, startTimeBucket);
+ public List<PointOfTime> getDurationPoints(Step step, long startTimeBucket, long endTimeBucket) {
+ DateTime dateTime = parseToDateTime(step, startTimeBucket);
- List<DurationPoint> durations = new LinkedList<>();
- durations.add(new DurationPoint(startTimeBucket, secondsBetween(downsampling, dateTime),
- minutesBetween(downsampling, dateTime)
- ));
+ List<PointOfTime> durations = new LinkedList<>();
+ durations.add(new PointOfTime(startTimeBucket));
int i = 0;
do {
- switch (downsampling) {
- case Day:
+ switch (step) {
+ case DAY:
dateTime = dateTime.plusDays(1);
String timeBucket = YYYYMMDD.print(dateTime);
- durations.add(new DurationPoint(Long.parseLong(timeBucket), secondsBetween(downsampling, dateTime),
- minutesBetween(downsampling, dateTime)
- ));
+ durations.add(new PointOfTime(Long.parseLong(timeBucket)));
break;
- case Hour:
+ case HOUR:
dateTime = dateTime.plusHours(1);
timeBucket = YYYYMMDDHH.print(dateTime);
- durations.add(new DurationPoint(Long.parseLong(timeBucket), secondsBetween(downsampling, dateTime),
- minutesBetween(downsampling, dateTime)
- ));
+ durations.add(new PointOfTime(Long.parseLong(timeBucket)));
break;
- case Minute:
+ case MINUTE:
dateTime = dateTime.plusMinutes(1);
timeBucket = YYYYMMDDHHMM.print(dateTime);
- durations.add(new DurationPoint(Long.parseLong(timeBucket), secondsBetween(downsampling, dateTime),
- minutesBetween(downsampling, dateTime)
- ));
+ durations.add(new PointOfTime(Long.parseLong(timeBucket)));
break;
- case Second:
+ case SECOND:
dateTime = dateTime.plusSeconds(1);
timeBucket = YYYYMMDDHHMMSS.print(dateTime);
- durations.add(new DurationPoint(Long.parseLong(timeBucket), secondsBetween(downsampling, dateTime),
- minutesBetween(downsampling, dateTime)
- ));
+ durations.add(new PointOfTime(Long.parseLong(timeBucket)));
break;
}
i++;
if (i > 500) {
throw new UnexpectedException(
- "Duration data error, step: " + downsampling.name() + ", start: " + startTimeBucket + ", end: " + endTimeBucket);
+ "Duration data error, step: " + step.name() + ", start: " + startTimeBucket + ", end: " + endTimeBucket);
}
}
while (endTimeBucket != durations.get(durations.size() - 1).getPoint());
@@ -192,17 +182,17 @@ public enum DurationUtils {
return durations;
}
- private DateTime parseToDateTime(DownSampling downsampling, long time) {
- switch (downsampling) {
- case Day:
+ private DateTime parseToDateTime(Step step, long time) {
+ switch (step) {
+ case DAY:
return YYYYMMDD.parseDateTime(String.valueOf(time));
- case Hour:
+ case HOUR:
return YYYYMMDDHH.parseDateTime(String.valueOf(time));
- case Minute:
+ case MINUTE:
return YYYYMMDDHHMM.parseDateTime(String.valueOf(time));
- case Second:
+ case SECOND:
return YYYYMMDDHHMMSS.parseDateTime(String.valueOf(time));
}
- throw new UnexpectedException("Unexpected downsampling: " + downsampling.name());
+ throw new UnexpectedException("Unexpected downsampling: " + step.name());
}
}
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/MetricQueryService.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/MetricQueryService.java
deleted file mode 100644
index 53450ea..0000000
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/MetricQueryService.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * 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.oap.server.core.query;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import org.apache.skywalking.apm.util.StringUtil;
-import org.apache.skywalking.oap.server.core.Const;
-import org.apache.skywalking.oap.server.core.analysis.DownSampling;
-import org.apache.skywalking.oap.server.core.analysis.metrics.Metrics;
-import org.apache.skywalking.oap.server.core.query.type.IntValues;
-import org.apache.skywalking.oap.server.core.query.type.Thermodynamic;
-import org.apache.skywalking.oap.server.core.query.sql.KeyValues;
-import org.apache.skywalking.oap.server.core.query.sql.Where;
-import org.apache.skywalking.oap.server.core.storage.StorageModule;
-import org.apache.skywalking.oap.server.core.storage.annotation.ValueColumnMetadata;
-import org.apache.skywalking.oap.server.core.storage.query.IMetricsQueryDAO;
-import org.apache.skywalking.oap.server.library.module.ModuleManager;
-import org.apache.skywalking.oap.server.library.module.Service;
-import org.apache.skywalking.oap.server.library.util.CollectionUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class MetricQueryService implements Service {
-
- private static final Logger logger = LoggerFactory.getLogger(MetricQueryService.class);
-
- private final ModuleManager moduleManager;
- private IMetricsQueryDAO metricQueryDAO;
-
- public MetricQueryService(ModuleManager moduleManager) {
- this.moduleManager = moduleManager;
- }
-
- private IMetricsQueryDAO getMetricQueryDAO() {
- if (metricQueryDAO == null) {
- metricQueryDAO = moduleManager.find(StorageModule.NAME).provider().getService(IMetricsQueryDAO.class);
- }
- return metricQueryDAO;
- }
-
- public IntValues getValues(final String metricsName, final List<String> ids, final DownSampling downsampling,
- final long startTB, final long endTB) throws IOException {
- if (CollectionUtils.isEmpty(ids)) {
- /*
- * Don't support query values w/o ID. but UI still did this(as bug),
- * we return an empty list, and a debug level log,
- * rather than an exception, which always being considered as a serious error from new users.
- */
- logger.debug("query metrics[{}] w/o IDs", metricsName);
- return new IntValues();
- }
-
- Where where = new Where();
- KeyValues intKeyValues = new KeyValues();
- intKeyValues.setKey(Metrics.ENTITY_ID);
- where.getKeyValues().add(intKeyValues);
- ids.forEach(intKeyValues.getValues()::add);
-
- return getMetricQueryDAO().getValues(metricsName, downsampling, startTB, endTB, where, ValueColumnMetadata.INSTANCE.getValueCName(metricsName), ValueColumnMetadata.INSTANCE
- .getValueFunction(metricsName));
- }
-
- public IntValues getLinearIntValues(final String indName, final String id, final DownSampling downsampling,
- final long startTB, final long endTB) throws IOException {
- List<DurationPoint> durationPoints = DurationUtils.INSTANCE.getDurationPoints(downsampling, startTB, endTB);
- List<String> ids = new ArrayList<>();
- if (StringUtil.isEmpty(id)) {
- durationPoints.forEach(durationPoint -> ids.add(String.valueOf(durationPoint.getPoint())));
- } else {
- durationPoints.forEach(durationPoint -> ids.add(durationPoint.getPoint() + Const.ID_CONNECTOR + id));
- }
-
- return getMetricQueryDAO().getLinearIntValues(indName, downsampling, ids, ValueColumnMetadata.INSTANCE.getValueCName(indName));
- }
-
- public List<IntValues> getMultipleLinearIntValues(final String indName, final String id, final int numOfLinear,
- final DownSampling downsampling, final long startTB, final long endTB) throws IOException {
- List<Integer> linearIndex = new ArrayList<>(numOfLinear);
- for (int i = 0; i < numOfLinear; i++) {
- linearIndex.add(i);
- }
-
- return getSubsetOfMultipleLinearIntValues(indName, id, linearIndex, downsampling, startTB, endTB);
- }
-
- public List<IntValues> getSubsetOfMultipleLinearIntValues(final String indName, final String id,
- final List<Integer> linearIndex, final DownSampling downsampling, final long startTB,
- final long endTB) throws IOException {
- List<DurationPoint> durationPoints = DurationUtils.INSTANCE.getDurationPoints(downsampling, startTB, endTB);
- List<String> ids = new ArrayList<>();
- if (StringUtil.isEmpty(id)) {
- durationPoints.forEach(durationPoint -> ids.add(String.valueOf(durationPoint.getPoint())));
- } else {
- durationPoints.forEach(durationPoint -> ids.add(durationPoint.getPoint() + Const.ID_CONNECTOR + id));
- }
-
- IntValues[] multipleLinearIntValues = getMetricQueryDAO().getMultipleLinearIntValues(indName, downsampling, ids, linearIndex, ValueColumnMetadata.INSTANCE
- .getValueCName(indName));
-
- List<IntValues> response = new ArrayList<>(linearIndex.size());
- Collections.addAll(response, multipleLinearIntValues);
- return response;
- }
-
- public Thermodynamic getThermodynamic(final String indName, final String id, final DownSampling downsampling,
- final long startTB, final long endTB) throws IOException {
- List<DurationPoint> durationPoints = DurationUtils.INSTANCE.getDurationPoints(downsampling, startTB, endTB);
- List<String> ids = new ArrayList<>();
- durationPoints.forEach(durationPoint -> {
- if (id == null) {
- ids.add(String.valueOf(durationPoint.getPoint()));
- } else {
- ids.add(durationPoint.getPoint() + Const.ID_CONNECTOR + id);
- }
- });
-
- return getMetricQueryDAO().getThermodynamic(indName, downsampling, ids, ValueColumnMetadata.INSTANCE.getValueCName(indName));
- }
-}
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/MetricsQueryService.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/MetricsQueryService.java
new file mode 100644
index 0000000..f44952c
--- /dev/null
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/MetricsQueryService.java
@@ -0,0 +1,85 @@
+/*
+ * 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.oap.server.core.query;
+
+import java.io.IOException;
+import java.util.List;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.skywalking.oap.server.core.query.input.Duration;
+import org.apache.skywalking.oap.server.core.query.input.MetricsCondition;
+import org.apache.skywalking.oap.server.core.query.type.HeatMap;
+import org.apache.skywalking.oap.server.core.query.type.MetricsValues;
+import org.apache.skywalking.oap.server.core.storage.StorageModule;
+import org.apache.skywalking.oap.server.core.storage.annotation.ValueColumnMetadata;
+import org.apache.skywalking.oap.server.core.storage.query.IMetricsQueryDAO;
+import org.apache.skywalking.oap.server.library.module.ModuleManager;
+import org.apache.skywalking.oap.server.library.module.Service;
+
+@Slf4j
+public class MetricsQueryService implements Service {
+ private final ModuleManager moduleManager;
+ private IMetricsQueryDAO metricQueryDAO;
+
+ public MetricsQueryService(ModuleManager moduleManager) {
+ this.moduleManager = moduleManager;
+ }
+
+ private IMetricsQueryDAO getMetricQueryDAO() {
+ if (metricQueryDAO == null) {
+ metricQueryDAO = moduleManager.find(StorageModule.NAME).provider().getService(IMetricsQueryDAO.class);
+ }
+ return metricQueryDAO;
+ }
+
+ /**
+ * Read metrics single value in the duration of required metrics
+ */
+ public int readMetricsValue(MetricsCondition condition, Duration duration) throws IOException {
+ return getMetricQueryDAO().readMetricsValue(
+ condition, ValueColumnMetadata.INSTANCE.getValueCName(condition.getName()), duration);
+ }
+
+ /**
+ * Read time-series values in the duration of required metrics
+ */
+ public MetricsValues readMetricsValues(MetricsCondition condition, Duration duration) throws IOException {
+ return getMetricQueryDAO().readMetricsValues(
+ condition, ValueColumnMetadata.INSTANCE.getValueCName(condition.getName()), duration);
+ }
+
+ /**
+ * Read value in the given time duration, usually as a linear.
+ *
+ * @param labels the labels you need to query.
+ */
+ public List<MetricsValues> readLabeledMetricsValues(MetricsCondition condition,
+ List<String> labels,
+ Duration duration) throws IOException {
+ return getMetricQueryDAO().readLabeledMetricsValues(
+ condition, ValueColumnMetadata.INSTANCE.getValueCName(condition.getName()), labels, duration);
+ }
+
+ /**
+ * Heatmap is bucket based value statistic result.
+ */
+ public HeatMap readHeatMap(MetricsCondition condition, Duration duration) throws IOException {
+ return getMetricQueryDAO().readHeatMap(
+ condition, ValueColumnMetadata.INSTANCE.getValueCName(condition.getName()), duration);
+ }
+}
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/DurationPoint.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/PointOfTime.java
similarity index 66%
rename from oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/DurationPoint.java
rename to oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/PointOfTime.java
index 049a9bc..67549e0 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/DurationPoint.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/PointOfTime.java
@@ -18,26 +18,28 @@
package org.apache.skywalking.oap.server.core.query;
-public class DurationPoint {
+import lombok.Getter;
+import org.apache.skywalking.oap.server.core.Const;
+
+/**
+ * PointOfTime represents any point of time based on different precisions.
+ */
+@Getter
+public class PointOfTime {
private long point;
- private long secondsBetween;
- private long minutesBetween;
- public DurationPoint(long point, long secondsBetween, long minutesBetween) {
+ public PointOfTime(long point) {
this.point = point;
- this.secondsBetween = secondsBetween;
- this.minutesBetween = minutesBetween;
- }
-
- public long getPoint() {
- return point;
- }
-
- public long getSecondsBetween() {
- return secondsBetween;
}
- public long getMinutesBetween() {
- return minutesBetween;
+ /**
+ * @return the row id
+ */
+ public String id(String entityId) {
+ if (entityId == null) {
+ return String.valueOf(point);
+ } else {
+ return point + Const.ID_CONNECTOR + entityId;
+ }
}
-}
+}
\ No newline at end of file
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/StepToDownSampling.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/StepToDownSampling.java
deleted file mode 100644
index fd0472d..0000000
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/StepToDownSampling.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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.oap.server.core.query;
-
-import org.apache.skywalking.oap.server.core.UnexpectedException;
-import org.apache.skywalking.oap.server.core.analysis.DownSampling;
-import org.apache.skywalking.oap.server.core.query.enumeration.Step;
-
-public class StepToDownSampling {
-
- public static DownSampling transform(Step step) {
- switch (step) {
- case SECOND:
- return DownSampling.Second;
- case MINUTE:
- return DownSampling.Minute;
- case HOUR:
- return DownSampling.Hour;
- case DAY:
- return DownSampling.Day;
- }
- throw new UnexpectedException("Unknown step value.");
- }
-}
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/input/Duration.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/input/Duration.java
index 7605ce0..f3895b3 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/input/Duration.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/input/Duration.java
@@ -18,6 +18,8 @@
package org.apache.skywalking.oap.server.core.query.input;
+import java.util.List;
+import org.apache.skywalking.oap.server.core.query.PointOfTime;
import org.apache.skywalking.oap.server.core.query.DurationUtils;
import org.apache.skywalking.oap.server.core.query.enumeration.Step;
@@ -39,4 +41,11 @@ public class Duration {
public long getEndTimeBucket() {
return DurationUtils.INSTANCE.convertToTimeBucket(end);
}
+
+ /**
+ * Assemble time point based on {@link #step} and {@link #start} / {@link #end}
+ */
+ public List<PointOfTime> assembleDurationPoints() {
+ return DurationUtils.INSTANCE.getDurationPoints(step, getStartTimeBucket(), getEndTimeBucket());
+ }
}
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/input/Entity.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/input/Entity.java
index 644c4e3..6e9f732 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/input/Entity.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/input/Entity.java
@@ -20,6 +20,7 @@ package org.apache.skywalking.oap.server.core.query.input;
import lombok.Getter;
import lombok.Setter;
+import org.apache.skywalking.oap.server.core.analysis.IDManager;
import org.apache.skywalking.oap.server.core.query.enumeration.Scope;
/**
@@ -60,9 +61,52 @@ public class Entity {
private String destServiceInstanceName;
private String destEndpointName;
- public boolean isService(){
+ public boolean isService() {
return Scope.Service.equals(scope);
}
-
+ /**
+ * @return entity id based on the definition.
+ */
+ public String buildId() {
+ switch (scope) {
+ case All:
+ // This is unnecessary. Just for making core clear.
+ return null;
+ case Service:
+ return IDManager.ServiceID.buildId(serviceName, isNormal);
+ case ServiceInstance:
+ return IDManager.ServiceInstanceID.buildId(
+ IDManager.ServiceID.buildId(serviceName, isNormal), serviceInstanceName);
+ case Endpoint:
+ return IDManager.EndpointID.buildId(IDManager.ServiceID.buildId(serviceName, isNormal), endpointName);
+ case ServiceRelation:
+ return IDManager.ServiceID.buildRelationId(
+ new IDManager.ServiceID.ServiceRelationDefine(
+ IDManager.ServiceID.buildId(serviceName, isNormal),
+ IDManager.ServiceID.buildId(destServiceName, destIsNormal)
+ )
+ );
+ case ServiceInstanceRelation:
+ return IDManager.ServiceInstanceID.buildRelationId(
+ new IDManager.ServiceInstanceID.ServiceInstanceRelationDefine(
+ IDManager.ServiceInstanceID.buildId(
+ IDManager.ServiceID.buildId(serviceName, isNormal), serviceInstanceName),
+ IDManager.ServiceInstanceID.buildId(
+ IDManager.ServiceID.buildId(destServiceName, destIsNormal), destServiceInstanceName)
+ )
+ );
+ case EndpointRelation:
+ return IDManager.EndpointID.buildRelationId(
+ new IDManager.EndpointID.EndpointRelationDefine(
+ IDManager.ServiceID.buildId(serviceName, isNormal),
+ endpointName,
+ IDManager.ServiceID.buildId(destServiceName, destIsNormal),
+ destEndpointName
+ )
+ );
+ default:
+ return null;
+ }
+ }
}
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/input/MetricsCondition.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/input/MetricsCondition.java
index f5ed21f..11c1232 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/input/MetricsCondition.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/input/MetricsCondition.java
@@ -18,9 +18,14 @@
package org.apache.skywalking.oap.server.core.query.input;
+import lombok.Getter;
+import lombok.Setter;
+
/**
* @since 8.0.0
*/
+@Getter
+@Setter
public class MetricsCondition {
/**
* Metrics name
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/Bucket.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/Bucket.java
index cb8ec34..f5aec3e 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/Bucket.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/Bucket.java
@@ -18,13 +18,25 @@
package org.apache.skywalking.oap.server.core.query.type;
+import lombok.AllArgsConstructor;
import lombok.Setter;
/**
* @since 8.0.0
*/
@Setter
+@AllArgsConstructor
public class Bucket {
- private int start;
- private int end;
+ /**
+ * The min value of this bucket representing.
+ */
+ private int min;
+ /**
+ * The max value of this bucket representing.
+ */
+ private int max;
+
+ public int duration() {
+ return this.max - this.min;
+ }
}
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/HeatMap.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/HeatMap.java
index 68d3001..a5cb600 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/HeatMap.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/HeatMap.java
@@ -19,8 +19,11 @@
package org.apache.skywalking.oap.server.core.query.type;
import java.util.ArrayList;
+import java.util.Comparator;
import java.util.List;
import lombok.Getter;
+import lombok.Setter;
+import org.apache.skywalking.oap.server.core.analysis.metrics.DataTable;
/**
* HeatMap represents the value distribution in the defined buckets.
@@ -29,6 +32,76 @@ import lombok.Getter;
*/
@Getter
public class HeatMap {
- private List<IntValues> values = new ArrayList<>(10);
+ private List<HeatMapColumn> values = new ArrayList<>(10);
private List<Bucket> buckets = new ArrayList<>(10);
+
+ public void addBucket(Bucket bucket) {
+ this.buckets.add(bucket);
+ }
+
+ /**
+ * Build one heatmap value column based on rawdata in the storage and row id.
+ *
+ * @param id of the row
+ * @param rawdata literal string, represent a {@link DataTable}
+ */
+ public void buildColumn(String id, String rawdata) {
+ DataTable dataset = new DataTable(rawdata);
+
+ final List<String> sortedKeys = dataset.sortedKeys(
+ Comparator.comparingInt(Integer::parseInt));
+ if (buckets == null) {
+ buckets = new ArrayList<>(dataset.size());
+ for (int i = 0; i < sortedKeys.size(); i++) {
+ if (i == 0) {
+ this.addBucket(new Bucket(0, Integer.parseInt(sortedKeys.get(i))));
+ } else {
+ this.addBucket(new Bucket(
+ Integer.parseInt(sortedKeys.get(i - 1)),
+ Integer.parseInt(sortedKeys.get(i))
+ ));
+ }
+ }
+ }
+
+ HeatMap.HeatMapColumn column = new HeatMap.HeatMapColumn();
+ column.setId(id);
+ sortedKeys.forEach(key -> {
+ column.addValue(dataset.get(key));
+
+ });
+ }
+
+ public void fixMissingColumns(List<String> ids) {
+ for (int i = 0; i < ids.size(); i++) {
+ final String expectedId = ids.get(i);
+ final HeatMapColumn column = values.get(i);
+ if (expectedId.equals(column.id)) {
+ continue;
+ } else {
+ final HeatMapColumn emptyColumn = buildMissingColumn(expectedId);
+ values.add(i, emptyColumn);
+ }
+ }
+ }
+
+ private HeatMapColumn buildMissingColumn(String id) {
+ HeatMapColumn column = new HeatMapColumn();
+ column.setId(id);
+ buckets.forEach(bucket -> {
+ column.addValue(0L);
+ });
+ return column;
+ }
+
+ @Getter
+ public static class HeatMapColumn {
+ @Setter
+ private String id;
+ private List<Long> values = new ArrayList<>();
+
+ public void addValue(Long value) {
+ values.add(value);
+ }
+ }
}
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/IntValues.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/IntValues.java
index 6fd7200..53fdf91 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/IntValues.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/IntValues.java
@@ -18,11 +18,11 @@
package org.apache.skywalking.oap.server.core.query.type;
-import java.util.LinkedList;
+import java.util.ArrayList;
+import java.util.List;
public class IntValues {
-
- private LinkedList<KVInt> values = new LinkedList<>();
+ private List<KVInt> values = new ArrayList<>();
public void addKVInt(KVInt e) {
values.add(e);
@@ -36,17 +36,4 @@ public class IntValues {
}
return defaultValue;
}
-
- public KVInt getLast() {
- return values.getLast();
- }
-
- public boolean contain(String id) {
- for (KVInt value : values) {
- if (value.getId().equals(id)) {
- return true;
- }
- }
- return false;
- }
}
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/Thermodynamic.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/Thermodynamic.java
index 8a79408..1164607 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/Thermodynamic.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/type/Thermodynamic.java
@@ -23,6 +23,10 @@ import java.util.List;
import lombok.Getter;
import lombok.Setter;
+/**
+ * Replaced by {@link HeatMap}
+ */
+@Deprecated
@Getter
public class Thermodynamic {
private final List<List<Long>> nodes;
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/annotation/Column.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/annotation/Column.java
index 8c2f703..6a8ddb5 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/annotation/Column.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/annotation/Column.java
@@ -48,6 +48,11 @@ public @interface Column {
Function function() default Function.None;
/**
+ * The default value of this column, when its {@link #isValue()} == true.
+ */
+ int defaultValue() default 0;
+
+ /**
* Match query means using analyzer(if storage have) to do key word match query.
*/
boolean matchQuery() default false;
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/annotation/ValueColumnMetadata.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/annotation/ValueColumnMetadata.java
index 174f277..968262f 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/annotation/ValueColumnMetadata.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/annotation/ValueColumnMetadata.java
@@ -20,6 +20,7 @@ package org.apache.skywalking.oap.server.core.storage.annotation;
import java.util.HashMap;
import java.util.Map;
+import lombok.RequiredArgsConstructor;
import org.apache.skywalking.oap.server.core.query.sql.Function;
/**
@@ -34,8 +35,8 @@ public enum ValueColumnMetadata {
/**
* Register the new metadata for the given model name.
*/
- public void putIfAbsent(String modelName, String valueCName, Function function) {
- mapping.putIfAbsent(modelName, new ValueColumn(valueCName, function));
+ public void putIfAbsent(String modelName, String valueCName, Function function, int defaultValue) {
+ mapping.putIfAbsent(modelName, new ValueColumn(valueCName, function, defaultValue));
}
/**
@@ -52,6 +53,10 @@ public enum ValueColumnMetadata {
return findColumn(metricsName).function;
}
+ public int getDefaultValue(String metricsName) {
+ return findColumn(metricsName).defaultValue;
+ }
+
private ValueColumn findColumn(String metricsName) {
ValueColumn column = mapping.get(metricsName);
if (column == null) {
@@ -60,13 +65,10 @@ public enum ValueColumnMetadata {
return column;
}
+ @RequiredArgsConstructor
class ValueColumn {
private final String valueCName;
private final Function function;
-
- private ValueColumn(String valueCName, Function function) {
- this.valueCName = valueCName;
- this.function = function;
- }
+ private final int defaultValue;
}
}
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/model/ModelColumn.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/model/ModelColumn.java
index 890c9b0..7f8c9a0 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/model/ModelColumn.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/model/ModelColumn.java
@@ -20,7 +20,7 @@ package org.apache.skywalking.oap.server.core.storage.model;
import com.google.gson.JsonObject;
import lombok.Getter;
-import org.apache.skywalking.oap.server.core.analysis.metrics.IntKeyLongValueHashMap;
+import org.apache.skywalking.oap.server.core.analysis.metrics.DataTable;
@Getter
public class ModelColumn {
@@ -51,7 +51,7 @@ public class ModelColumn {
/*
* byte[] and {@link IntKeyLongValueHashMap} could never be query.
*/
- if (type.equals(byte[].class) || type.equals(IntKeyLongValueHashMap.class)) {
+ if (type.equals(byte[].class) || type.equals(DataTable.class)) {
this.storageOnly = true;
} else {
if (storageOnly && isValue) {
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/query/IMetricsQueryDAO.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/query/IMetricsQueryDAO.java
index 3311cfc..e9ca2b2 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/query/IMetricsQueryDAO.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/query/IMetricsQueryDAO.java
@@ -20,24 +20,28 @@ package org.apache.skywalking.oap.server.core.storage.query;
import java.io.IOException;
import java.util.List;
-import org.apache.skywalking.oap.server.core.analysis.DownSampling;
-import org.apache.skywalking.oap.server.core.query.type.IntValues;
-import org.apache.skywalking.oap.server.core.query.type.Thermodynamic;
-import org.apache.skywalking.oap.server.core.query.sql.Function;
-import org.apache.skywalking.oap.server.core.query.sql.Where;
+import org.apache.skywalking.oap.server.core.query.input.Duration;
+import org.apache.skywalking.oap.server.core.query.input.MetricsCondition;
+import org.apache.skywalking.oap.server.core.query.type.HeatMap;
+import org.apache.skywalking.oap.server.core.query.type.MetricsValues;
import org.apache.skywalking.oap.server.core.storage.DAO;
+/**
+ * Query metrics values in different formats.
+ *
+ * @since 8.0.0
+ */
public interface IMetricsQueryDAO extends DAO {
+ int readMetricsValue(MetricsCondition condition, String valueColumnName, Duration duration) throws IOException;
- IntValues getValues(String indName, DownSampling downsampling, long startTB, long endTB, Where where,
- String valueCName, Function function) throws IOException;
-
- IntValues getLinearIntValues(String indName, DownSampling downsampling, List<String> ids,
- String valueCName) throws IOException;
+ MetricsValues readMetricsValues(MetricsCondition condition,
+ String valueColumnName,
+ Duration duration) throws IOException;
- IntValues[] getMultipleLinearIntValues(String indName, DownSampling downsampling, List<String> ids,
- List<Integer> linearIndex, String valueCName) throws IOException;
+ List<MetricsValues> readLabeledMetricsValues(MetricsCondition condition,
+ String valueColumnName,
+ List<String> labels,
+ Duration duration) throws IOException;
- Thermodynamic getThermodynamic(String indName, DownSampling downsampling, List<String> ids,
- String valueCName) throws IOException;
+ HeatMap readHeatMap(MetricsCondition condition, String valueColumnName, Duration duration) throws IOException;
}
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/type/StorageDataComplexObject.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/type/StorageDataComplexObject.java
index 079c0e1..15f1da6 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/type/StorageDataComplexObject.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/type/StorageDataComplexObject.java
@@ -21,7 +21,7 @@ package org.apache.skywalking.oap.server.core.storage.type;
/**
* StorageDataComplexObject implementation supports String-Object interconversion.
*/
-public interface StorageDataComplexObject {
+public interface StorageDataComplexObject<T> {
/**
* @return string representing this object.
*/
@@ -35,5 +35,5 @@ public interface StorageDataComplexObject {
/**
* Initialize the object based on the given source.
*/
- void copyFrom(Object source);
+ void append(T source);
}
diff --git a/oap-server/server-core/src/main/proto/RemoteService.proto b/oap-server/server-core/src/main/proto/RemoteService.proto
index 48b9ca3..5303f43 100644
--- a/oap-server/server-core/src/main/proto/RemoteService.proto
+++ b/oap-server/server-core/src/main/proto/RemoteService.proto
@@ -36,16 +36,6 @@ message RemoteData {
repeated int64 dataLongs = 2;
repeated double dataDoubles = 3;
repeated int32 dataIntegers = 4;
- repeated DataIntLongPairList dataLists = 5;
-}
-
-message DataIntLongPairList {
- repeated IntKeyLongValuePair value = 1;
-}
-
-message IntKeyLongValuePair {
- int32 key = 1;
- int64 value = 2;
}
message Empty {
diff --git a/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/analysis/metrics/IntKeyLongValueHashMapTestCase.java b/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/analysis/metrics/DataTableTestCase.java
similarity index 51%
rename from oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/analysis/metrics/IntKeyLongValueHashMapTestCase.java
rename to oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/analysis/metrics/DataTableTestCase.java
index 8d8a7da..f51d537 100644
--- a/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/analysis/metrics/IntKeyLongValueHashMapTestCase.java
+++ b/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/analysis/metrics/DataTableTestCase.java
@@ -21,9 +21,9 @@ import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
-public class IntKeyLongValueHashMapTestCase {
+public class DataTableTestCase {
- private IntKeyLongValueHashMap intKeyLongValueHashMap;
+ private DataTable dataTable;
@Before
public void init() {
@@ -33,36 +33,36 @@ public class IntKeyLongValueHashMapTestCase {
IntKeyLongValue v4 = new IntKeyLongValue(2, 200);
IntKeyLongValue v5 = new IntKeyLongValue(7, 700);
- intKeyLongValueHashMap = new IntKeyLongValueHashMap();
- intKeyLongValueHashMap.put(v1.getKey(), v1);
- intKeyLongValueHashMap.put(v2.getKey(), v2);
- intKeyLongValueHashMap.put(v3.getKey(), v3);
- intKeyLongValueHashMap.put(v4.getKey(), v4);
- intKeyLongValueHashMap.put(v5.getKey(), v5);
+ dataTable = new DataTable();
+ dataTable.put(v1.getKey(), v1);
+ dataTable.put(v2.getKey(), v2);
+ dataTable.put(v3.getKey(), v3);
+ dataTable.put(v4.getKey(), v4);
+ dataTable.put(v5.getKey(), v5);
}
@Test
public void toStorageData() {
- Assert.assertEquals("1,100|2,200|5,500|6,600|7,700", intKeyLongValueHashMap.toStorageData());
+ Assert.assertEquals("1,100|2,200|5,500|6,600|7,700", dataTable.toStorageData());
}
@Test
public void toObject() {
- IntKeyLongValueHashMap intKeyLongValueHashMap = new IntKeyLongValueHashMap();
- intKeyLongValueHashMap.toObject("1,100|2,200|5,500|6,600|7,700");
+ DataTable dataTable = new DataTable();
+ dataTable.toObject("1,100|2,200|5,500|6,600|7,700");
- Assert.assertEquals(100, intKeyLongValueHashMap.get(1).getValue());
- Assert.assertEquals(200, intKeyLongValueHashMap.get(2).getValue());
- Assert.assertEquals(500, intKeyLongValueHashMap.get(5).getValue());
- Assert.assertEquals(600, intKeyLongValueHashMap.get(6).getValue());
- Assert.assertEquals(700, intKeyLongValueHashMap.get(7).getValue());
+ Assert.assertEquals(100, dataTable.get(1).getValue());
+ Assert.assertEquals(200, dataTable.get(2).getValue());
+ Assert.assertEquals(500, dataTable.get(5).getValue());
+ Assert.assertEquals(600, dataTable.get(6).getValue());
+ Assert.assertEquals(700, dataTable.get(7).getValue());
}
@Test
public void copyFrom() {
- IntKeyLongValueHashMap intKeyLongValueHashMap = new IntKeyLongValueHashMap();
- intKeyLongValueHashMap.copyFrom(this.intKeyLongValueHashMap);
+ DataTable dataTable = new DataTable();
+ dataTable.append(this.dataTable);
- Assert.assertEquals("1,100|2,200|5,500|6,600|7,700", intKeyLongValueHashMap.toStorageData());
+ Assert.assertEquals("1,100|2,200|5,500|6,600|7,700", dataTable.toStorageData());
}
}
diff --git a/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/analysis/metrics/ThermodynamicMetricsTest.java b/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/analysis/metrics/HistogramMetricsTest.java
similarity index 90%
rename from oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/analysis/metrics/ThermodynamicMetricsTest.java
rename to oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/analysis/metrics/HistogramMetricsTest.java
index b9aa988..b683d5d 100644
--- a/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/analysis/metrics/ThermodynamicMetricsTest.java
+++ b/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/analysis/metrics/HistogramMetricsTest.java
@@ -23,13 +23,13 @@ import org.apache.skywalking.oap.server.core.remote.grpc.proto.RemoteData;
import org.junit.Assert;
import org.junit.Test;
-public class ThermodynamicMetricsTest {
+public class HistogramMetricsTest {
private int step = 10; //ms
private int maxNumOfSteps = 10; //count
@Test
public void testEntrance() {
- ThermodynamicMetricsMocker metricsMocker = new ThermodynamicMetricsMocker();
+ HistogramMetricsMocker metricsMocker = new HistogramMetricsMocker();
metricsMocker.combine(2000, step, maxNumOfSteps);
metricsMocker.combine(110, step, maxNumOfSteps);
@@ -45,7 +45,7 @@ public class ThermodynamicMetricsTest {
metricsMocker.combine(100, step, maxNumOfSteps);
metricsMocker.combine(100, step, maxNumOfSteps);
- Map<Integer, IntKeyLongValue> index = metricsMocker.getDetailGroup();
+ Map<Integer, IntKeyLongValue> index = metricsMocker.getDataset();
Assert.assertEquals(4, index.size());
Assert.assertEquals(1, index.get(2).getValue());
@@ -56,7 +56,7 @@ public class ThermodynamicMetricsTest {
@Test
public void testMerge() {
- ThermodynamicMetricsMocker metricsMocker = new ThermodynamicMetricsMocker();
+ HistogramMetricsMocker metricsMocker = new HistogramMetricsMocker();
metricsMocker.combine(2000, step, maxNumOfSteps);
metricsMocker.combine(110, step, maxNumOfSteps);
@@ -66,7 +66,7 @@ public class ThermodynamicMetricsTest {
metricsMocker.combine(50, step, maxNumOfSteps);
metricsMocker.combine(50, step, maxNumOfSteps);
- ThermodynamicMetricsMocker metricsMocker1 = new ThermodynamicMetricsMocker();
+ HistogramMetricsMocker metricsMocker1 = new HistogramMetricsMocker();
metricsMocker1.combine(28, step, maxNumOfSteps);
metricsMocker1.combine(50, step, maxNumOfSteps);
@@ -77,7 +77,7 @@ public class ThermodynamicMetricsTest {
metricsMocker.combine(metricsMocker1);
- Map<Integer, IntKeyLongValue> index = metricsMocker.getDetailGroup();
+ Map<Integer, IntKeyLongValue> index = metricsMocker.getDataset();
Assert.assertEquals(4, index.size());
Assert.assertEquals(1, index.get(2).getValue());
@@ -86,7 +86,7 @@ public class ThermodynamicMetricsTest {
Assert.assertEquals(8, index.get(10).getValue());
}
- public class ThermodynamicMetricsMocker extends ThermodynamicMetrics {
+ public class HistogramMetricsMocker extends HistogramMetrics {
@Override
public String id() {
diff --git a/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/analysis/metrics/PxxMetricsTest.java b/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/analysis/metrics/PxxMetricsTest.java
index dc16629..acbadc1 100644
--- a/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/analysis/metrics/PxxMetricsTest.java
+++ b/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/analysis/metrics/PxxMetricsTest.java
@@ -129,7 +129,7 @@ public class PxxMetricsTest {
@Test
public void testAccurate() {
- IntKeyLongValueHashMap map = new IntKeyLongValueHashMap();
+ DataTable map = new DataTable();
map.toObject("0,109|128,3|130,1|131,1|132,2|5,16|6,23|10,1|12,1|13,25|14,10|15,2|17,1|146,2|18,1|19,16|20,9|21,4|22,1|23,2|152,1|25,4|26,4|27,3|28,1|31,1|32,2|34,1|44,1|318,1|319,7|320,2|321,1|323,1|324,1|325,2|326,1|327,3|328,1|330,2|205,27|206,14|208,1|337,1|219,15|220,2|221,2|222,1|224,1|352,1|225,1|226,3|227,1|229,1|232,2|105,16|233,1|106,13|108,1|113,20|114,4|115,3|116,2|118,6|119,12|120,4|121,4|122,6|250,1|124,4|125,1|126,4|127,2");
PxxMetricsMocker metrics50Mocker = new PxxMetricsMocker(50);
diff --git a/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/storage/model/ModelColumnTest.java b/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/storage/model/ModelColumnTest.java
index e28100c..7c2d0a2 100644
--- a/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/storage/model/ModelColumnTest.java
+++ b/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/storage/model/ModelColumnTest.java
@@ -18,7 +18,7 @@
package org.apache.skywalking.oap.server.core.storage.model;
-import org.apache.skywalking.oap.server.core.analysis.metrics.IntKeyLongValueHashMap;
+import org.apache.skywalking.oap.server.core.analysis.metrics.DataTable;
import org.junit.Assert;
import org.junit.Test;
@@ -31,7 +31,7 @@ public class ModelColumnTest {
Assert.assertEquals(true, column.isStorageOnly());
Assert.assertEquals("abc", column.getColumnName().getName());
- column = new ModelColumn(new ColumnName("", "abc"), IntKeyLongValueHashMap.class, true,
+ column = new ModelColumn(new ColumnName("", "abc"), DataTable.class, true,
false, true, 200
);
Assert.assertEquals(true, column.isStorageOnly());
diff --git a/oap-server/server-query-plugin/query-graphql-plugin/src/main/java/org/apache/skywalking/oap/query/graphql/resolver/MetricQuery.java b/oap-server/server-query-plugin/query-graphql-plugin/src/main/java/org/apache/skywalking/oap/query/graphql/resolver/MetricQuery.java
index 3f33f33..8fe2605 100644
--- a/oap-server/server-query-plugin/query-graphql-plugin/src/main/java/org/apache/skywalking/oap/query/graphql/resolver/MetricQuery.java
+++ b/oap-server/server-query-plugin/query-graphql-plugin/src/main/java/org/apache/skywalking/oap/query/graphql/resolver/MetricQuery.java
@@ -21,15 +21,19 @@ package org.apache.skywalking.oap.query.graphql.resolver;
import com.coxautodev.graphql.tools.GraphQLQueryResolver;
import java.io.IOException;
import java.text.ParseException;
+import java.util.ArrayList;
import java.util.List;
+import lombok.RequiredArgsConstructor;
import org.apache.skywalking.oap.query.graphql.type.BatchMetricConditions;
import org.apache.skywalking.oap.server.core.query.input.Duration;
+import org.apache.skywalking.oap.server.core.query.input.Entity;
import org.apache.skywalking.oap.server.core.query.input.MetricCondition;
-import org.apache.skywalking.oap.server.core.CoreModule;
-import org.apache.skywalking.oap.server.core.query.DurationUtils;
-import org.apache.skywalking.oap.server.core.query.MetricQueryService;
-import org.apache.skywalking.oap.server.core.query.StepToDownSampling;
+import org.apache.skywalking.oap.server.core.query.input.MetricsCondition;
+import org.apache.skywalking.oap.server.core.query.type.Bucket;
+import org.apache.skywalking.oap.server.core.query.type.HeatMap;
import org.apache.skywalking.oap.server.core.query.type.IntValues;
+import org.apache.skywalking.oap.server.core.query.type.KVInt;
+import org.apache.skywalking.oap.server.core.query.type.MetricsValues;
import org.apache.skywalking.oap.server.core.query.type.Thermodynamic;
import org.apache.skywalking.oap.server.library.module.ModuleManager;
@@ -38,64 +42,118 @@ import org.apache.skywalking.oap.server.library.module.ModuleManager;
*/
@Deprecated
public class MetricQuery implements GraphQLQueryResolver {
-
- private final ModuleManager moduleManager;
- private MetricQueryService metricQueryService;
+ private MetricsQuery query;
public MetricQuery(ModuleManager moduleManager) {
- this.moduleManager = moduleManager;
- }
-
- private MetricQueryService getMetricQueryService() {
- if (metricQueryService == null) {
- this.metricQueryService = moduleManager.find(CoreModule.NAME)
- .provider()
- .getService(MetricQueryService.class);
- }
- return metricQueryService;
+ query = new MetricsQuery(moduleManager);
}
public IntValues getValues(final BatchMetricConditions metrics, final Duration duration) throws IOException {
- long startTimeBucket = DurationUtils.INSTANCE.convertToTimeBucket(duration.getStart());
- long endTimeBucket = DurationUtils.INSTANCE.convertToTimeBucket(duration.getEnd());
+ IntValues values = new IntValues();
+ for (final String id : metrics.getIds()) {
+ KVInt kv = new KVInt();
+ kv.setId(id);
+
+ MetricsCondition condition = new MetricsCondition();
+ condition.setName(metrics.getName());
+ condition.setEntity(new MockEntity(id));
- return getMetricQueryService().getValues(metrics.getName(), metrics.getIds(), StepToDownSampling.transform(duration
- .getStep()), startTimeBucket, endTimeBucket);
+ kv.setValue(query.readMetricsValue(condition, duration));
+ }
+
+ return values;
}
public IntValues getLinearIntValues(final MetricCondition metrics,
- final Duration duration) throws IOException, ParseException {
- long startTimeBucket = DurationUtils.INSTANCE.convertToTimeBucket(duration.getStart());
- long endTimeBucket = DurationUtils.INSTANCE.convertToTimeBucket(duration.getEnd());
+ final Duration duration) throws IOException, ParseException {
- return getMetricQueryService().getLinearIntValues(metrics.getName(), metrics.getId(), StepToDownSampling.transform(duration
- .getStep()), startTimeBucket, endTimeBucket);
+ MetricsCondition condition = new MetricsCondition();
+ condition.setName(metrics.getName());
+ condition.setEntity(new MockEntity(metrics.getId()));
+
+ final MetricsValues metricsValues = query.readMetricsValues(condition, duration);
+ return metricsValues.getValues();
}
public List<IntValues> getMultipleLinearIntValues(final MetricCondition metrics, final int numOfLinear,
- final Duration duration) throws IOException, ParseException {
- long startTimeBucket = DurationUtils.INSTANCE.convertToTimeBucket(duration.getStart());
- long endTimeBucket = DurationUtils.INSTANCE.convertToTimeBucket(duration.getEnd());
+ final Duration duration) throws IOException, ParseException {
+ MetricsCondition condition = new MetricsCondition();
+ condition.setName(metrics.getName());
+ condition.setEntity(new MockEntity(metrics.getId()));
+
+ List<String> labels = new ArrayList<>(numOfLinear);
+ for (int i = 0; i < numOfLinear; i++) {
+ labels.add(String.valueOf(i));
+ }
- return getMetricQueryService().getMultipleLinearIntValues(metrics.getName(), metrics.getId(), numOfLinear, StepToDownSampling
- .transform(duration.getStep()), startTimeBucket, endTimeBucket);
+ final List<MetricsValues> metricsValues = query.readLabeledMetricsValues(condition, labels, duration);
+ List<IntValues> response = new ArrayList<>(metricsValues.size());
+ metricsValues.forEach(value -> {
+ response.add(value.getValues());
+ });
+
+ return response;
}
public List<IntValues> getSubsetOfMultipleLinearIntValues(final MetricCondition metrics,
- final List<Integer> linearIndex, final Duration duration) throws IOException, ParseException {
- long startTimeBucket = DurationUtils.INSTANCE.convertToTimeBucket(duration.getStart());
- long endTimeBucket = DurationUtils.INSTANCE.convertToTimeBucket(duration.getEnd());
-
- return getMetricQueryService().getSubsetOfMultipleLinearIntValues(metrics.getName(), metrics.getId(), linearIndex, StepToDownSampling
- .transform(duration.getStep()), startTimeBucket, endTimeBucket);
+ final List<Integer> linearIndex,
+ final Duration duration) throws IOException, ParseException {
+ MetricsCondition condition = new MetricsCondition();
+ condition.setName(metrics.getName());
+ condition.setEntity(new MockEntity(metrics.getId()));
+
+ List<String> labels = new ArrayList<>(linearIndex.size());
+ linearIndex.forEach(i -> labels.add(String.valueOf(i)));
+
+ final List<MetricsValues> metricsValues = query.readLabeledMetricsValues(condition, labels, duration);
+ List<IntValues> response = new ArrayList<>(metricsValues.size());
+ metricsValues.forEach(value -> {
+ response.add(value.getValues());
+ });
+
+ return response;
}
public Thermodynamic getThermodynamic(final MetricCondition metrics,
- final Duration duration) throws IOException, ParseException {
- long startTimeBucket = DurationUtils.INSTANCE.convertToTimeBucket(duration.getStart());
- long endTimeBucket = DurationUtils.INSTANCE.convertToTimeBucket(duration.getEnd());
+ final Duration duration) throws IOException, ParseException {
+ MetricsCondition condition = new MetricsCondition();
+ condition.setName(metrics.getName());
+ condition.setEntity(new MockEntity(metrics.getId()));
+
+ final HeatMap heatMap = query.readHeatMap(condition, duration);
+
+ Thermodynamic thermodynamic = new Thermodynamic();
+ final List<Bucket> buckets = heatMap.getBuckets();
+
+ if (buckets.size() > 0) {
+ // Use the first bucket size as the axis Y step, because in the previous(before 8.x),
+ // We only use equilong bucket.
+ thermodynamic.setAxisYStep(buckets.get(0).duration());
+ } else {
+ // Used to be a static config.
+ thermodynamic.setAxisYStep(200);
+ }
+
+ final List<List<Long>> nodeMatrix = thermodynamic.getNodes();
+ for (int x = 0; x < heatMap.getValues().size(); x++) {
+ final HeatMap.HeatMapColumn heatMapColumn = heatMap.getValues().get(x);
+ List<Long> column = new ArrayList<>(23);
+ for (int y = 0; y < heatMapColumn.getValues().size(); y++) {
+ column.add(heatMapColumn.getValues().get(y));
+ }
+ nodeMatrix.add(column);
+ }
- return getMetricQueryService().getThermodynamic(metrics.getName(), metrics.getId(), StepToDownSampling.transform(duration
- .getStep()), startTimeBucket, endTimeBucket);
+ return thermodynamic;
+ }
+
+ @RequiredArgsConstructor
+ private static class MockEntity extends Entity {
+ private final String id;
+
+ @Override
+ public String buildId() {
+ return id;
+ }
}
}
diff --git a/oap-server/server-query-plugin/query-graphql-plugin/src/main/java/org/apache/skywalking/oap/query/graphql/resolver/MetricsQuery.java b/oap-server/server-query-plugin/query-graphql-plugin/src/main/java/org/apache/skywalking/oap/query/graphql/resolver/MetricsQuery.java
index 6efbb04..a4fb417 100644
--- a/oap-server/server-query-plugin/query-graphql-plugin/src/main/java/org/apache/skywalking/oap/query/graphql/resolver/MetricsQuery.java
+++ b/oap-server/server-query-plugin/query-graphql-plugin/src/main/java/org/apache/skywalking/oap/query/graphql/resolver/MetricsQuery.java
@@ -20,11 +20,10 @@ package org.apache.skywalking.oap.query.graphql.resolver;
import com.coxautodev.graphql.tools.GraphQLQueryResolver;
import java.io.IOException;
-import java.util.Collections;
import java.util.List;
import org.apache.skywalking.oap.server.core.CoreModule;
import org.apache.skywalking.oap.server.core.query.AggregationQueryService;
-import org.apache.skywalking.oap.server.core.query.MetricQueryService;
+import org.apache.skywalking.oap.server.core.query.MetricsQueryService;
import org.apache.skywalking.oap.server.core.query.TopNRecordsQueryService;
import org.apache.skywalking.oap.server.core.query.enumeration.MetricsType;
import org.apache.skywalking.oap.server.core.query.input.Duration;
@@ -42,7 +41,7 @@ import org.apache.skywalking.oap.server.library.module.ModuleManager;
*/
public class MetricsQuery implements GraphQLQueryResolver {
private final ModuleManager moduleManager;
- private MetricQueryService metricQueryService;
+ private MetricsQueryService metricsQueryService;
private AggregationQueryService queryService;
private TopNRecordsQueryService topNRecordsQueryService;
@@ -68,6 +67,15 @@ public class MetricsQuery implements GraphQLQueryResolver {
return topNRecordsQueryService;
}
+ private MetricsQueryService getMetricsQueryService() {
+ if (metricsQueryService == null) {
+ this.metricsQueryService = moduleManager.find(CoreModule.NAME)
+ .provider()
+ .getService(MetricsQueryService.class);
+ }
+ return metricsQueryService;
+ }
+
/**
* Metrics definition metadata query. Response the metrics type which determines the suitable query methods.
*/
@@ -79,14 +87,14 @@ public class MetricsQuery implements GraphQLQueryResolver {
* Read metrics single value in the duration of required metrics
*/
public int readMetricsValue(MetricsCondition condition, Duration duration) throws IOException {
- return 0;
+ return getMetricsQueryService().readMetricsValue(condition, duration);
}
/**
* Read time-series values in the duration of required metrics
*/
- public List<MetricsValues> readMetricsValues(MetricsCondition condition, Duration duration) throws IOException {
- return Collections.emptyList();
+ public MetricsValues readMetricsValues(MetricsCondition condition, Duration duration) throws IOException {
+ return getMetricsQueryService().readMetricsValues(condition, duration);
}
/**
@@ -104,14 +112,14 @@ public class MetricsQuery implements GraphQLQueryResolver {
public List<MetricsValues> readLabeledMetricsValues(MetricsCondition condition,
List<String> labels,
Duration duration) throws IOException {
- return Collections.emptyList();
+ return getMetricsQueryService().readLabeledMetricsValues(condition, labels, duration);
}
/**
* Heatmap is bucket based value statistic result.
*/
public HeatMap readHeatMap(MetricsCondition condition, Duration duration) throws IOException {
- return new HeatMap();
+ return getMetricsQueryService().readHeatMap(condition, duration);
}
/**
diff --git a/oap-server/server-query-plugin/query-graphql-plugin/src/main/resources/query-protocol b/oap-server/server-query-plugin/query-graphql-plugin/src/main/resources/query-protocol
index 01a16ef..3751b2e 160000
--- a/oap-server/server-query-plugin/query-graphql-plugin/src/main/resources/query-protocol
+++ b/oap-server/server-query-plugin/query-graphql-plugin/src/main/resources/query-protocol
@@ -1 +1 @@
-Subproject commit 01a16efbbd53e13709c3fa862065ce45eff05a2a
+Subproject commit 3751b2e570797286cf51ecfdae78a7059d805bac
diff --git a/oap-server/server-storage-plugin/storage-elasticsearch-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch/base/ColumnTypeEsMapping.java b/oap-server/server-storage-plugin/storage-elasticsearch-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch/base/ColumnTypeEsMapping.java
index 45dc635..7eefe65 100644
--- a/oap-server/server-storage-plugin/storage-elasticsearch-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch/base/ColumnTypeEsMapping.java
+++ b/oap-server/server-storage-plugin/storage-elasticsearch-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch/base/ColumnTypeEsMapping.java
@@ -20,7 +20,7 @@ package org.apache.skywalking.oap.server.storage.plugin.elasticsearch.base;
import com.google.gson.JsonObject;
import org.apache.skywalking.oap.server.core.analysis.NodeType;
-import org.apache.skywalking.oap.server.core.analysis.metrics.IntKeyLongValueHashMap;
+import org.apache.skywalking.oap.server.core.analysis.metrics.DataTable;
import org.apache.skywalking.oap.server.core.storage.model.DataTypeMapping;
public class ColumnTypeEsMapping implements DataTypeMapping {
@@ -35,7 +35,7 @@ public class ColumnTypeEsMapping implements DataTypeMapping {
return "double";
} else if (String.class.equals(type)) {
return "keyword";
- } else if (IntKeyLongValueHashMap.class.equals(type)) {
+ } else if (DataTable.class.equals(type)) {
return "text";
} else if (byte[].class.equals(type)) {
return "binary";
diff --git a/oap-server/server-storage-plugin/storage-elasticsearch-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch/query/MetricsQueryEsDAO.java b/oap-server/server-storage-plugin/storage-elasticsearch-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch/query/MetricsQueryEsDAO.java
index 55d8815..983b531 100644
--- a/oap-server/server-storage-plugin/storage-elasticsearch-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch/query/MetricsQueryEsDAO.java
+++ b/oap-server/server-storage-plugin/storage-elasticsearch-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch/query/MetricsQueryEsDAO.java
@@ -25,11 +25,14 @@ import java.util.List;
import java.util.Map;
import org.apache.skywalking.oap.server.core.analysis.DownSampling;
import org.apache.skywalking.oap.server.core.analysis.metrics.IntKeyLongValue;
-import org.apache.skywalking.oap.server.core.analysis.metrics.IntKeyLongValueHashMap;
+import org.apache.skywalking.oap.server.core.analysis.metrics.DataTable;
import org.apache.skywalking.oap.server.core.analysis.metrics.Metrics;
-import org.apache.skywalking.oap.server.core.analysis.metrics.ThermodynamicMetrics;
+import org.apache.skywalking.oap.server.core.analysis.metrics.HistogramMetrics;
+import org.apache.skywalking.oap.server.core.query.input.Duration;
+import org.apache.skywalking.oap.server.core.query.input.MetricsCondition;
import org.apache.skywalking.oap.server.core.query.type.IntValues;
import org.apache.skywalking.oap.server.core.query.type.KVInt;
+import org.apache.skywalking.oap.server.core.query.type.MetricsValues;
import org.apache.skywalking.oap.server.core.query.type.Thermodynamic;
import org.apache.skywalking.oap.server.core.query.sql.Function;
import org.apache.skywalking.oap.server.core.query.sql.Where;
@@ -51,6 +54,20 @@ public class MetricsQueryEsDAO extends EsDAO implements IMetricsQueryDAO {
super(client);
}
+ /**
+ * Read metrics single value in the duration of required metrics
+ */
+ public int readMetricsValue(MetricsCondition condition, Duration duration) throws IOException {
+ return 0;
+ }
+
+ /**
+ * Read time-series values in the duration of required metrics
+ */
+ public MetricsValues readMetricsValues(MetricsCondition condition, Duration duration) throws IOException {
+ return null;
+ }
+
@Override
public IntValues getValues(String indexName, DownSampling downsampling, long startTB, long endTB, Where where,
String valueCName, Function function) throws IOException {
@@ -150,7 +167,7 @@ public class MetricsQueryEsDAO extends EsDAO implements IMetricsQueryDAO {
if (idMap.containsKey(id)) {
Map<String, Object> source = idMap.get(id);
- IntKeyLongValueHashMap multipleValues = new IntKeyLongValueHashMap(5);
+ DataTable multipleValues = new DataTable(5);
multipleValues.toObject((String) source.getOrDefault(valueCName, ""));
for (int i = 0; i < linearIndex.size(); i++) {
@@ -180,12 +197,12 @@ public class MetricsQueryEsDAO extends EsDAO implements IMetricsQueryDAO {
// add empty list to represent no data exist for this time bucket
thermodynamicValueMatrix.add(new ArrayList<>());
} else {
- int axisYStep = ((Number) source.get(ThermodynamicMetrics.STEP)).intValue();
+ int axisYStep = ((Number) source.get(HistogramMetrics.STEP)).intValue();
thermodynamic.setAxisYStep(axisYStep);
- numOfSteps = ((Number) source.get(ThermodynamicMetrics.NUM_OF_STEPS)).intValue() + 1;
+ numOfSteps = ((Number) source.get(HistogramMetrics.NUM_OF_STEPS)).intValue() + 1;
- String value = (String) source.get(ThermodynamicMetrics.DETAIL_GROUP);
- IntKeyLongValueHashMap intKeyLongValues = new IntKeyLongValueHashMap(5);
+ String value = (String) source.get(HistogramMetrics.DATASET);
+ DataTable intKeyLongValues = new DataTable(5);
intKeyLongValues.toObject(value);
List<Long> axisYValues = new ArrayList<>();
diff --git a/oap-server/server-storage-plugin/storage-influxdb-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/influxdb/query/MetricsQuery.java b/oap-server/server-storage-plugin/storage-influxdb-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/influxdb/query/MetricsQuery.java
index 3faf264..0c0fa95 100644
--- a/oap-server/server-storage-plugin/storage-influxdb-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/influxdb/query/MetricsQuery.java
+++ b/oap-server/server-storage-plugin/storage-influxdb-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/influxdb/query/MetricsQuery.java
@@ -28,8 +28,8 @@ import java.util.Map;
import lombok.extern.slf4j.Slf4j;
import org.apache.skywalking.oap.server.core.analysis.DownSampling;
import org.apache.skywalking.oap.server.core.analysis.metrics.IntKeyLongValue;
-import org.apache.skywalking.oap.server.core.analysis.metrics.IntKeyLongValueHashMap;
-import org.apache.skywalking.oap.server.core.analysis.metrics.ThermodynamicMetrics;
+import org.apache.skywalking.oap.server.core.analysis.metrics.DataTable;
+import org.apache.skywalking.oap.server.core.analysis.metrics.HistogramMetrics;
import org.apache.skywalking.oap.server.core.query.type.IntValues;
import org.apache.skywalking.oap.server.core.query.type.KVInt;
import org.apache.skywalking.oap.server.core.query.type.Thermodynamic;
@@ -216,7 +216,7 @@ public class MetricsQuery implements IMetricsQueryDAO {
return intValues;
}
series.get(0).getValues().forEach(values -> {
- IntKeyLongValueHashMap multipleValues = new IntKeyLongValueHashMap(5);
+ DataTable multipleValues = new DataTable(5);
multipleValues.toObject((String) values.get(2));
final String id = (String) values.get(1);
@@ -250,9 +250,9 @@ public class MetricsQuery implements IMetricsQueryDAO {
String valueCName)
throws IOException {
WhereQueryImpl<SelectQueryImpl> query = select()
- .column(ThermodynamicMetrics.STEP)
- .column(ThermodynamicMetrics.NUM_OF_STEPS)
- .column(ThermodynamicMetrics.DETAIL_GROUP)
+ .column(HistogramMetrics.STEP)
+ .column(HistogramMetrics.NUM_OF_STEPS)
+ .column(HistogramMetrics.DATASET)
.column("id")
.from(client.getDatabase(), measurement)
.where(contains("id", Joiner.on("|").join(ids)));
@@ -272,7 +272,7 @@ public class MetricsQuery implements IMetricsQueryDAO {
for (List<Object> values : series.getValues()) {
numOfSteps = (int) values.get(2) + 1;
axisYStep = (int) values.get(1);
- IntKeyLongValueHashMap intKeyLongValues = new IntKeyLongValueHashMap(5);
+ DataTable intKeyLongValues = new DataTable(5);
intKeyLongValues.toObject((String) values.get(3));
List<Long> axisYValues = new ArrayList<>(numOfSteps);
for (int i = 0; i < numOfSteps; i++) {
diff --git a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2MetricsQueryDAO.java b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2MetricsQueryDAO.java
index 91835c5..3335d75 100644
--- a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2MetricsQueryDAO.java
+++ b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2MetricsQueryDAO.java
@@ -26,17 +26,18 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import org.apache.skywalking.oap.server.core.analysis.DownSampling;
-import org.apache.skywalking.oap.server.core.analysis.metrics.IntKeyLongValue;
-import org.apache.skywalking.oap.server.core.analysis.metrics.IntKeyLongValueHashMap;
+import org.apache.skywalking.oap.server.core.analysis.metrics.DataTable;
+import org.apache.skywalking.oap.server.core.analysis.metrics.HistogramMetrics;
import org.apache.skywalking.oap.server.core.analysis.metrics.Metrics;
-import org.apache.skywalking.oap.server.core.analysis.metrics.ThermodynamicMetrics;
+import org.apache.skywalking.oap.server.core.query.PointOfTime;
+import org.apache.skywalking.oap.server.core.query.input.Duration;
+import org.apache.skywalking.oap.server.core.query.input.MetricsCondition;
+import org.apache.skywalking.oap.server.core.query.sql.Function;
+import org.apache.skywalking.oap.server.core.query.type.HeatMap;
import org.apache.skywalking.oap.server.core.query.type.IntValues;
import org.apache.skywalking.oap.server.core.query.type.KVInt;
-import org.apache.skywalking.oap.server.core.query.type.Thermodynamic;
-import org.apache.skywalking.oap.server.core.query.sql.Function;
-import org.apache.skywalking.oap.server.core.query.sql.KeyValues;
-import org.apache.skywalking.oap.server.core.query.sql.Where;
+import org.apache.skywalking.oap.server.core.query.type.MetricsValues;
+import org.apache.skywalking.oap.server.core.storage.annotation.ValueColumnMetadata;
import org.apache.skywalking.oap.server.core.storage.query.IMetricsQueryDAO;
import org.apache.skywalking.oap.server.library.client.jdbc.hikaricp.JDBCHikariCPClient;
@@ -49,9 +50,10 @@ public class H2MetricsQueryDAO extends H2SQLExecutor implements IMetricsQueryDAO
}
@Override
- public IntValues getValues(String tableName, DownSampling downsampling, long startTB, long endTB, Where where,
- String valueCName, Function function) throws IOException {
- List<KeyValues> whereKeyValues = where.getKeyValues();
+ public int readMetricsValue(final MetricsCondition condition,
+ String valueColumnName,
+ final Duration duration) throws IOException {
+ final Function function = ValueColumnMetadata.INSTANCE.getValueFunction(condition.getName());
String op;
switch (function) {
case Avg:
@@ -60,56 +62,39 @@ public class H2MetricsQueryDAO extends H2SQLExecutor implements IMetricsQueryDAO
default:
op = "sum";
}
- List<String> ids = new ArrayList<>(20);
- StringBuilder whereSql = new StringBuilder();
- if (whereKeyValues.size() > 0) {
- whereSql.append("(");
- for (int i = 0; i < whereKeyValues.size(); i++) {
- if (i != 0) {
- whereSql.append(" or ");
- }
- KeyValues keyValues = whereKeyValues.get(i);
-
- StringBuilder valueCollection = new StringBuilder();
- List<String> values = keyValues.getValues();
- for (int valueIdx = 0; valueIdx < values.size(); valueIdx++) {
- if (valueIdx != 0) {
- valueCollection.append(",");
- }
- String id = values.get(valueIdx);
- ids.add(id);
- valueCollection.append("'").append(id).append("'");
- }
- whereSql.append(keyValues.getKey()).append(" in (").append(valueCollection).append(")");
- }
- whereSql.append(") and ");
- }
- IntValues intValues = new IntValues();
try (Connection connection = h2Client.getConnection()) {
try (ResultSet resultSet = h2Client.executeQuery(
connection,
- "select " + Metrics.ENTITY_ID + " id, " + op + "(" + valueCName + ") value from " + tableName + " where " + whereSql + Metrics.TIME_BUCKET + ">= ? and " + Metrics.TIME_BUCKET + "<=?" + " group by " + Metrics.ENTITY_ID,
- startTB, endTB
+ "select " + Metrics.ENTITY_ID + " id, " + op + "(" + valueColumnName + ") value from " + condition.getName() + " where "
+ + Metrics.ENTITY_ID + " = ? and "
+ + Metrics.TIME_BUCKET + ">= ? and " + Metrics.TIME_BUCKET + "<=?" + " group by " + Metrics.ENTITY_ID,
+ condition.getEntity().buildId(),
+ duration.getStartTimeBucket(),
+ duration.getEndTimeBucket()
)) {
-
while (resultSet.next()) {
- KVInt kv = new KVInt();
- kv.setId(resultSet.getString("id"));
- kv.setValue(resultSet.getLong("value"));
- intValues.addKVInt(kv);
+ return resultSet.getInt("value");
}
}
} catch (SQLException e) {
throw new IOException(e);
}
- return intValues;
+ return ValueColumnMetadata.INSTANCE.getDefaultValue(condition.getName());
}
@Override
- public IntValues getLinearIntValues(String tableName, DownSampling downsampling, List<String> ids,
- String valueCName) throws IOException {
- StringBuilder sql = new StringBuilder("select id, " + valueCName + " from " + tableName + " where id in (");
+ public MetricsValues readMetricsValues(final MetricsCondition condition,
+ final String valueColumnName,
+ final Duration duration) throws IOException {
+ final List<PointOfTime> pointOfTimes = duration.assembleDurationPoints();
+ List<String> ids = new ArrayList<>(pointOfTimes.size());
+ pointOfTimes.forEach(pointOfTime -> {
+ ids.add(pointOfTime.id(condition.getEntity().buildId()));
+ });
+
+ StringBuilder sql = new StringBuilder(
+ "select id, " + valueColumnName + " from " + condition.getName() + " where id in (");
List<Object> parameters = new ArrayList();
for (int i = 0; i < ids.size(); i++) {
if (i == 0) {
@@ -121,7 +106,9 @@ public class H2MetricsQueryDAO extends H2SQLExecutor implements IMetricsQueryDAO
}
sql.append(")");
- IntValues intValues = new IntValues();
+ MetricsValues metricsValues = new MetricsValues();
+ // Label is null, because in readMetricsValues, no label parameter.
+ final IntValues intValues = metricsValues.getValues();
try (Connection connection = h2Client.getConnection()) {
@@ -130,7 +117,7 @@ public class H2MetricsQueryDAO extends H2SQLExecutor implements IMetricsQueryDAO
while (resultSet.next()) {
KVInt kv = new KVInt();
kv.setId(resultSet.getString("id"));
- kv.setValue(resultSet.getLong(valueCName));
+ kv.setValue(resultSet.getLong(valueColumnName));
intValues.addKVInt(kv);
}
}
@@ -138,16 +125,26 @@ public class H2MetricsQueryDAO extends H2SQLExecutor implements IMetricsQueryDAO
throw new IOException(e);
}
- return orderWithDefault0(intValues, ids);
+ metricsValues.setValues(
+ sortValues(intValues, ids, ValueColumnMetadata.INSTANCE.getDefaultValue(condition.getName()))
+ );
+ return metricsValues;
}
@Override
- public IntValues[] getMultipleLinearIntValues(String tableName,
- DownSampling downsampling,
- List<String> ids,
- final List<Integer> linearIndex,
- String valueCName) throws IOException {
- StringBuilder sql = new StringBuilder("select id, " + valueCName + " from " + tableName + " where id in (");
+ public List<MetricsValues> readLabeledMetricsValues(final MetricsCondition condition,
+ final String valueColumnName,
+ final List<String> labels,
+ final Duration duration) throws IOException {
+ final List<PointOfTime> pointOfTimes = duration.assembleDurationPoints();
+ List<String> ids = new ArrayList<>(pointOfTimes.size());
+ pointOfTimes.forEach(pointOfTime -> {
+ ids.add(pointOfTime.id(condition.getEntity().buildId()));
+ });
+
+ StringBuilder sql = new StringBuilder(
+ "select id, " + valueColumnName + " from " + condition.getName() + " where id in (");
+
List<Object> parameters = new ArrayList();
for (int i = 0; i < ids.size(); i++) {
if (i == 0) {
@@ -159,10 +156,13 @@ public class H2MetricsQueryDAO extends H2SQLExecutor implements IMetricsQueryDAO
}
sql.append(")");
- IntValues[] intValuesArray = new IntValues[linearIndex.size()];
- for (int i = 0; i < intValuesArray.length; i++) {
- intValuesArray[i] = new IntValues();
- }
+ Map<String, MetricsValues> labeledValues = new HashMap<>(labels.size());
+ labels.forEach(label -> {
+ MetricsValues labelValue = new MetricsValues();
+ labelValue.setLabel(label);
+
+ labeledValues.put(label, labelValue);
+ });
try (Connection connection = h2Client.getConnection()) {
try (ResultSet resultSet = h2Client.executeQuery(
@@ -170,56 +170,42 @@ public class H2MetricsQueryDAO extends H2SQLExecutor implements IMetricsQueryDAO
while (resultSet.next()) {
String id = resultSet.getString("id");
- IntKeyLongValueHashMap multipleValues = new IntKeyLongValueHashMap(5);
- multipleValues.toObject(resultSet.getString(valueCName));
+ DataTable multipleValues = new DataTable(5);
+ multipleValues.toObject(resultSet.getString(valueColumnName));
- for (int i = 0; i < linearIndex.size(); i++) {
- Integer index = linearIndex.get(i);
+ labels.forEach(label -> {
+ final Long data = multipleValues.get(label);
+ final IntValues values = labeledValues.get(label).getValues();
KVInt kv = new KVInt();
kv.setId(id);
- kv.setValue(multipleValues.get(index).getValue());
- intValuesArray[i].addKVInt(kv);
- }
+ kv.setValue(data);
+ values.addKVInt(kv);
+ });
}
}
} catch (SQLException e) {
throw new IOException(e);
}
- return orderWithDefault0(intValuesArray, ids);
+ return sortValues(
+ new ArrayList<>(labeledValues.values()),
+ ids,
+ ValueColumnMetadata.INSTANCE.getDefaultValue(condition.getName())
+ );
}
- /**
- * Make sure the order is same as the expected order, and keep default value as 0.
- */
- private IntValues orderWithDefault0(IntValues origin, List<String> expectedOrder) {
- IntValues intValues = new IntValues();
-
- expectedOrder.forEach(id -> {
- KVInt e = new KVInt();
- e.setId(id);
- e.setValue(origin.findValue(id, 0));
- intValues.addKVInt(e);
+ @Override
+ public HeatMap readHeatMap(final MetricsCondition condition,
+ final String valueColumnName,
+ final Duration duration) throws IOException {
+ final List<PointOfTime> pointOfTimes = duration.assembleDurationPoints();
+ List<String> ids = new ArrayList<>(pointOfTimes.size());
+ pointOfTimes.forEach(pointOfTime -> {
+ ids.add(pointOfTime.id(condition.getEntity().buildId()));
});
- return intValues;
- }
-
- /**
- * Make sure the order is same as the expected order, and keep default value as 0.
- */
- private IntValues[] orderWithDefault0(IntValues[] origin, List<String> expectedOrder) {
- for (int i = 0; i < origin.length; i++) {
- origin[i] = orderWithDefault0(origin[i], expectedOrder);
- }
- return origin;
- }
-
- @Override
- public Thermodynamic getThermodynamic(String tableName, DownSampling downsampling, List<String> ids,
- String valueCName) throws IOException {
StringBuilder sql = new StringBuilder(
- "select " + ThermodynamicMetrics.STEP + " step, " + ThermodynamicMetrics.NUM_OF_STEPS + " num_of_steps, " + ThermodynamicMetrics.DETAIL_GROUP + " detail_group, " + "id " + " from " + tableName + " where id in (");
+ "select id, " + valueColumnName + " dataset, id from " + condition.getName() + " where id in (");
List<Object> parameters = new ArrayList();
for (int i = 0; i < ids.size(); i++) {
if (i == 0) {
@@ -231,52 +217,48 @@ public class H2MetricsQueryDAO extends H2SQLExecutor implements IMetricsQueryDAO
}
sql.append(")");
- List<List<Long>> thermodynamicValueCollection = new ArrayList<>();
- Map<String, List<Long>> thermodynamicValueMatrix = new HashMap<>();
-
try (Connection connection = h2Client.getConnection()) {
- Thermodynamic thermodynamic = new Thermodynamic();
- int numOfSteps = 0;
- int axisYStep = 0;
+ HeatMap heatMap = new HeatMap();
try (ResultSet resultSet = h2Client.executeQuery(
connection, sql.toString(), parameters.toArray(new Object[0]))) {
while (resultSet.next()) {
- axisYStep = resultSet.getInt("step");
- String id = resultSet.getString("id");
- numOfSteps = resultSet.getInt("num_of_steps") + 1;
- String value = resultSet.getString("detail_group");
- IntKeyLongValueHashMap intKeyLongValues = new IntKeyLongValueHashMap(5);
- intKeyLongValues.toObject(value);
-
- List<Long> axisYValues = new ArrayList<>();
- for (int i = 0; i < numOfSteps; i++) {
- axisYValues.add(0L);
- }
-
- for (IntKeyLongValue intKeyLongValue : intKeyLongValues.values()) {
- axisYValues.set(intKeyLongValue.getKey(), intKeyLongValue.getValue());
- }
-
- thermodynamicValueMatrix.put(id, axisYValues);
+ heatMap.buildColumn(resultSet.getString("id"), resultSet.getString("dataset"));
}
-
- // try to add default values when there is no data in that time bucket.
- ids.forEach(id -> {
- if (thermodynamicValueMatrix.containsKey(id)) {
- thermodynamicValueCollection.add(thermodynamicValueMatrix.get(id));
- } else {
- thermodynamicValueCollection.add(new ArrayList<>());
- }
- });
}
- thermodynamic.fromMatrixData(thermodynamicValueCollection, numOfSteps);
- thermodynamic.setAxisYStep(axisYStep);
+ heatMap.fixMissingColumns(ids);
- return thermodynamic;
+ return heatMap;
} catch (SQLException e) {
throw new IOException(e);
}
}
+
+ /**
+ * Make sure the order is same as the expected order, add defaultValue if absent.
+ */
+ private IntValues sortValues(IntValues origin, List<String> expectedOrder, int defaultValue) {
+ IntValues intValues = new IntValues();
+
+ expectedOrder.forEach(id -> {
+ KVInt e = new KVInt();
+ e.setId(id);
+ e.setValue(origin.findValue(id, defaultValue));
+ intValues.addKVInt(e);
+ });
+
+ return intValues;
+ }
+
+ /**
+ * Make sure the order is same as the expected order, add defaultValue if absent.
+ */
+ private List<MetricsValues> sortValues(List<MetricsValues> origin, List<String> expectedOrder, int defaultValue) {
+ for (int i = 0; i < origin.size(); i++) {
+ final MetricsValues metricsValues = origin.get(i);
+ metricsValues.setValues(sortValues(metricsValues.getValues(), expectedOrder, defaultValue));
+ }
+ return origin;
+ }
}
diff --git a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2TableInstaller.java b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2TableInstaller.java
index 42c68ba..4d10bf4 100644
--- a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2TableInstaller.java
+++ b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2TableInstaller.java
@@ -23,7 +23,7 @@ import java.sql.Connection;
import java.sql.SQLException;
import lombok.extern.slf4j.Slf4j;
import org.apache.skywalking.oap.server.core.analysis.NodeType;
-import org.apache.skywalking.oap.server.core.analysis.metrics.IntKeyLongValueHashMap;
+import org.apache.skywalking.oap.server.core.analysis.metrics.DataTable;
import org.apache.skywalking.oap.server.core.storage.StorageException;
import org.apache.skywalking.oap.server.core.storage.model.ColumnName;
import org.apache.skywalking.oap.server.core.storage.model.Model;
@@ -98,7 +98,7 @@ public class H2TableInstaller extends ModelInstaller {
return "DOUBLE";
} else if (String.class.equals(type)) {
return "VARCHAR(" + column.getLength() + ")";
- } else if (IntKeyLongValueHashMap.class.equals(type)) {
+ } else if (DataTable.class.equals(type)) {
return "VARCHAR(20000)";
} else if (byte[].class.equals(type)) {
return "MEDIUMTEXT";
diff --git a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/mysql/MySQLTableInstaller.java b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/mysql/MySQLTableInstaller.java
index 47fbb78..839fefb 100644
--- a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/mysql/MySQLTableInstaller.java
+++ b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/mysql/MySQLTableInstaller.java
@@ -22,7 +22,7 @@ import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import lombok.extern.slf4j.Slf4j;
-import org.apache.skywalking.oap.server.core.analysis.metrics.IntKeyLongValueHashMap;
+import org.apache.skywalking.oap.server.core.analysis.metrics.DataTable;
import org.apache.skywalking.oap.server.core.storage.StorageException;
import org.apache.skywalking.oap.server.core.storage.model.ExtraQueryIndex;
import org.apache.skywalking.oap.server.core.storage.model.Model;
@@ -105,7 +105,7 @@ public class MySQLTableInstaller extends H2TableInstaller {
@Override
protected String getColumnType(final ModelColumn column) {
- if (IntKeyLongValueHashMap.class.equals(column.getType())) {
+ if (DataTable.class.equals(column.getType())) {
return "MEDIUMTEXT";
}
return super.getColumnType(column);
diff --git a/oap-server/server-tools/profile-exporter/tool-profile-snapshot-server-mock/src/main/java/org/apache/skywalking/oap/server/tool/profile/core/MockCoreModuleProvider.java b/oap-server/server-tools/profile-exporter/tool-profile-snapshot-server-mock/src/main/java/org/apache/skywalking/oap/server/tool/profile/core/MockCoreModuleProvider.java
index 04413b9..b48790f 100755
--- a/oap-server/server-tools/profile-exporter/tool-profile-snapshot-server-mock/src/main/java/org/apache/skywalking/oap/server/tool/profile/core/MockCoreModuleProvider.java
+++ b/oap-server/server-tools/profile-exporter/tool-profile-snapshot-server-mock/src/main/java/org/apache/skywalking/oap/server/tool/profile/core/MockCoreModuleProvider.java
@@ -36,7 +36,7 @@ import org.apache.skywalking.oap.server.core.query.AggregationQueryService;
import org.apache.skywalking.oap.server.core.query.AlarmQueryService;
import org.apache.skywalking.oap.server.core.query.LogQueryService;
import org.apache.skywalking.oap.server.core.query.MetadataQueryService;
-import org.apache.skywalking.oap.server.core.query.MetricQueryService;
+import org.apache.skywalking.oap.server.core.query.MetricsQueryService;
import org.apache.skywalking.oap.server.core.query.ProfileTaskQueryService;
import org.apache.skywalking.oap.server.core.query.TopNRecordsQueryService;
import org.apache.skywalking.oap.server.core.query.TopologyQueryService;
@@ -132,7 +132,7 @@ public class MockCoreModuleProvider extends CoreModuleProvider {
NetworkAddressAliasCache.class, new NetworkAddressAliasCache(moduleConfig));
this.registerServiceImplementation(TopologyQueryService.class, new TopologyQueryService(getManager()));
- this.registerServiceImplementation(MetricQueryService.class, new MetricQueryService(getManager()));
+ this.registerServiceImplementation(MetricsQueryService.class, new MetricsQueryService(getManager()));
this.registerServiceImplementation(TraceQueryService.class, new TraceQueryService(getManager()));
this.registerServiceImplementation(LogQueryService.class, new LogQueryService(getManager()));
this.registerServiceImplementation(MetadataQueryService.class, new MetadataQueryService(getManager()));