You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@skywalking.apache.org by "wankai123 (via GitHub)" <gi...@apache.org> on 2023/02/20 09:58:56 UTC

[GitHub] [skywalking] wankai123 opened a new pull request, #10415: Support prometheus HTTP API and promQL.

wankai123 opened a new pull request, #10415:
URL: https://github.com/apache/skywalking/pull/10415

   - [ ] If this is non-trivial feature, paste the links/URLs to the design doc.
   - [ ] Update the documentation to include this new feature.
   - [X] Tests(including UT, IT, E2E) are added to verify the new feature.
   - [X] If it's UI related, attach the screenshots below.
   
   - [ ] If this pull request closes/resolves/fixes an existing issue, replace the issue number. Closes #10080 .
   - [X] Update the [`CHANGES` log](https://github.com/apache/skywalking/blob/master/docs/en/changes/changes.md).
   
   Support HTTP API list:
   - /api/v1/metadata
   - /api/v1/labels
   - /api/v1/label/{label_name}/values
   - /api/v1/series
   - /api/v1/query
   - /api/v1/query_range
   
   Support basic promQL for query traffic/metrics/labeled_metrics/topN/sampled_records from OAP
   
   A Grafana dashboards demo based on this feature can visit:
   http://34.92.90.119:3000/
   admin/admin
   
   Include: General Service / Service Mesh / Virtual-Database
   
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@skywalking.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [skywalking] wu-sheng commented on pull request #10415: Support prometheus HTTP API and promQL.

Posted by "wu-sheng (via GitHub)" <gi...@apache.org>.
wu-sheng commented on PR #10415:
URL: https://github.com/apache/skywalking/pull/10415#issuecomment-1436666832

   One TODO, complete docs for PromQL. This should be done through next PR.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@skywalking.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [skywalking] wu-sheng commented on a diff in pull request #10415: Support prometheus HTTP API and promQL.

Posted by "wu-sheng (via GitHub)" <gi...@apache.org>.
wu-sheng commented on code in PR #10415:
URL: https://github.com/apache/skywalking/pull/10415#discussion_r1111728383


##########
oap-server/server-starter/src/main/resources/application.yml:
##########
@@ -435,6 +435,17 @@ query-zipkin:
     # Default look back on the UI for search traces, 15 minutes in millis
     uiDefaultLookback: ${SW_QUERY_ZIPKIN_UI_DEFAULT_LOOKBACK:900000}
 
+query-prometheus:

Review Comment:
   ```suggestion
   promql:
   ```
   
   From the official explanation, **PromQL, short for Prometheus Querying Language, is the main way to query metrics within Prometheus. You can display an expression's return either as a graph or export it using the HTTP API**. PromQL should be good enough.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@skywalking.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [skywalking] wu-sheng commented on a diff in pull request #10415: Support prometheus HTTP API and promQL.

Posted by "wu-sheng (via GitHub)" <gi...@apache.org>.
wu-sheng commented on code in PR #10415:
URL: https://github.com/apache/skywalking/pull/10415#discussion_r1111736751


##########
oap-server/server-query-plugin/prometheus-query-plugin/pom.xml:
##########
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ 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.
+  ~
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>server-query-plugin</artifactId>
+        <groupId>org.apache.skywalking</groupId>
+        <version>9.4.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>prometheus-query-plugin</artifactId>

Review Comment:
   ```suggestion
       <artifactId>promql-plugin</artifactId>
   ```
   
   We are protocol-oriented, let's use promql in all places.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@skywalking.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [skywalking] wu-sheng commented on a diff in pull request #10415: Support prometheus HTTP API and promQL.

Posted by "wu-sheng (via GitHub)" <gi...@apache.org>.
wu-sheng commented on code in PR #10415:
URL: https://github.com/apache/skywalking/pull/10415#discussion_r1111735673


##########
docs/en/changes/changes.md:
##########
@@ -99,6 +99,7 @@
 * Refactor http-based alarm plugins and extract common logic to `HttpAlarmCallback`.
 * Support Amazon Simple Storage Service (Amazon S3) metrics monitoring
 * Support process Sum metrics with AGGREGATION_TEMPORALITY_DELTA case
+* Support prometheus HTTP API and promQL.

Review Comment:
   ```suggestion
   * Support prometheus HTTP API and promQL.
   * `Scope` in the Entity of Metrics query v1 protocol is not required and automatical correction. The scope is determined based on the metric itself.
   ```
   
   I think we should update the GraphQL to remove required and add comments about the new mechanism.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@skywalking.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [skywalking] kezhenxu94 commented on a diff in pull request #10415: Support prometheus HTTP API and promQL.

Posted by "kezhenxu94 (via GitHub)" <gi...@apache.org>.
kezhenxu94 commented on code in PR #10415:
URL: https://github.com/apache/skywalking/pull/10415#discussion_r1113743076


##########
oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/RecordQueryService.java:
##########
@@ -48,7 +49,10 @@ private IRecordsQueryDAO getRecordsQueryDAO() {
     }
 
     public List<Record> readRecords(RecordCondition condition, Duration duration) throws IOException {
+        if (!condition.getParentEntity().isValid()) {
+            return Collections.EMPTY_LIST;

Review Comment:
   Use `Collections.emptyList()` to avoid generic warnings.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@skywalking.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [skywalking] kezhenxu94 commented on a diff in pull request #10415: Support prometheus HTTP API and promQL.

Posted by "kezhenxu94 (via GitHub)" <gi...@apache.org>.
kezhenxu94 commented on code in PR #10415:
URL: https://github.com/apache/skywalking/pull/10415#discussion_r1111753730


##########
oap-server/server-query-plugin/prometheus-query-plugin/src/main/java/org/apache/skywalking/oap/query/prometheus/rt/PromOpUtils.java:
##########
@@ -0,0 +1,255 @@
+/*
+ * 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.query.prometheus.rt;
+
+import java.text.DecimalFormat;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+import org.apache.skywalking.oap.query.prometheus.entity.MetricRangeData;
+import org.apache.skywalking.oap.query.prometheus.entity.TimeValuePair;
+import org.apache.skywalking.oap.query.prometheus.rt.exception.IllegalExpressionException;
+import org.apache.skywalking.oap.query.prometheus.rt.result.ParseResultType;
+import org.apache.skywalking.oap.query.prometheus.rt.result.MetricsRangeResult;
+import org.apache.skywalking.oap.query.prometheus.rt.result.ScalarResult;
+import org.apache.skywalking.oap.server.core.query.DurationUtils;
+import org.apache.skywalking.oap.server.core.query.PointOfTime;
+import org.apache.skywalking.oap.server.core.query.enumeration.Step;
+import org.apache.skywalking.oap.server.core.query.input.Duration;
+import org.apache.skywalking.oap.server.core.query.type.MetricsValues;
+import org.apache.skywalking.promql.rt.grammar.PromQLParser;
+import org.joda.time.DateTime;
+
+public class PromOpUtils {
+    //Adopt skywalking time step.
+    public static Duration timestamp2Duration(long startTS, long endTS) {
+        Duration duration = new Duration();
+        if (endTS < startTS) {
+            throw new IllegalArgumentException("End time must not be before start");
+        }
+        DateTime startDT = new DateTime(startTS);
+        DateTime endDT = new DateTime(endTS);
+
+        long durationValue = endTS - startTS;
+
+        if (durationValue < 3600000) {
+            duration.setStep(Step.MINUTE);
+            duration.setStart(startDT.toString(DurationUtils.YYYY_MM_DD_HHMM));
+            duration.setEnd(endDT.toString(DurationUtils.YYYY_MM_DD_HHMM));
+        } else if (durationValue < 86400000) {
+            duration.setStep(Step.HOUR);
+            duration.setStart(startDT.toString(DurationUtils.YYYY_MM_DD_HH));
+            duration.setEnd(endDT.toString(DurationUtils.YYYY_MM_DD_HH));
+        } else {
+            duration.setStep(Step.DAY);
+            duration.setStart(startDT.toString(DurationUtils.YYYY_MM_DD));
+            duration.setEnd(endDT.toString(DurationUtils.YYYY_MM_DD));
+        }
+        return duration;
+    }
+
+    static MetricsRangeResult matrixScalarBinaryOp(MetricsRangeResult matrix, ScalarResult scalar, int opType) {
+        MetricsRangeResult result = new MetricsRangeResult();
+        result.setResultType(ParseResultType.metrics_range);
+        matrix.getMetricDataList().forEach(metricData -> {
+            MetricRangeData newData = new MetricRangeData();
+            result.getMetricDataList().add(newData);
+            newData.setMetric(metricData.getMetric());
+            List<TimeValuePair> newValues = metricData.getValues().stream().map(value -> {
+                double v = Double.parseDouble(value.getValue());
+                return new TimeValuePair(
+                    value.getTime(),
+                    formatDoubleValue(scalarBinaryOp(v, scalar.getValue(), opType))
+                );
+
+            }).collect(Collectors.toList());
+            newData.setValues(newValues);
+        });
+        return result;
+    }
+
+    static MetricsRangeResult matrixBinaryOp(MetricsRangeResult matrixLeft,
+                                             MetricsRangeResult matrixRight,
+                                             int opType) throws IllegalExpressionException {
+        MetricsRangeResult result = new MetricsRangeResult();
+        result.setResultType(ParseResultType.metrics_range);
+        for (int i = 0; i < matrixLeft.getMetricDataList().size(); i++) {
+            MetricRangeData dataLeft = matrixLeft.getMetricDataList().get(i);
+            MetricRangeData dataRight = matrixRight.getMetricDataList().get(i);
+            if (!dataLeft.getMetric().equals(dataRight.getMetric())) {
+                throw new IllegalExpressionException(
+                    "The metric info result left in conformity with right.");
+            }
+            if (dataLeft.getValues().size() != dataRight.getValues().size()) {
+                throw new IllegalExpressionException(
+                    "The metric value range left in conformity with right.");
+            }
+            MetricRangeData newData = new MetricRangeData();
+            result.getMetricDataList().add(newData);
+            newData.setMetric(dataLeft.getMetric());
+            List<TimeValuePair> newValues = new ArrayList<>();
+            newData.setValues(newValues);
+            for (int j = 0; j < dataLeft.getValues().size(); j++) {
+                double lv = Double.parseDouble(dataLeft.getValues().get(j).getValue());
+                double rv = Double.parseDouble(dataRight.getValues().get(j).getValue());
+                newValues.add(new TimeValuePair(
+                    dataLeft.getValues().get(j).getTime(),
+                    formatDoubleValue(scalarBinaryOp(lv, rv, opType))
+                ));
+            }
+        }
+        return result;
+    }
+
+    static double scalarBinaryOp(double leftValue, double rightValue, int opType) {
+        double calculatedResult = 0;
+        switch (opType) {
+            case PromQLParser.ADD:
+                calculatedResult = leftValue + rightValue;
+                break;
+            case PromQLParser.SUB:
+                calculatedResult = leftValue - rightValue;
+                break;
+            case PromQLParser.MUL:
+                calculatedResult = leftValue * rightValue;
+                break;
+            case PromQLParser.DIV:
+                calculatedResult = leftValue / rightValue;
+                break;
+            case PromQLParser.MOD:
+                calculatedResult = leftValue % rightValue;
+                break;
+        }
+        return calculatedResult;
+    }
+
+    static int scalarCompareOp(double leftValue, double rightValue, int opType) {
+        int comparedResult = 0;
+        switch (opType) {
+            case PromQLParser.DEQ:
+                comparedResult = boolToInt(leftValue == rightValue);
+                break;
+            case PromQLParser.NEQ:
+                comparedResult = boolToInt(leftValue != rightValue);
+                break;
+            case PromQLParser.GT:
+                comparedResult = boolToInt(leftValue > rightValue);
+                break;
+            case PromQLParser.LT:
+                comparedResult = boolToInt(leftValue < rightValue);
+                break;
+            case PromQLParser.GTE:
+                comparedResult = boolToInt(leftValue >= rightValue);
+                break;
+            case PromQLParser.LTE:
+                comparedResult = boolToInt(leftValue <= rightValue);
+                break;
+        }
+        return comparedResult;
+    }
+
+    private static int boolToInt(Boolean v) {
+        return v ? 1 : 0;
+    }

Review Comment:
   Either change the type of the argument to `boolean` or add null check for `v`, otherwise when `v == null` NPE occurs here



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@skywalking.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [skywalking] wu-sheng commented on a diff in pull request #10415: Support prometheus HTTP API and promQL.

Posted by "wu-sheng (via GitHub)" <gi...@apache.org>.
wu-sheng commented on code in PR #10415:
URL: https://github.com/apache/skywalking/pull/10415#discussion_r1111727188


##########
pom.xml:
##########
@@ -177,7 +177,7 @@
           in a single place. Upgrading Antlr version here requires recompiling the oal-rt/oal-rt modules so users
           won't face error like "ANTLR Tool version 4.9.3 used for code generation does not match the current runtime version 4.7.1".
         -->
-        <antlr.version>4.9.2</antlr.version>
+        <antlr.version>4.11.1</antlr.version>

Review Comment:
   This may cause dependencies license check fail, I guess?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@skywalking.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [skywalking] kezhenxu94 commented on a diff in pull request #10415: Support prometheus HTTP API and promQL.

Posted by "kezhenxu94 (via GitHub)" <gi...@apache.org>.
kezhenxu94 commented on code in PR #10415:
URL: https://github.com/apache/skywalking/pull/10415#discussion_r1111783055


##########
oap-server/server-query-plugin/prometheus-query-plugin/src/main/java/org/apache/skywalking/oap/query/prometheus/entity/TimeValuePair.java:
##########
@@ -0,0 +1,35 @@
+/*
+ * 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.query.prometheus.entity;
+
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import lombok.Data;
+import org.apache.skywalking.oap.query.prometheus.entity.codec.TimeValuePairSerializer;
+
+@Data
+@JsonSerialize(using = TimeValuePairSerializer.class)
+public class TimeValuePair {
+    private final long time;
+    private String value;

Review Comment:
   Looks like this class is a value holder and can be an immutable class
   
   ```suggestion
       private final String value;
   ```



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@skywalking.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [skywalking] kezhenxu94 commented on a diff in pull request #10415: Support prometheus HTTP API and promQL.

Posted by "kezhenxu94 (via GitHub)" <gi...@apache.org>.
kezhenxu94 commented on code in PR #10415:
URL: https://github.com/apache/skywalking/pull/10415#discussion_r1111772947


##########
oap-server/server-query-plugin/prometheus-query-plugin/src/main/java/org/apache/skywalking/oap/query/prometheus/handler/PrometheusApiHandler.java:
##########
@@ -0,0 +1,544 @@
+/*
+ * 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.query.prometheus.handler;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.linecorp.armeria.common.HttpData;
+import com.linecorp.armeria.common.HttpResponse;
+import com.linecorp.armeria.common.HttpStatus;
+import com.linecorp.armeria.common.MediaType;
+import com.linecorp.armeria.common.ResponseHeaders;
+import com.linecorp.armeria.server.annotation.Blocking;
+import com.linecorp.armeria.server.annotation.Get;
+import com.linecorp.armeria.server.annotation.Param;
+import com.linecorp.armeria.server.annotation.Path;
+import com.linecorp.armeria.server.annotation.Post;
+import graphql.org.antlr.v4.runtime.misc.ParseCancellationException;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+import org.antlr.v4.runtime.CharStreams;
+import org.antlr.v4.runtime.CommonTokenStream;
+import org.antlr.v4.runtime.tree.ParseTree;
+import org.apache.skywalking.oap.query.graphql.resolver.MetadataQueryV2;
+import org.apache.skywalking.oap.query.graphql.resolver.MetricsQuery;
+import org.apache.skywalking.oap.query.graphql.resolver.RecordsQuery;
+import org.apache.skywalking.oap.query.prometheus.PrometheusQueryConfig;
+import org.apache.skywalking.oap.query.prometheus.entity.ErrorType;
+import org.apache.skywalking.oap.query.prometheus.entity.LabelName;
+import org.apache.skywalking.oap.query.prometheus.entity.LabelValuePair;
+import org.apache.skywalking.oap.query.prometheus.entity.MetricInstantData;
+import org.apache.skywalking.oap.query.prometheus.entity.MetricMetadata;
+import org.apache.skywalking.oap.query.prometheus.entity.MetricRangeData;
+import org.apache.skywalking.oap.query.prometheus.entity.TimeValuePair;
+import org.apache.skywalking.oap.query.prometheus.entity.response.ExprQueryRsp;
+import org.apache.skywalking.oap.query.prometheus.entity.MetricInfo;
+import org.apache.skywalking.oap.query.prometheus.entity.response.LabelValuesQueryRsp;
+import org.apache.skywalking.oap.query.prometheus.entity.response.LabelsQueryRsp;
+import org.apache.skywalking.oap.query.prometheus.entity.ResultStatus;
+import org.apache.skywalking.oap.query.prometheus.entity.response.MetricRspData;
+import org.apache.skywalking.oap.query.prometheus.entity.response.MetadataQueryRsp;
+import org.apache.skywalking.oap.query.prometheus.entity.response.MetricType;
+import org.apache.skywalking.oap.query.prometheus.entity.response.QueryResponse;
+import org.apache.skywalking.oap.query.prometheus.entity.response.ResultType;
+import org.apache.skywalking.oap.query.prometheus.entity.response.ScalarRspData;
+import org.apache.skywalking.oap.query.prometheus.entity.response.SeriesQueryRsp;
+import org.apache.skywalking.oap.query.prometheus.rt.PromOpUtils;
+import org.apache.skywalking.oap.query.prometheus.rt.PromQLMatchVisitor;
+import org.apache.skywalking.oap.query.prometheus.rt.exception.ParseErrorListener;
+import org.apache.skywalking.oap.query.prometheus.rt.result.MatcherSetResult;
+import org.apache.skywalking.oap.query.prometheus.rt.result.MetricsRangeResult;
+import org.apache.skywalking.oap.query.prometheus.rt.PromQLExprQueryVisitor;
+import org.apache.skywalking.oap.query.prometheus.rt.result.ParseResult;
+import org.apache.skywalking.oap.query.prometheus.rt.result.ScalarResult;
+import org.apache.skywalking.oap.server.core.analysis.IDManager;
+import org.apache.skywalking.oap.server.core.analysis.Layer;
+import org.apache.skywalking.oap.server.core.analysis.manual.endpoint.EndpointTraffic;
+import org.apache.skywalking.oap.server.core.analysis.manual.instance.InstanceTraffic;
+import org.apache.skywalking.oap.server.core.analysis.manual.service.ServiceTraffic;
+import org.apache.skywalking.oap.server.core.query.MetricDefinition;
+import org.apache.skywalking.oap.server.core.query.enumeration.Scope;
+import org.apache.skywalking.oap.server.core.query.input.Duration;
+import org.apache.skywalking.oap.server.core.query.type.Endpoint;
+import org.apache.skywalking.oap.server.core.query.type.Service;
+import org.apache.skywalking.oap.server.core.query.type.ServiceInstance;
+import org.apache.skywalking.oap.server.core.storage.annotation.Column;
+import org.apache.skywalking.oap.server.core.storage.annotation.ValueColumnMetadata;
+import org.apache.skywalking.oap.server.library.module.ModuleManager;
+import org.apache.skywalking.oap.server.library.util.StringUtil;
+import org.apache.skywalking.promql.rt.grammar.PromQLLexer;
+import org.apache.skywalking.promql.rt.grammar.PromQLParser;
+
+import static org.apache.skywalking.oap.query.prometheus.rt.PromOpUtils.formatDoubleValue;
+import static org.apache.skywalking.oap.query.prometheus.rt.PromOpUtils.timestamp2Duration;
+
+public class PrometheusApiHandler {
+    private final PrometheusQueryConfig config;
+    private final MetadataQueryV2 metadataQuery;
+    private final MetricsQuery metricsQuery;
+    private final RecordsQuery recordsQuery;
+    private static final ObjectMapper MAPPER = new ObjectMapper();
+
+    public PrometheusApiHandler(final PrometheusQueryConfig config,
+                                ModuleManager moduleManager) {
+        this.config = config;
+        this.metadataQuery = new MetadataQueryV2(moduleManager);
+        this.metricsQuery = new MetricsQuery(moduleManager);
+        this.recordsQuery = new RecordsQuery(moduleManager);
+    }
+
+    @Get
+    @Post
+    @Path("/api/v1/metadata")
+    public HttpResponse metadata(
+        @Param("limit") Optional<Integer> limit,
+        @Param("metric") Optional<String> metric) throws JsonProcessingException {
+        MetadataQueryRsp response = new MetadataQueryRsp();
+        response.setStatus(ResultStatus.success);
+        String regex = "";
+        if (metric.isPresent()) {
+            regex = metric.get();
+        }
+        List<MetricDefinition> definitionList = metricsQuery.listMetrics(regex);
+        int maxNum = definitionList.size();
+        if (limit.isPresent()) {
+            maxNum = limit.get();
+        }
+        for (int i = 0; i < maxNum; i++) {
+            List<MetricMetadata> metadataList = new ArrayList<>();
+            MetricMetadata metadata = new MetricMetadata(MetricType.gauge, "", "");
+            metadataList.add(metadata);
+            response.getData().put(definitionList.get(i).getName(), metadataList);
+        }
+        return jsonResponse(response);
+    }
+
+    @Get
+    @Post
+    @Path("/api/v1/labels")
+    public HttpResponse labels(
+        @Param("match[]") Optional<String> match,
+        @Param("start") Optional<String> start,
+        @Param("end") Optional<String> end) throws IOException {
+        LabelsQueryRsp response = new LabelsQueryRsp();
+        if (match.isPresent()) {
+            PromQLLexer lexer = new PromQLLexer(
+                CharStreams.fromString(match.get()));
+            lexer.addErrorListener(ParseErrorListener.INSTANCE);
+            PromQLParser parser = new PromQLParser(new CommonTokenStream(lexer));
+            parser.addErrorListener(ParseErrorListener.INSTANCE);
+            ParseTree tree;
+            try {
+                tree = parser.expression();
+            } catch (ParseCancellationException e) {
+                response.setStatus(ResultStatus.error);
+                response.setErrorType(ErrorType.bad_data.name());
+                response.setError(e.getMessage());
+                return jsonResponse(response);
+            }
+            PromQLMatchVisitor visitor = new PromQLMatchVisitor();
+            MatcherSetResult parseResult = visitor.visit(tree);
+            String metricName = parseResult.getMetricName();
+            Optional<ValueColumnMetadata.ValueColumn> valueColumn = ValueColumnMetadata.INSTANCE.readValueColumnDefinition(
+                metricName);
+            if (valueColumn.isPresent()) {
+                ValueColumnMetadata.ValueColumn metaData = valueColumn.get();
+                Scope scope = Scope.Finder.valueOf(metaData.getScopeId());
+                Column.ValueDataType dataType = metaData.getDataType();
+                response.getData().addAll(buildLabelNames(scope, dataType));
+            }
+        } else {
+            Arrays.stream(LabelName.values()).forEach(label -> {
+                response.getData().add(label);
+            });
+        }
+        response.setStatus(ResultStatus.success);
+        return jsonResponse(response);
+    }
+
+    @Get
+    @Post
+    @Path("/api/v1/label/{label_name}/values")
+    public HttpResponse labelValues(
+        @Param("label_name") String labelName,
+        @Param("match[]") Optional<String> match,
+        @Param("start") Optional<String> start,
+        @Param("end") Optional<String> end) throws IOException {

Review Comment:
   Why are these 3 parameters not used but listed here?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@skywalking.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [skywalking] kezhenxu94 commented on a diff in pull request #10415: Support prometheus HTTP API and promQL.

Posted by "kezhenxu94 (via GitHub)" <gi...@apache.org>.
kezhenxu94 commented on code in PR #10415:
URL: https://github.com/apache/skywalking/pull/10415#discussion_r1111770727


##########
oap-server/server-query-plugin/prometheus-query-plugin/src/main/java/org/apache/skywalking/oap/query/prometheus/handler/PrometheusApiHandler.java:
##########
@@ -0,0 +1,544 @@
+/*
+ * 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.query.prometheus.handler;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.linecorp.armeria.common.HttpData;
+import com.linecorp.armeria.common.HttpResponse;
+import com.linecorp.armeria.common.HttpStatus;
+import com.linecorp.armeria.common.MediaType;
+import com.linecorp.armeria.common.ResponseHeaders;
+import com.linecorp.armeria.server.annotation.Blocking;
+import com.linecorp.armeria.server.annotation.Get;
+import com.linecorp.armeria.server.annotation.Param;
+import com.linecorp.armeria.server.annotation.Path;
+import com.linecorp.armeria.server.annotation.Post;
+import graphql.org.antlr.v4.runtime.misc.ParseCancellationException;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+import org.antlr.v4.runtime.CharStreams;
+import org.antlr.v4.runtime.CommonTokenStream;
+import org.antlr.v4.runtime.tree.ParseTree;
+import org.apache.skywalking.oap.query.graphql.resolver.MetadataQueryV2;
+import org.apache.skywalking.oap.query.graphql.resolver.MetricsQuery;
+import org.apache.skywalking.oap.query.graphql.resolver.RecordsQuery;
+import org.apache.skywalking.oap.query.prometheus.PrometheusQueryConfig;
+import org.apache.skywalking.oap.query.prometheus.entity.ErrorType;
+import org.apache.skywalking.oap.query.prometheus.entity.LabelName;
+import org.apache.skywalking.oap.query.prometheus.entity.LabelValuePair;
+import org.apache.skywalking.oap.query.prometheus.entity.MetricInstantData;
+import org.apache.skywalking.oap.query.prometheus.entity.MetricMetadata;
+import org.apache.skywalking.oap.query.prometheus.entity.MetricRangeData;
+import org.apache.skywalking.oap.query.prometheus.entity.TimeValuePair;
+import org.apache.skywalking.oap.query.prometheus.entity.response.ExprQueryRsp;
+import org.apache.skywalking.oap.query.prometheus.entity.MetricInfo;
+import org.apache.skywalking.oap.query.prometheus.entity.response.LabelValuesQueryRsp;
+import org.apache.skywalking.oap.query.prometheus.entity.response.LabelsQueryRsp;
+import org.apache.skywalking.oap.query.prometheus.entity.ResultStatus;
+import org.apache.skywalking.oap.query.prometheus.entity.response.MetricRspData;
+import org.apache.skywalking.oap.query.prometheus.entity.response.MetadataQueryRsp;
+import org.apache.skywalking.oap.query.prometheus.entity.response.MetricType;
+import org.apache.skywalking.oap.query.prometheus.entity.response.QueryResponse;
+import org.apache.skywalking.oap.query.prometheus.entity.response.ResultType;
+import org.apache.skywalking.oap.query.prometheus.entity.response.ScalarRspData;
+import org.apache.skywalking.oap.query.prometheus.entity.response.SeriesQueryRsp;
+import org.apache.skywalking.oap.query.prometheus.rt.PromOpUtils;
+import org.apache.skywalking.oap.query.prometheus.rt.PromQLMatchVisitor;
+import org.apache.skywalking.oap.query.prometheus.rt.exception.ParseErrorListener;
+import org.apache.skywalking.oap.query.prometheus.rt.result.MatcherSetResult;
+import org.apache.skywalking.oap.query.prometheus.rt.result.MetricsRangeResult;
+import org.apache.skywalking.oap.query.prometheus.rt.PromQLExprQueryVisitor;
+import org.apache.skywalking.oap.query.prometheus.rt.result.ParseResult;
+import org.apache.skywalking.oap.query.prometheus.rt.result.ScalarResult;
+import org.apache.skywalking.oap.server.core.analysis.IDManager;
+import org.apache.skywalking.oap.server.core.analysis.Layer;
+import org.apache.skywalking.oap.server.core.analysis.manual.endpoint.EndpointTraffic;
+import org.apache.skywalking.oap.server.core.analysis.manual.instance.InstanceTraffic;
+import org.apache.skywalking.oap.server.core.analysis.manual.service.ServiceTraffic;
+import org.apache.skywalking.oap.server.core.query.MetricDefinition;
+import org.apache.skywalking.oap.server.core.query.enumeration.Scope;
+import org.apache.skywalking.oap.server.core.query.input.Duration;
+import org.apache.skywalking.oap.server.core.query.type.Endpoint;
+import org.apache.skywalking.oap.server.core.query.type.Service;
+import org.apache.skywalking.oap.server.core.query.type.ServiceInstance;
+import org.apache.skywalking.oap.server.core.storage.annotation.Column;
+import org.apache.skywalking.oap.server.core.storage.annotation.ValueColumnMetadata;
+import org.apache.skywalking.oap.server.library.module.ModuleManager;
+import org.apache.skywalking.oap.server.library.util.StringUtil;
+import org.apache.skywalking.promql.rt.grammar.PromQLLexer;
+import org.apache.skywalking.promql.rt.grammar.PromQLParser;
+
+import static org.apache.skywalking.oap.query.prometheus.rt.PromOpUtils.formatDoubleValue;
+import static org.apache.skywalking.oap.query.prometheus.rt.PromOpUtils.timestamp2Duration;
+
+public class PrometheusApiHandler {
+    private final PrometheusQueryConfig config;
+    private final MetadataQueryV2 metadataQuery;
+    private final MetricsQuery metricsQuery;
+    private final RecordsQuery recordsQuery;
+    private static final ObjectMapper MAPPER = new ObjectMapper();
+
+    public PrometheusApiHandler(final PrometheusQueryConfig config,
+                                ModuleManager moduleManager) {
+        this.config = config;
+        this.metadataQuery = new MetadataQueryV2(moduleManager);
+        this.metricsQuery = new MetricsQuery(moduleManager);
+        this.recordsQuery = new RecordsQuery(moduleManager);
+    }
+
+    @Get
+    @Post
+    @Path("/api/v1/metadata")
+    public HttpResponse metadata(
+        @Param("limit") Optional<Integer> limit,
+        @Param("metric") Optional<String> metric) throws JsonProcessingException {
+        MetadataQueryRsp response = new MetadataQueryRsp();
+        response.setStatus(ResultStatus.success);
+        String regex = "";
+        if (metric.isPresent()) {
+            regex = metric.get();
+        }

Review Comment:
   This looks neater, also revise other places where `Optional` appears.
   
   ```suggestion
           String regex = metric.orElse("");
   ```



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@skywalking.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [skywalking] kezhenxu94 commented on a diff in pull request #10415: Support prometheus HTTP API and promQL.

Posted by "kezhenxu94 (via GitHub)" <gi...@apache.org>.
kezhenxu94 commented on code in PR #10415:
URL: https://github.com/apache/skywalking/pull/10415#discussion_r1111751110


##########
oap-server/server-query-plugin/prometheus-query-plugin/src/test/java/org/apache/skywalking/prometheus/rt/parser/PromQLMatchVisitorTest.java:
##########
@@ -0,0 +1,28 @@
+package org.apache.skywalking.prometheus.rt.parser;
+
+import org.antlr.v4.runtime.CharStreams;
+import org.antlr.v4.runtime.CommonTokenStream;
+import org.antlr.v4.runtime.tree.ParseTree;
+import org.apache.skywalking.oap.query.prometheus.rt.PromQLMatchVisitor;
+import org.apache.skywalking.oap.query.prometheus.rt.result.MatcherSetResult;
+import org.apache.skywalking.oap.query.prometheus.rt.result.ParseResultType;
+import org.apache.skywalking.promql.rt.grammar.PromQLLexer;
+import org.apache.skywalking.promql.rt.grammar.PromQLParser;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+public class PromQLMatchVisitorTest {
+        @Test
+        public void testMatchVisitor() {
+            PromQLLexer lexer = new PromQLLexer(
+                CharStreams.fromString("service_cpm{service='serviceA', layer='GENERAL'}"));
+            CommonTokenStream tokens = new CommonTokenStream(lexer);
+            PromQLParser parser = new PromQLParser(tokens);
+            ParseTree tree = parser.expression();
+            PromQLMatchVisitor visitor = new PromQLMatchVisitor();
+            MatcherSetResult parseResult = visitor.visit(tree);
+            Assertions.assertEquals(ParseResultType.match, parseResult.getResultType());
+            Assertions.assertEquals("service_cpm", parseResult.getMetricName());
+            Assertions.assertEquals(2, parseResult.getLabelMap().size());
+        }

Review Comment:
   The indentation looks bad



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@skywalking.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [skywalking] wu-sheng merged pull request #10415: Support prometheus HTTP API and promQL.

Posted by "wu-sheng (via GitHub)" <gi...@apache.org>.
wu-sheng merged PR #10415:
URL: https://github.com/apache/skywalking/pull/10415


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@skywalking.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [skywalking] kezhenxu94 commented on a diff in pull request #10415: Support prometheus HTTP API and promQL.

Posted by "kezhenxu94 (via GitHub)" <gi...@apache.org>.
kezhenxu94 commented on code in PR #10415:
URL: https://github.com/apache/skywalking/pull/10415#discussion_r1111731707


##########
oap-server/server-query-plugin/prometheus-query-plugin/src/main/java/org/apache/skywalking/oap/query/prometheus/entity/ErrorType.java:
##########
@@ -0,0 +1,25 @@
+/*
+ * 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.query.prometheus.entity;
+
+public enum ErrorType {
+    bad_data,
+    internal

Review Comment:
   The naming convention of enum in Java is all uppercase



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@skywalking.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [skywalking] wu-sheng commented on pull request #10415: Support prometheus HTTP API and promQL.

Posted by "wu-sheng (via GitHub)" <gi...@apache.org>.
wu-sheng commented on PR #10415:
URL: https://github.com/apache/skywalking/pull/10415#issuecomment-1436666106

   > A Grafana dashboards demo based on this feature can visit:
   http://34.92.90.119:3000/
   admin/admin
   
   Once this PR gets merged, please free this public IP. We don't want this gets logged and become a leak one day.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@skywalking.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [skywalking] wankai123 commented on a diff in pull request #10415: Support prometheus HTTP API and promQL.

Posted by "wankai123 (via GitHub)" <gi...@apache.org>.
wankai123 commented on code in PR #10415:
URL: https://github.com/apache/skywalking/pull/10415#discussion_r1113784957


##########
oap-server/server-query-plugin/prometheus-query-plugin/src/main/java/org/apache/skywalking/oap/query/prometheus/handler/PrometheusApiHandler.java:
##########
@@ -0,0 +1,544 @@
+/*
+ * 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.query.prometheus.handler;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.linecorp.armeria.common.HttpData;
+import com.linecorp.armeria.common.HttpResponse;
+import com.linecorp.armeria.common.HttpStatus;
+import com.linecorp.armeria.common.MediaType;
+import com.linecorp.armeria.common.ResponseHeaders;
+import com.linecorp.armeria.server.annotation.Blocking;
+import com.linecorp.armeria.server.annotation.Get;
+import com.linecorp.armeria.server.annotation.Param;
+import com.linecorp.armeria.server.annotation.Path;
+import com.linecorp.armeria.server.annotation.Post;
+import graphql.org.antlr.v4.runtime.misc.ParseCancellationException;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+import org.antlr.v4.runtime.CharStreams;
+import org.antlr.v4.runtime.CommonTokenStream;
+import org.antlr.v4.runtime.tree.ParseTree;
+import org.apache.skywalking.oap.query.graphql.resolver.MetadataQueryV2;
+import org.apache.skywalking.oap.query.graphql.resolver.MetricsQuery;
+import org.apache.skywalking.oap.query.graphql.resolver.RecordsQuery;
+import org.apache.skywalking.oap.query.prometheus.PrometheusQueryConfig;
+import org.apache.skywalking.oap.query.prometheus.entity.ErrorType;
+import org.apache.skywalking.oap.query.prometheus.entity.LabelName;
+import org.apache.skywalking.oap.query.prometheus.entity.LabelValuePair;
+import org.apache.skywalking.oap.query.prometheus.entity.MetricInstantData;
+import org.apache.skywalking.oap.query.prometheus.entity.MetricMetadata;
+import org.apache.skywalking.oap.query.prometheus.entity.MetricRangeData;
+import org.apache.skywalking.oap.query.prometheus.entity.TimeValuePair;
+import org.apache.skywalking.oap.query.prometheus.entity.response.ExprQueryRsp;
+import org.apache.skywalking.oap.query.prometheus.entity.MetricInfo;
+import org.apache.skywalking.oap.query.prometheus.entity.response.LabelValuesQueryRsp;
+import org.apache.skywalking.oap.query.prometheus.entity.response.LabelsQueryRsp;
+import org.apache.skywalking.oap.query.prometheus.entity.ResultStatus;
+import org.apache.skywalking.oap.query.prometheus.entity.response.MetricRspData;
+import org.apache.skywalking.oap.query.prometheus.entity.response.MetadataQueryRsp;
+import org.apache.skywalking.oap.query.prometheus.entity.response.MetricType;
+import org.apache.skywalking.oap.query.prometheus.entity.response.QueryResponse;
+import org.apache.skywalking.oap.query.prometheus.entity.response.ResultType;
+import org.apache.skywalking.oap.query.prometheus.entity.response.ScalarRspData;
+import org.apache.skywalking.oap.query.prometheus.entity.response.SeriesQueryRsp;
+import org.apache.skywalking.oap.query.prometheus.rt.PromOpUtils;
+import org.apache.skywalking.oap.query.prometheus.rt.PromQLMatchVisitor;
+import org.apache.skywalking.oap.query.prometheus.rt.exception.ParseErrorListener;
+import org.apache.skywalking.oap.query.prometheus.rt.result.MatcherSetResult;
+import org.apache.skywalking.oap.query.prometheus.rt.result.MetricsRangeResult;
+import org.apache.skywalking.oap.query.prometheus.rt.PromQLExprQueryVisitor;
+import org.apache.skywalking.oap.query.prometheus.rt.result.ParseResult;
+import org.apache.skywalking.oap.query.prometheus.rt.result.ScalarResult;
+import org.apache.skywalking.oap.server.core.analysis.IDManager;
+import org.apache.skywalking.oap.server.core.analysis.Layer;
+import org.apache.skywalking.oap.server.core.analysis.manual.endpoint.EndpointTraffic;
+import org.apache.skywalking.oap.server.core.analysis.manual.instance.InstanceTraffic;
+import org.apache.skywalking.oap.server.core.analysis.manual.service.ServiceTraffic;
+import org.apache.skywalking.oap.server.core.query.MetricDefinition;
+import org.apache.skywalking.oap.server.core.query.enumeration.Scope;
+import org.apache.skywalking.oap.server.core.query.input.Duration;
+import org.apache.skywalking.oap.server.core.query.type.Endpoint;
+import org.apache.skywalking.oap.server.core.query.type.Service;
+import org.apache.skywalking.oap.server.core.query.type.ServiceInstance;
+import org.apache.skywalking.oap.server.core.storage.annotation.Column;
+import org.apache.skywalking.oap.server.core.storage.annotation.ValueColumnMetadata;
+import org.apache.skywalking.oap.server.library.module.ModuleManager;
+import org.apache.skywalking.oap.server.library.util.StringUtil;
+import org.apache.skywalking.promql.rt.grammar.PromQLLexer;
+import org.apache.skywalking.promql.rt.grammar.PromQLParser;
+
+import static org.apache.skywalking.oap.query.prometheus.rt.PromOpUtils.formatDoubleValue;
+import static org.apache.skywalking.oap.query.prometheus.rt.PromOpUtils.timestamp2Duration;
+
+public class PrometheusApiHandler {
+    private final PrometheusQueryConfig config;
+    private final MetadataQueryV2 metadataQuery;
+    private final MetricsQuery metricsQuery;
+    private final RecordsQuery recordsQuery;
+    private static final ObjectMapper MAPPER = new ObjectMapper();
+
+    public PrometheusApiHandler(final PrometheusQueryConfig config,
+                                ModuleManager moduleManager) {
+        this.config = config;
+        this.metadataQuery = new MetadataQueryV2(moduleManager);
+        this.metricsQuery = new MetricsQuery(moduleManager);
+        this.recordsQuery = new RecordsQuery(moduleManager);
+    }
+
+    @Get
+    @Post
+    @Path("/api/v1/metadata")
+    public HttpResponse metadata(
+        @Param("limit") Optional<Integer> limit,
+        @Param("metric") Optional<String> metric) throws JsonProcessingException {
+        MetadataQueryRsp response = new MetadataQueryRsp();
+        response.setStatus(ResultStatus.success);
+        String regex = "";
+        if (metric.isPresent()) {
+            regex = metric.get();
+        }
+        List<MetricDefinition> definitionList = metricsQuery.listMetrics(regex);
+        int maxNum = definitionList.size();
+        if (limit.isPresent()) {
+            maxNum = limit.get();
+        }
+        for (int i = 0; i < maxNum; i++) {
+            List<MetricMetadata> metadataList = new ArrayList<>();
+            MetricMetadata metadata = new MetricMetadata(MetricType.gauge, "", "");
+            metadataList.add(metadata);
+            response.getData().put(definitionList.get(i).getName(), metadataList);
+        }
+        return jsonResponse(response);
+    }
+
+    @Get
+    @Post
+    @Path("/api/v1/labels")
+    public HttpResponse labels(
+        @Param("match[]") Optional<String> match,
+        @Param("start") Optional<String> start,
+        @Param("end") Optional<String> end) throws IOException {
+        LabelsQueryRsp response = new LabelsQueryRsp();
+        if (match.isPresent()) {
+            PromQLLexer lexer = new PromQLLexer(
+                CharStreams.fromString(match.get()));
+            lexer.addErrorListener(ParseErrorListener.INSTANCE);
+            PromQLParser parser = new PromQLParser(new CommonTokenStream(lexer));
+            parser.addErrorListener(ParseErrorListener.INSTANCE);
+            ParseTree tree;
+            try {
+                tree = parser.expression();
+            } catch (ParseCancellationException e) {
+                response.setStatus(ResultStatus.error);
+                response.setErrorType(ErrorType.bad_data.name());
+                response.setError(e.getMessage());
+                return jsonResponse(response);
+            }
+            PromQLMatchVisitor visitor = new PromQLMatchVisitor();
+            MatcherSetResult parseResult = visitor.visit(tree);
+            String metricName = parseResult.getMetricName();
+            Optional<ValueColumnMetadata.ValueColumn> valueColumn = ValueColumnMetadata.INSTANCE.readValueColumnDefinition(
+                metricName);
+            if (valueColumn.isPresent()) {
+                ValueColumnMetadata.ValueColumn metaData = valueColumn.get();
+                Scope scope = Scope.Finder.valueOf(metaData.getScopeId());
+                Column.ValueDataType dataType = metaData.getDataType();
+                response.getData().addAll(buildLabelNames(scope, dataType));
+            }
+        } else {
+            Arrays.stream(LabelName.values()).forEach(label -> {
+                response.getData().add(label);
+            });
+        }
+        response.setStatus(ResultStatus.success);
+        return jsonResponse(response);
+    }
+
+    @Get
+    @Post
+    @Path("/api/v1/label/{label_name}/values")
+    public HttpResponse labelValues(
+        @Param("label_name") String labelName,
+        @Param("match[]") Optional<String> match,
+        @Param("start") Optional<String> start,
+        @Param("end") Optional<String> end) throws IOException {

Review Comment:
   Reserve these param to keep consistent with API protocol, have add commons on methods



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@skywalking.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org