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/21 13:25:59 UTC

[skywalking] branch metrics-type created (now 481e1ef)

This is an automated email from the ASF dual-hosted git repository.

wusheng pushed a change to branch metrics-type
in repository https://gitbox.apache.org/repos/asf/skywalking.git.


      at 481e1ef  Add data type to the column definition to replace the simple isValue definition. And top N query is also requiring value column now.

This branch includes the following new commits:

     new 481e1ef  Add data type to the column definition to replace the simple isValue definition. And top N query is also requiring value column now.

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[skywalking] 01/01: Add data type to the column definition to replace the simple isValue definition. And top N query is also requiring value column now.

Posted by wu...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

wusheng pushed a commit to branch metrics-type
in repository https://gitbox.apache.org/repos/asf/skywalking.git

commit 481e1ef761dccfb8f3034e892d547bb70054a028
Author: Wu Sheng <wu...@foxmail.com>
AuthorDate: Tue Apr 21 21:25:06 2020 +0800

    Add data type to the column definition to replace the simple isValue definition. And top N query is also requiring value column now.
---
 .../skywalking/oap/server/core/CoreModule.java     |  2 +
 .../oap/server/core/CoreModuleProvider.java        |  2 +
 .../oap/server/core/analysis/topn/TopN.java        |  2 +-
 .../core/query/MetricsMetadataQueryService.java    | 51 ++++++++++++++++++++++
 .../server/core/query/TopNRecordsQueryService.java |  4 +-
 .../oap/server/core/storage/annotation/Column.java | 51 +++++++++++++++++++---
 .../storage/annotation/ValueColumnMetadata.java    | 18 ++++++--
 .../server/core/storage/model/StorageModels.java   |  6 +--
 .../core/storage/query/ITopNRecordsQueryDAO.java   |  4 +-
 .../oap/query/graphql/resolver/MetricsQuery.java   | 18 ++++++--
 .../elasticsearch/query/TopNRecordsQueryEsDAO.java |  5 ++-
 .../plugin/influxdb/query/TopNRecordsQuery.java    |  3 +-
 .../plugin/jdbc/h2/dao/H2TopNRecordsQueryDAO.java  |  5 ++-
 .../tool/profile/core/MockCoreModuleProvider.java  |  2 +
 14 files changed, 149 insertions(+), 24 deletions(-)

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 82450bb..13c1cad 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,6 +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.MetricsMetadataQueryService;
 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;
@@ -90,6 +91,7 @@ public class CoreModule extends ModuleDefine {
 
     private void addQueryService(List<Class> classes) {
         classes.add(TopologyQueryService.class);
+        classes.add(MetricsMetadataQueryService.class);
         classes.add(MetricsQueryService.class);
         classes.add(TraceQueryService.class);
         classes.add(LogQueryService.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 03a1be7..cf81132 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,6 +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.MetricsMetadataQueryService;
 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;
@@ -213,6 +214,7 @@ public class CoreModuleProvider extends ModuleProvider {
             NetworkAddressAliasCache.class, new NetworkAddressAliasCache(moduleConfig));
 
         this.registerServiceImplementation(TopologyQueryService.class, new TopologyQueryService(getManager()));
+        this.registerServiceImplementation(MetricsMetadataQueryService.class, new MetricsMetadataQueryService());
         this.registerServiceImplementation(MetricsQueryService.class, new MetricsQueryService(getManager()));
         this.registerServiceImplementation(TraceQueryService.class, new TraceQueryService(getManager()));
         this.registerServiceImplementation(LogQueryService.class, new LogQueryService(getManager()));
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/topn/TopN.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/topn/TopN.java
index 8f97078..4ec3763 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/topn/TopN.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/topn/TopN.java
@@ -39,7 +39,7 @@ public abstract class TopN extends Record implements ComparableStorageData {
     private String statement;
     @Getter
     @Setter
-    @Column(columnName = LATENCY)
+    @Column(columnName = LATENCY, dataType = Column.ValueDataType.SAMPLED_RECORD)
     private long latency;
     @Getter
     @Setter
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/MetricsMetadataQueryService.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/MetricsMetadataQueryService.java
new file mode 100644
index 0000000..93483a1
--- /dev/null
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/MetricsMetadataQueryService.java
@@ -0,0 +1,51 @@
+/*
+ * 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.util.Optional;
+import org.apache.skywalking.oap.server.core.query.enumeration.MetricsType;
+import org.apache.skywalking.oap.server.core.storage.annotation.ValueColumnMetadata;
+import org.apache.skywalking.oap.server.library.module.Service;
+
+/**
+ * MetricsMetadataQueryService provides the metadata of metrics to other modules.
+ */
+public class MetricsMetadataQueryService implements Service {
+    public MetricsType typeOfMetrics(String metricsName) {
+        final Optional<ValueColumnMetadata.ValueColumn> valueColumn
+            = ValueColumnMetadata.INSTANCE.readValueColumnDefinition(metricsName);
+        if (valueColumn.isPresent()) {
+            switch (valueColumn.get().getDataType()) {
+                case COMMON_VALUE:
+                    return MetricsType.REGULAR_VALUE;
+                case LABELED_VALUE:
+                    return MetricsType.LABELED_VALUE;
+                case HISTOGRAM:
+                    return MetricsType.HEATMAP;
+                case SAMPLED_RECORD:
+                    return MetricsType.SAMPLED_RECORD;
+                case NOT_VALUE:
+                default:
+                    return MetricsType.UNKNOWN;
+            }
+        } else {
+            return MetricsType.UNKNOWN;
+        }
+    }
+}
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/TopNRecordsQueryService.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/TopNRecordsQueryService.java
index 1e8e4c8..31c55d5 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/TopNRecordsQueryService.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/TopNRecordsQueryService.java
@@ -24,6 +24,7 @@ import org.apache.skywalking.oap.server.core.query.input.Duration;
 import org.apache.skywalking.oap.server.core.query.input.TopNCondition;
 import org.apache.skywalking.oap.server.core.query.type.SelectedRecord;
 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.ITopNRecordsQueryDAO;
 import org.apache.skywalking.oap.server.library.module.ModuleManager;
 import org.apache.skywalking.oap.server.library.module.Service;
@@ -46,6 +47,7 @@ public class TopNRecordsQueryService implements Service {
     }
 
     public List<SelectedRecord> readSampledRecords(TopNCondition condition, Duration duration) throws IOException {
-        return getTopNRecordsQueryDAO().readSampledRecords(condition, duration);
+        return getTopNRecordsQueryDAO().readSampledRecords(
+            condition, ValueColumnMetadata.INSTANCE.getValueCName(condition.getName()), duration);
     }
 }
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 6a8ddb5..ce0b433 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
@@ -22,6 +22,7 @@ import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
+import lombok.Getter;
 import org.apache.skywalking.oap.server.core.query.sql.Function;
 import org.apache.skywalking.oap.server.core.storage.model.IModelOverride;
 
@@ -38,17 +39,12 @@ public @interface Column {
     String columnName();
 
     /**
-     * The column value is used in metrics value query.
-     */
-    boolean isValue() default false;
-
-    /**
      * The function is used in aggregation query.
      */
     Function function() default Function.None;
 
     /**
-     * The default value of this column, when its {@link #isValue()} == true.
+     * The default value of this column, when its {@link #dataType()} != {@link ValueDataType#NOT_VALUE}.
      */
     int defaultValue() default 0;
 
@@ -68,4 +64,47 @@ public @interface Column {
      * @since 7.1.0
      */
     int length() default 200;
+
+    /**
+     * @return the data type of this value column. The value column is the query related value Set {@link
+     * ValueDataType#NOT_VALUE} if this is not the value column, read {@link ValueDataType} for more details.
+     * @since 8.0.0
+     */
+    ValueDataType dataType() default ValueDataType.NOT_VALUE;
+
+    /**
+     * ValueDataType represents the data structure of value column. The persistent way of the value column determine the
+     * available ways to query the data.
+     */
+    enum ValueDataType {
+        /**
+         * NOT_VALUE represents this value wouldn't be queried directly through metrics v2 protocol. It could be never
+         * queried, or just through hard code to do so, uch as the lines of topology and service.
+         */
+        NOT_VALUE(false),
+        /**
+         * COMMON_VALUE represents a single value, usually int or long.
+         */
+        COMMON_VALUE(true),
+        /**
+         * LABELLED_VALUE represents this metrics have multiple values with different labels.
+         */
+        LABELED_VALUE(true),
+        /**
+         * HISTOGRAM represents the values are grouped by the buckets, usually suitable for heatmap query.
+         */
+        HISTOGRAM(true),
+        /**
+         * SAMPLED_RECORD represents the values are detail data, being persistent by following some sampled rules.
+         * Usually do topn query based on value column value ASC or DESC.
+         */
+        SAMPLED_RECORD(true);
+
+        @Getter
+        private boolean isValue = false;
+
+        ValueDataType(final boolean isValue) {
+            this.isValue = isValue;
+        }
+    }
 }
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 968262f..76af49d 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,8 @@ package org.apache.skywalking.oap.server.core.storage.annotation;
 
 import java.util.HashMap;
 import java.util.Map;
+import java.util.Optional;
+import lombok.Getter;
 import lombok.RequiredArgsConstructor;
 import org.apache.skywalking.oap.server.core.query.sql.Function;
 
@@ -35,8 +37,12 @@ public enum ValueColumnMetadata {
     /**
      * Register the new metadata for the given model name.
      */
-    public void putIfAbsent(String modelName, String valueCName, Function function, int defaultValue) {
-        mapping.putIfAbsent(modelName, new ValueColumn(valueCName, function, defaultValue));
+    public void putIfAbsent(String modelName,
+                            String valueCName,
+                            Column.ValueDataType dataType,
+                            Function function,
+                            int defaultValue) {
+        mapping.putIfAbsent(modelName, new ValueColumn(valueCName, dataType, function, defaultValue));
     }
 
     /**
@@ -57,6 +63,10 @@ public enum ValueColumnMetadata {
         return findColumn(metricsName).defaultValue;
     }
 
+    public Optional<ValueColumn> readValueColumnDefinition(String metricsName) {
+        return Optional.ofNullable(mapping.get(metricsName));
+    }
+
     private ValueColumn findColumn(String metricsName) {
         ValueColumn column = mapping.get(metricsName);
         if (column == null) {
@@ -65,9 +75,11 @@ public enum ValueColumnMetadata {
         return column;
     }
 
+    @Getter
     @RequiredArgsConstructor
-    class ValueColumn {
+    public class ValueColumn {
         private final String valueCName;
+        private final Column.ValueDataType dataType;
         private final Function function;
         private final int defaultValue;
     }
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/model/StorageModels.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/model/StorageModels.java
index 0a25e74..93e7d30 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/model/StorageModels.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/model/StorageModels.java
@@ -76,13 +76,13 @@ public class StorageModels implements IModelManager, INewModel, IModelOverride {
                 modelColumns.add(
                     new ModelColumn(
                         new ColumnName(modelName, column.columnName()), field.getType(), column.matchQuery(), column
-                        .storageOnly(), column.isValue(), column.length()));
+                        .storageOnly(), column.dataType().isValue(), column.length()));
                 if (log.isDebugEnabled()) {
                     log.debug("The field named {} with the {} type", column.columnName(), field.getType());
                 }
-                if (column.isValue()) {
+                if (column.dataType().isValue()) {
                     ValueColumnMetadata.INSTANCE.putIfAbsent(
-                        modelName, column.columnName(), column.function(), column.defaultValue());
+                        modelName, column.columnName(), column.dataType(), column.function(), column.defaultValue());
                 }
 
                 List<QueryUnifiedIndex> indexDefinitions = new ArrayList<>();
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/query/ITopNRecordsQueryDAO.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/query/ITopNRecordsQueryDAO.java
index a818d5c..7805bb0 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/query/ITopNRecordsQueryDAO.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/query/ITopNRecordsQueryDAO.java
@@ -33,5 +33,7 @@ import org.apache.skywalking.oap.server.library.module.Service;
  * @since 8.0.0
  */
 public interface ITopNRecordsQueryDAO extends Service {
-    List<SelectedRecord> readSampledRecords(TopNCondition condition, Duration duration) throws IOException;
+    List<SelectedRecord> readSampledRecords(TopNCondition condition,
+                                            final String valueColumnName,
+                                            Duration duration) throws IOException;
 }
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 b450a3c..d9f091e 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
@@ -23,6 +23,7 @@ import java.io.IOException;
 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.MetricsMetadataQueryService;
 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;
@@ -44,11 +45,21 @@ public class MetricsQuery implements GraphQLQueryResolver {
     private MetricsQueryService metricsQueryService;
     private AggregationQueryService queryService;
     private TopNRecordsQueryService topNRecordsQueryService;
+    private MetricsMetadataQueryService metricsMetadataQueryService;
 
     public MetricsQuery(ModuleManager moduleManager) {
         this.moduleManager = moduleManager;
     }
 
+    private MetricsMetadataQueryService getMetricsMetadataQueryService() {
+        if (metricsMetadataQueryService == null) {
+            this.metricsMetadataQueryService = moduleManager.find(CoreModule.NAME)
+                                                            .provider()
+                                                            .getService(MetricsMetadataQueryService.class);
+        }
+        return metricsMetadataQueryService;
+    }
+
     private AggregationQueryService getQueryService() {
         if (queryService == null) {
             this.queryService = moduleManager.find(CoreModule.NAME)
@@ -80,7 +91,7 @@ public class MetricsQuery implements GraphQLQueryResolver {
      * Metrics definition metadata query. Response the metrics type which determines the suitable query methods.
      */
     public MetricsType typeOfMetrics(String name) throws IOException {
-        return MetricsType.UNKNOWN;
+        return getMetricsMetadataQueryService().typeOfMetrics(name);
     }
 
     /**
@@ -118,9 +129,8 @@ public class MetricsQuery implements GraphQLQueryResolver {
     /**
      * Heatmap is bucket based value statistic result.
      *
-     * @return heapmap including the latency distribution
-     * {@link HeatMap#getBuckets()}
-     * {@link HeatMap.HeatMapColumn#getValues()} follows this rule.
+     * @return heapmap including the latency distribution {@link HeatMap#getBuckets()} {@link
+     * HeatMap.HeatMapColumn#getValues()} follows this rule.
      * <pre>
      *      key = 0, represents [0, 100), value = count of requests in the latency range.
      *      key = 100, represents [100, 200), value = count of requests in the latency range.
diff --git a/oap-server/server-storage-plugin/storage-elasticsearch-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch/query/TopNRecordsQueryEsDAO.java b/oap-server/server-storage-plugin/storage-elasticsearch-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch/query/TopNRecordsQueryEsDAO.java
index 7b324a7..f630a08 100644
--- a/oap-server/server-storage-plugin/storage-elasticsearch-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch/query/TopNRecordsQueryEsDAO.java
+++ b/oap-server/server-storage-plugin/storage-elasticsearch-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/elasticsearch/query/TopNRecordsQueryEsDAO.java
@@ -45,6 +45,7 @@ public class TopNRecordsQueryEsDAO extends EsDAO implements ITopNRecordsQueryDAO
 
     @Override
     public List<SelectedRecord> readSampledRecords(final TopNCondition condition,
+                                                   final String valueColumnName,
                                                    final Duration duration) throws IOException {
         SearchSourceBuilder sourceBuilder = SearchSourceBuilder.searchSource();
         BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
@@ -59,7 +60,7 @@ public class TopNRecordsQueryEsDAO extends EsDAO implements ITopNRecordsQueryDAO
 
         sourceBuilder.query(boolQueryBuilder);
         sourceBuilder.size(condition.getTopN())
-                     .sort(TopN.LATENCY, condition.getOrder().equals(Order.DES) ? SortOrder.DESC : SortOrder.ASC);
+                     .sort(valueColumnName, condition.getOrder().equals(Order.DES) ? SortOrder.DESC : SortOrder.ASC);
         SearchResponse response = getClient().search(condition.getName(), sourceBuilder);
 
         List<SelectedRecord> results = new ArrayList<>(condition.getTopN());
@@ -68,7 +69,7 @@ public class TopNRecordsQueryEsDAO extends EsDAO implements ITopNRecordsQueryDAO
             SelectedRecord record = new SelectedRecord();
             record.setName((String) searchHit.getSourceAsMap().get(TopN.STATEMENT));
             record.setRefId((String) searchHit.getSourceAsMap().get(TopN.TRACE_ID));
-            record.setValue(((Number) searchHit.getSourceAsMap().get(TopN.LATENCY)).toString());
+            record.setValue(((Number) searchHit.getSourceAsMap().get(valueColumnName)).toString());
             results.add(record);
         }
 
diff --git a/oap-server/server-storage-plugin/storage-influxdb-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/influxdb/query/TopNRecordsQuery.java b/oap-server/server-storage-plugin/storage-influxdb-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/influxdb/query/TopNRecordsQuery.java
index ba7a592..9608fd8 100644
--- a/oap-server/server-storage-plugin/storage-influxdb-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/influxdb/query/TopNRecordsQuery.java
+++ b/oap-server/server-storage-plugin/storage-influxdb-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/influxdb/query/TopNRecordsQuery.java
@@ -52,6 +52,7 @@ public class TopNRecordsQuery implements ITopNRecordsQueryDAO {
 
     @Override
     public List<SelectedRecord> readSampledRecords(final TopNCondition condition,
+                                                   final String valueColumnName,
                                                    final Duration duration) throws IOException {
         String function = InfluxConstants.SORT_ASC;
         // Have to re-sort here. Because the function, top()/bottom(), get the result ordered by the `time`.
@@ -62,7 +63,7 @@ public class TopNRecordsQuery implements ITopNRecordsQueryDAO {
         }
 
         WhereQueryImpl query = select()
-            .function(function, TopN.LATENCY, condition.getTopN())
+            .function(function, valueColumnName, condition.getTopN())
             .column(TopN.STATEMENT)
             .column(TopN.TRACE_ID)
             .from(client.getDatabase(), condition.getName())
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/H2TopNRecordsQueryDAO.java b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2TopNRecordsQueryDAO.java
index 2f9a22d..f1a9b8d 100644
--- a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2TopNRecordsQueryDAO.java
+++ b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2TopNRecordsQueryDAO.java
@@ -43,6 +43,7 @@ public class H2TopNRecordsQueryDAO implements ITopNRecordsQueryDAO {
 
     @Override
     public List<SelectedRecord> readSampledRecords(final TopNCondition condition,
+                                                   final String valueColumnName,
                                                    final Duration duration) throws IOException {
         StringBuilder sql = new StringBuilder("select * from " + condition.getName() + " where ");
         List<Object> parameters = new ArrayList<>(10);
@@ -58,7 +59,7 @@ public class H2TopNRecordsQueryDAO implements ITopNRecordsQueryDAO {
         sql.append(" and ").append(TopN.TIME_BUCKET).append(" <= ?");
         parameters.add(duration.getEndTimeBucket());
 
-        sql.append(" order by ").append(TopN.LATENCY);
+        sql.append(" order by ").append(valueColumnName);
         if (condition.getOrder().equals(Order.DES)) {
             sql.append(" desc ");
         } else {
@@ -74,7 +75,7 @@ public class H2TopNRecordsQueryDAO implements ITopNRecordsQueryDAO {
                     SelectedRecord record = new SelectedRecord();
                     record.setName(resultSet.getString(TopN.STATEMENT));
                     record.setRefId(resultSet.getString(TopN.TRACE_ID));
-                    record.setValue(resultSet.getString(TopN.LATENCY));
+                    record.setValue(resultSet.getString(valueColumnName));
                     results.add(record);
                 }
             }
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 b48790f..8f32900 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,6 +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.MetricsMetadataQueryService;
 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;
@@ -132,6 +133,7 @@ public class MockCoreModuleProvider extends CoreModuleProvider {
             NetworkAddressAliasCache.class, new NetworkAddressAliasCache(moduleConfig));
 
         this.registerServiceImplementation(TopologyQueryService.class, new TopologyQueryService(getManager()));
+        this.registerServiceImplementation(MetricsMetadataQueryService.class, new MetricsMetadataQueryService());
         this.registerServiceImplementation(MetricsQueryService.class, new MetricsQueryService(getManager()));
         this.registerServiceImplementation(TraceQueryService.class, new TraceQueryService(getManager()));
         this.registerServiceImplementation(LogQueryService.class, new LogQueryService(getManager()));