You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@skywalking.apache.org by wu...@apache.org on 2018/09/10 15:53:16 UTC

[incubator-skywalking-oal-tool] branch master updated: Add for Pxx.

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

wusheng pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-skywalking-oal-tool.git


The following commit(s) were added to refs/heads/master by this push:
     new 3d903a8  Add for Pxx.
3d903a8 is described below

commit 3d903a8325eae21d2cee06fd09bf0da17c61bf09
Author: Wu Sheng <wu...@foxmail.com>
AuthorDate: Mon Sep 10 23:53:06 2018 +0800

    Add for Pxx.
---
 .../oal/tool/output/DispatcherContext.java         |   1 +
 .../skywalking/oal/tool/output/FileGenerator.java  |  13 ++-
 .../skywalking/oal/tool/parser/AnalysisResult.java |  17 +++
 .../skywalking/oal/tool/parser/DeepAnalysis.java   |  22 +++-
 .../skywalking/oal/tool/parser/OALListener.java    |   3 +
 .../oal/tool/parser/PersistenceColumns.java        |   9 ++
 .../oal/tool/parser/SourceColumnsFactory.java      |   2 +
 .../skywalking/oap/server/core/Indicators.java     |   5 +
 .../indicator/IntKeyLongValue.java}                |  48 +++++---
 .../core/analysis/indicator/P50Indicator.java      |  30 +++++
 .../core/analysis/indicator/P75Indicator.java      |  30 +++++
 .../core/analysis/indicator/P90Indicator.java      |  30 +++++
 .../core/analysis/indicator/P95Indicator.java      |  30 +++++
 .../core/analysis/indicator/P99Indicator.java      |  30 +++++
 .../core/analysis/indicator/PxxIndicator.java      | 125 +++++++++++++++++++++
 .../core/analysis/indicator/annotation/Arg.java    |  32 ++++++
 .../code-templates/AllDispatcherTemplate.ftl       |  65 +++++++++++
 .../code-templates/IndicatorImplementor.ftl        |  13 ++-
 .../IndicatorImplementorExpected.java              |   2 +
 oal-parser/src/test/resources/oal_test.oal         |   2 +
 .../apache/skywalking/oal/tool/grammar/OALLexer.g4 |   4 +-
 .../skywalking/oal/tool/grammar/OALLexer.tokens    |   4 +-
 .../skywalking/oal/tool/grammar/OALParser.g4       |   6 +-
 23 files changed, 496 insertions(+), 27 deletions(-)

diff --git a/oal-parser/src/main/java/org/apache/skywalking/oal/tool/output/DispatcherContext.java b/oal-parser/src/main/java/org/apache/skywalking/oal/tool/output/DispatcherContext.java
index d8f3dbd..c5eb829 100644
--- a/oal-parser/src/main/java/org/apache/skywalking/oal/tool/output/DispatcherContext.java
+++ b/oal-parser/src/main/java/org/apache/skywalking/oal/tool/output/DispatcherContext.java
@@ -28,6 +28,7 @@ import org.apache.skywalking.oal.tool.parser.AnalysisResult;
 @Getter(AccessLevel.PUBLIC)
 @Setter(AccessLevel.PUBLIC)
 public class DispatcherContext {
+    private List<AnalysisResult> allIndicators = new LinkedList<>();
     private List<AnalysisResult> serviceIndicators = new LinkedList<>();
     private List<AnalysisResult> serviceInstanceIndicators = new LinkedList<>();
     private List<AnalysisResult> endpointIndicators = new LinkedList<>();
diff --git a/oal-parser/src/main/java/org/apache/skywalking/oal/tool/output/FileGenerator.java b/oal-parser/src/main/java/org/apache/skywalking/oal/tool/output/FileGenerator.java
index 7e3a17b..dd4b29d 100644
--- a/oal-parser/src/main/java/org/apache/skywalking/oal/tool/output/FileGenerator.java
+++ b/oal-parser/src/main/java/org/apache/skywalking/oal/tool/output/FileGenerator.java
@@ -49,7 +49,11 @@ public class FileGenerator {
             generate(result, "Indicator.java", (writer) -> generateIndicatorImplementor(result, writer));
         }
 
-        File file = new File(outputPath, "generated/service/ServiceDispatcher.java");
+        File file = new File(outputPath, "generated/all/AllDispatcher.java");
+        createFile(file);
+        this.generateAllDispatcher(new FileWriter(file));
+
+        file = new File(outputPath, "generated/service/ServiceDispatcher.java");
         createFile(file);
         this.generateServiceDispatcher(new FileWriter(file));
 
@@ -121,6 +125,10 @@ public class FileGenerator {
         configuration.getTemplate("IndicatorImplementor.ftl").process(result, output);
     }
 
+    void generateAllDispatcher(Writer output) throws IOException, TemplateException {
+        configuration.getTemplate("AllDispatcherTemplate.ftl").process(dispatcherContext, output);
+    }
+
     void generateServiceDispatcher(Writer output) throws IOException, TemplateException {
         configuration.getTemplate("ServiceDispatcherTemplate.ftl").process(dispatcherContext, output);
     }
@@ -166,6 +174,9 @@ public class FileGenerator {
         for (AnalysisResult result : results) {
             String sourceName = result.getSourceName();
             switch (sourceName) {
+                case "All":
+                    dispatcherContext.getAllIndicators().add(result);
+                    break;
                 case "Service":
                     dispatcherContext.getServiceIndicators().add(result);
                     break;
diff --git a/oal-parser/src/main/java/org/apache/skywalking/oal/tool/parser/AnalysisResult.java b/oal-parser/src/main/java/org/apache/skywalking/oal/tool/parser/AnalysisResult.java
index c1fe744..2b68f5d 100644
--- a/oal-parser/src/main/java/org/apache/skywalking/oal/tool/parser/AnalysisResult.java
+++ b/oal-parser/src/main/java/org/apache/skywalking/oal/tool/parser/AnalysisResult.java
@@ -51,6 +51,9 @@ public class AnalysisResult {
 
     private List<ConditionExpression> funcConditionExpressions;
 
+    private List<String> funcArgs;
+    private int argGetIdx = 0;
+
     private List<DataColumn> persistentFields;
 
     private List<SourceColumn> fieldsFromSource;
@@ -86,6 +89,17 @@ public class AnalysisResult {
         filterExpressionsParserResult.add(conditionExpression);
     }
 
+    public void addFuncArg(String value) {
+        if (funcArgs == null) {
+            funcArgs = new LinkedList<>();
+        }
+        funcArgs.add(value);
+    }
+
+    public String getNextFuncArg() {
+        return funcArgs.get(argGetIdx++);
+    }
+
     public void generateSerializeFields() {
         serializeFields = new PersistenceColumns();
         for (SourceColumn sourceColumn : fieldsFromSource) {
@@ -123,6 +137,9 @@ public class AnalysisResult {
                 case "long":
                     serializeFields.addLongField(column.getFieldName());
                     break;
+                case "List":
+                    serializeFields.addIntLongValuePairelistField(column.getFieldName());
+                    break;
                 default:
                     throw new IllegalStateException("Unexpected field type [" + type + "] of persistence column [" + column.getFieldName() + "]");
             }
diff --git a/oal-parser/src/main/java/org/apache/skywalking/oal/tool/parser/DeepAnalysis.java b/oal-parser/src/main/java/org/apache/skywalking/oal/tool/parser/DeepAnalysis.java
index 90ea536..c75c675 100644
--- a/oal-parser/src/main/java/org/apache/skywalking/oal/tool/parser/DeepAnalysis.java
+++ b/oal-parser/src/main/java/org/apache/skywalking/oal/tool/parser/DeepAnalysis.java
@@ -26,6 +26,7 @@ import java.util.List;
 import org.apache.skywalking.oal.tool.util.ClassMethodUtil;
 import org.apache.skywalking.oap.server.core.Indicators;
 import org.apache.skywalking.oap.server.core.analysis.indicator.Indicator;
+import org.apache.skywalking.oap.server.core.analysis.indicator.annotation.Arg;
 import org.apache.skywalking.oap.server.core.analysis.indicator.annotation.ConstOne;
 import org.apache.skywalking.oap.server.core.analysis.indicator.annotation.Entrance;
 import org.apache.skywalking.oap.server.core.analysis.indicator.annotation.Expression;
@@ -41,13 +42,26 @@ public class DeepAnalysis {
         result.setPackageName(result.getSourceName().toLowerCase());
 
         Class<? extends Indicator> indicatorClass = Indicators.find(result.getAggregationFunctionName());
+        String indicatorClassSimpleName = indicatorClass.getSimpleName();
 
         // 2. Assert indicator class has IndicatorOperator annotation.
-        IndicatorOperator indicatorClassAnnotation = indicatorClass.getAnnotation(IndicatorOperator.class);
+        // 2. Assert indicator class has IndicatorOperator annotation.
+        IndicatorOperator indicatorClassAnnotation = null;
+        do {
+            indicatorClassAnnotation = indicatorClass.getAnnotation(IndicatorOperator.class);
+            if (indicatorClassAnnotation == null) {
+                indicatorClass = (Class<? extends Indicator>)indicatorClass.getSuperclass();
+                if (indicatorClass.equals(Indicator.class)) {
+                    break;
+                }
+            }
+        }
+        while (indicatorClassAnnotation == null);
+
         if (indicatorClassAnnotation == null) {
             throw new IllegalArgumentException("Can't find IndicatorOperator in class: " + indicatorClass.getName());
         }
-        result.setIndicatorClassName(indicatorClass.getSimpleName());
+        result.setIndicatorClassName(indicatorClassSimpleName);
 
         // Optional for filter
         List<ConditionExpression> expressions = result.getFilterExpressionsParserResult();
@@ -64,7 +78,7 @@ public class DeepAnalysis {
                     filterExpression.setLeft("source." + ClassMethodUtil.toGetMethod(expression.getAttribute()) + "()");
                     filterExpression.setRight(expression.getValue());
                     result.addFilterExpressions(filterExpression);
-                } else{
+                } else {
                     throw new IllegalArgumentException("filter expression [" + expression.getExpressionType() + "] not found");
                 }
             }
@@ -124,6 +138,8 @@ public class DeepAnalysis {
                 } else {
                     throw new IllegalArgumentException("Entrance method:" + entranceMethod + " argument has @ExpressionArg0, but can't find funcParamExpression.");
                 }
+            } else if (annotation instanceof Arg) {
+                entryMethod.addArg(result.getNextFuncArg());
             } else {
                 throw new IllegalArgumentException("Entrance method:" + entranceMethod + " doesn't the expected annotation.");
             }
diff --git a/oal-parser/src/main/java/org/apache/skywalking/oal/tool/parser/OALListener.java b/oal-parser/src/main/java/org/apache/skywalking/oal/tool/parser/OALListener.java
index e306307..8c90642 100644
--- a/oal-parser/src/main/java/org/apache/skywalking/oal/tool/parser/OALListener.java
+++ b/oal-parser/src/main/java/org/apache/skywalking/oal/tool/parser/OALListener.java
@@ -116,6 +116,9 @@ public class OALListener extends OALParserBaseListener {
     // Expression end.
     ////////////
 
+    @Override public void enterLiteralExpression(OALParser.LiteralExpressionContext ctx) {
+        current.addFuncArg(ctx.getText());
+    }
 
     private String metricNameFormat(String source) {
         source = firstLetterUpper(source);
diff --git a/oal-parser/src/main/java/org/apache/skywalking/oal/tool/parser/PersistenceColumns.java b/oal-parser/src/main/java/org/apache/skywalking/oal/tool/parser/PersistenceColumns.java
index 448755d..82cf2e8 100644
--- a/oal-parser/src/main/java/org/apache/skywalking/oal/tool/parser/PersistenceColumns.java
+++ b/oal-parser/src/main/java/org/apache/skywalking/oal/tool/parser/PersistenceColumns.java
@@ -26,6 +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> intLongValuePairListFields = new LinkedList<>();
 
     public void addStringField(String fieldName) {
         stringFields.add(new PersistenceField(fieldName));
@@ -43,6 +44,10 @@ public class PersistenceColumns {
         intFields.add(new PersistenceField(fieldName));
     }
 
+    public void addIntLongValuePairelistField(String fieldName) {
+        intLongValuePairListFields.add(new PersistenceField(fieldName));
+    }
+
     public List<PersistenceField> getStringFields() {
         return stringFields;
     }
@@ -58,4 +63,8 @@ public class PersistenceColumns {
     public List<PersistenceField> getIntFields() {
         return intFields;
     }
+
+    public List<PersistenceField> getIntLongValuePairListFields() {
+        return intLongValuePairListFields;
+    }
 }
diff --git a/oal-parser/src/main/java/org/apache/skywalking/oal/tool/parser/SourceColumnsFactory.java b/oal-parser/src/main/java/org/apache/skywalking/oal/tool/parser/SourceColumnsFactory.java
index 6b2fce3..f0312d5 100644
--- a/oal-parser/src/main/java/org/apache/skywalking/oal/tool/parser/SourceColumnsFactory.java
+++ b/oal-parser/src/main/java/org/apache/skywalking/oal/tool/parser/SourceColumnsFactory.java
@@ -25,6 +25,8 @@ public class SourceColumnsFactory {
         List<SourceColumn> columnList;
         SourceColumn idColumn;
         switch (source) {
+            case "All":
+                return new LinkedList<>();
             case "Service":
                 columnList = new LinkedList<>();
                 // Service id;
diff --git a/oal-parser/src/main/java/org/apache/skywalking/oap/server/core/Indicators.java b/oal-parser/src/main/java/org/apache/skywalking/oap/server/core/Indicators.java
index 0d96cba..e73f366 100644
--- a/oal-parser/src/main/java/org/apache/skywalking/oap/server/core/Indicators.java
+++ b/oal-parser/src/main/java/org/apache/skywalking/oap/server/core/Indicators.java
@@ -29,6 +29,11 @@ public class Indicators {
         REGISTER.put("doubleAvg", DoubleAvgIndicator.class);
         REGISTER.put("percent", PercentIndicator.class);
         REGISTER.put("sum", SumIndicator.class);
+        REGISTER.put("p99", P99Indicator.class);
+        REGISTER.put("p95", P95Indicator.class);
+        REGISTER.put("p90", P90Indicator.class);
+        REGISTER.put("p75", P75Indicator.class);
+        REGISTER.put("p50", P50Indicator.class);
     }
 
     public static Class<? extends Indicator> find(String functionName) {
diff --git a/oal-parser/src/main/java/org/apache/skywalking/oap/server/core/Indicators.java b/oal-parser/src/main/java/org/apache/skywalking/oap/server/core/analysis/indicator/IntKeyLongValue.java
similarity index 50%
copy from oal-parser/src/main/java/org/apache/skywalking/oap/server/core/Indicators.java
copy to oal-parser/src/main/java/org/apache/skywalking/oap/server/core/analysis/indicator/IntKeyLongValue.java
index 0d96cba..11677f6 100644
--- a/oal-parser/src/main/java/org/apache/skywalking/oap/server/core/Indicators.java
+++ b/oal-parser/src/main/java/org/apache/skywalking/oap/server/core/analysis/indicator/IntKeyLongValue.java
@@ -16,28 +16,42 @@
  *
  */
 
-package org.apache.skywalking.oap.server.core;
+package org.apache.skywalking.oap.server.core.analysis.indicator;
 
-import java.util.*;
-import org.apache.skywalking.oap.server.core.analysis.indicator.*;
+import java.util.Objects;
+import lombok.Getter;
+import lombok.Setter;
 
-public class Indicators {
-    private static Map<String, Class<? extends Indicator>> REGISTER = new HashMap<>();
+/**
+ * IntKeyLongValue is a common bean, with key in Int and value in Long
+ *
+ * @author wusheng
+ */
+@Setter
+@Getter
+public class IntKeyLongValue implements Comparable<IntKeyLongValue>{
+    private int key;
+    private long value;
 
-    static {
-        REGISTER.put("longAvg", LongAvgIndicator.class);
-        REGISTER.put("doubleAvg", DoubleAvgIndicator.class);
-        REGISTER.put("percent", PercentIndicator.class);
-        REGISTER.put("sum", SumIndicator.class);
+    public void addValue(long value) {
+        this.value += value;
     }
 
-    public static Class<? extends Indicator> find(String functionName) {
-        String func = functionName;
-        Class<? extends Indicator> indicatorClass = REGISTER.get(func);
-        if (indicatorClass == null) {
-            throw new IllegalArgumentException("Can't find indicator.");
-        }
-        return indicatorClass;
+    @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);
+    }
 }
diff --git a/oal-parser/src/main/java/org/apache/skywalking/oap/server/core/analysis/indicator/P50Indicator.java b/oal-parser/src/main/java/org/apache/skywalking/oap/server/core/analysis/indicator/P50Indicator.java
new file mode 100644
index 0000000..bb815e0
--- /dev/null
+++ b/oal-parser/src/main/java/org/apache/skywalking/oap/server/core/analysis/indicator/P50Indicator.java
@@ -0,0 +1,30 @@
+/*
+ * 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.indicator;
+
+/**
+ * P50
+ *
+ * @author wusheng
+ */
+public abstract class P50Indicator extends PxxIndicator {
+    public P50Indicator() {
+        super(50);
+    }
+}
diff --git a/oal-parser/src/main/java/org/apache/skywalking/oap/server/core/analysis/indicator/P75Indicator.java b/oal-parser/src/main/java/org/apache/skywalking/oap/server/core/analysis/indicator/P75Indicator.java
new file mode 100644
index 0000000..cfe4e87
--- /dev/null
+++ b/oal-parser/src/main/java/org/apache/skywalking/oap/server/core/analysis/indicator/P75Indicator.java
@@ -0,0 +1,30 @@
+/*
+ * 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.indicator;
+
+/**
+ * P75
+ *
+ * @author wusheng
+ */
+public abstract class P75Indicator extends PxxIndicator {
+    public P75Indicator() {
+        super(75);
+    }
+}
diff --git a/oal-parser/src/main/java/org/apache/skywalking/oap/server/core/analysis/indicator/P90Indicator.java b/oal-parser/src/main/java/org/apache/skywalking/oap/server/core/analysis/indicator/P90Indicator.java
new file mode 100644
index 0000000..52c75c7
--- /dev/null
+++ b/oal-parser/src/main/java/org/apache/skywalking/oap/server/core/analysis/indicator/P90Indicator.java
@@ -0,0 +1,30 @@
+/*
+ * 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.indicator;
+
+/**
+ * P90
+ *
+ * @author wusheng
+ */
+public abstract class P90Indicator extends PxxIndicator {
+    public P90Indicator() {
+        super(90);
+    }
+}
diff --git a/oal-parser/src/main/java/org/apache/skywalking/oap/server/core/analysis/indicator/P95Indicator.java b/oal-parser/src/main/java/org/apache/skywalking/oap/server/core/analysis/indicator/P95Indicator.java
new file mode 100644
index 0000000..9345b20
--- /dev/null
+++ b/oal-parser/src/main/java/org/apache/skywalking/oap/server/core/analysis/indicator/P95Indicator.java
@@ -0,0 +1,30 @@
+/*
+ * 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.indicator;
+
+/**
+ * P95
+ *
+ * @author wusheng
+ */
+public abstract class P95Indicator extends PxxIndicator {
+    public P95Indicator() {
+        super(95);
+    }
+}
diff --git a/oal-parser/src/main/java/org/apache/skywalking/oap/server/core/analysis/indicator/P99Indicator.java b/oal-parser/src/main/java/org/apache/skywalking/oap/server/core/analysis/indicator/P99Indicator.java
new file mode 100644
index 0000000..761e86f
--- /dev/null
+++ b/oal-parser/src/main/java/org/apache/skywalking/oap/server/core/analysis/indicator/P99Indicator.java
@@ -0,0 +1,30 @@
+/*
+ * 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.indicator;
+
+/**
+ * P99
+ *
+ * @author wusheng
+ */
+public abstract class P99Indicator extends PxxIndicator {
+    public P99Indicator() {
+        super(99);
+    }
+}
diff --git a/oal-parser/src/main/java/org/apache/skywalking/oap/server/core/analysis/indicator/PxxIndicator.java b/oal-parser/src/main/java/org/apache/skywalking/oap/server/core/analysis/indicator/PxxIndicator.java
new file mode 100644
index 0000000..b4ac4c8
--- /dev/null
+++ b/oal-parser/src/main/java/org/apache/skywalking/oap/server/core/analysis/indicator/PxxIndicator.java
@@ -0,0 +1,125 @@
+/*
+ * 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.indicator;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import lombok.Getter;
+import lombok.Setter;
+import org.apache.skywalking.oap.server.core.analysis.indicator.annotation.Arg;
+import org.apache.skywalking.oap.server.core.analysis.indicator.annotation.Entrance;
+import org.apache.skywalking.oap.server.core.analysis.indicator.annotation.IndicatorOperator;
+import org.apache.skywalking.oap.server.core.analysis.indicator.annotation.SourceFrom;
+import org.apache.skywalking.oap.server.core.storage.annotation.Column;
+
+/**
+ * PxxIndicator is a parent indicator for p99/p95/p90/p75/p50 indicators. P(xx) indicator is also for P(xx) percentile.
+ *
+ * A percentile (or a centile) is a measure used in statistics indicating the value below which a given percentage of
+ * 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.
+ *
+ * @author wusheng
+ */
+@IndicatorOperator
+public abstract class PxxIndicator extends Indicator {
+    protected static final String DETAIL_GROUP = "detail_group";
+    protected static final String VALUE = "value";
+    protected static final String PRECISION = "precision";
+
+    @Getter @Setter @Column(columnName = VALUE) private int value;
+    @Getter @Setter @Column(columnName = PRECISION) private int precision;
+    @Getter @Setter @Column(columnName = DETAIL_GROUP) private List<IntKeyLongValue> detailGroup;
+
+    private final int percentileRank;
+    private Map<Integer, IntKeyLongValue> detailIndex;
+
+    public PxxIndicator(int percentileRank) {
+        this.percentileRank = percentileRank;
+        detailGroup = new ArrayList<>(30);
+    }
+
+    @Entrance
+    public final void combine(@SourceFrom int value, @Arg int precision) {
+        this.precision = precision;
+
+        this.indexCheckAndInit();
+
+        int index = value / precision;
+        IntKeyLongValue element = detailIndex.get(index);
+        if (element == null) {
+            element = new IntKeyLongValue();
+            element.setKey(index);
+            element.setValue(1);
+            addElement(element);
+        } else {
+            element.addValue(1);
+        }
+    }
+
+    @Override
+    public void combine(Indicator indicator) {
+        PxxIndicator pxxIndicator = (PxxIndicator)indicator;
+        this.indexCheckAndInit();
+        pxxIndicator.indexCheckAndInit();
+
+        pxxIndicator.detailIndex.forEach((key, element) -> {
+            IntKeyLongValue existingElement = this.detailIndex.get(key);
+            if (existingElement == null) {
+                existingElement = new IntKeyLongValue();
+                existingElement.setKey(key);
+                existingElement.setValue(element.getValue());
+                addElement(element);
+            } else {
+                existingElement.addValue(element.getValue());
+            }
+        });
+    }
+
+    @Override
+    public final void calculate() {
+        Collections.sort(detailGroup);
+        int total = detailGroup.stream().mapToInt(element -> (int)element.getValue()).sum();
+        int roof = Math.round(total * percentileRank * 1.0f / 100);
+
+        int count = 0;
+        for (IntKeyLongValue element : detailGroup) {
+            count += element.getValue();
+            if (count >= roof) {
+                value = element.getKey();
+                return;
+            }
+        }
+    }
+
+    private void addElement(IntKeyLongValue element) {
+        detailGroup.add(element);
+        detailIndex.put(element.getKey(), element);
+    }
+
+    private void indexCheckAndInit() {
+        if (detailIndex == null) {
+            detailIndex = new HashMap<>();
+            detailGroup.forEach(element -> detailIndex.put(element.getKey(), element));
+        }
+    }
+}
diff --git a/oal-parser/src/main/java/org/apache/skywalking/oap/server/core/analysis/indicator/annotation/Arg.java b/oal-parser/src/main/java/org/apache/skywalking/oap/server/core/analysis/indicator/annotation/Arg.java
new file mode 100644
index 0000000..fd212f2
--- /dev/null
+++ b/oal-parser/src/main/java/org/apache/skywalking/oap/server/core/analysis/indicator/annotation/Arg.java
@@ -0,0 +1,32 @@
+/*
+ * 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.indicator.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * @author wusheng
+ */
+@Target(ElementType.PARAMETER)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Arg {
+}
diff --git a/oal-parser/src/main/resources/code-templates/AllDispatcherTemplate.ftl b/oal-parser/src/main/resources/code-templates/AllDispatcherTemplate.ftl
new file mode 100644
index 0000000..2893041
--- /dev/null
+++ b/oal-parser/src/main/resources/code-templates/AllDispatcherTemplate.ftl
@@ -0,0 +1,65 @@
+/*
+ * 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.generated.all;
+
+import org.apache.skywalking.oap.server.core.analysis.SourceDispatcher;
+<#if (allIndicators?size>0)>
+import org.apache.skywalking.oap.server.core.analysis.worker.IndicatorProcess;
+    <#list allIndicators as indicator>
+        <#if indicator.filterExpressions??>
+import org.apache.skywalking.oap.server.core.analysis.indicator.expression.*;
+        </#if>
+    </#list>
+</#if>
+import org.apache.skywalking.oap.server.core.source.*;
+
+/**
+ * This class is auto generated. Please don't change this class manually.
+ *
+ * @author Observability Analysis Language code generator
+ */
+public class AllDispatcher implements SourceDispatcher<All> {
+
+    @Override public void dispatch(All source) {
+<#list allIndicators as indicator>
+        do${indicator.metricName}(source);
+</#list>
+    }
+
+<#list allIndicators as indicator>
+    private void do${indicator.metricName}(All source) {
+    ${indicator.metricName}Indicator indicator = new ${indicator.metricName}Indicator();
+
+    <#if indicator.filterExpressions??>
+        <#list indicator.filterExpressions as filterExpression>
+        if (!new ${filterExpression.expressionObject}().setLeft(${filterExpression.left}).setRight(${filterExpression.right}).match()) {
+            return;
+        }
+        </#list>
+    </#if>
+
+        indicator.setTimeBucket(source.getTimeBucket());
+    <#list indicator.fieldsFromSource as field>
+        indicator.${field.fieldSetter}(source.${field.fieldGetter}());
+    </#list>
+        indicator.${indicator.entryMethod.methodName}(<#list indicator.entryMethod.argsExpressions as arg>${arg}<#if arg_has_next>, </#if></#list>);
+        IndicatorProcess.INSTANCE.in(indicator);
+    }
+</#list>
+}
diff --git a/oal-parser/src/main/resources/code-templates/IndicatorImplementor.ftl b/oal-parser/src/main/resources/code-templates/IndicatorImplementor.ftl
index fcc738a..333713e 100644
--- a/oal-parser/src/main/resources/code-templates/IndicatorImplementor.ftl
+++ b/oal-parser/src/main/resources/code-templates/IndicatorImplementor.ftl
@@ -105,6 +105,9 @@ public class ${metricName}Indicator extends ${indicatorClassName} implements Ala
 <#list serializeFields.intFields as field>
         remoteBuilder.setDataIntegers(${field?index}, ${field.getter}());
 </#list>
+<#list serializeFields.intLongValuePairListFields as field>
+        ${field.getter}().forEach(element -> remoteBuilder.addDataIntLongPairList(element.serialize()));
+</#list>
 
         return remoteBuilder;
     }
@@ -125,10 +128,18 @@ public class ${metricName}Indicator extends ${indicatorClassName} implements Ala
 <#list serializeFields.intFields as field>
         ${field.setter}(remoteData.getDataIntegers(${field?index}));
 </#list>
+
+<#list serializeFields.intLongValuePairListFields as field>
+        setDetailGroup(new ArrayList<>(30));
+        remoteData.getDataIntLongPairListList().forEach(element -> {
+            getDetailGroup().add(new IntKeyLongValue(element.getKey(), element.getValue()));
+        });
+</#list>
+
     }
 
     @Override public AlarmMeta getAlarmMeta() {
-        return new AlarmMeta("${varName}", Scope.${sourceName}, <#list fieldsFromSource as field>${field.fieldName}<#if field_has_next>, </#if></#list>);
+        return new AlarmMeta("${varName}", Scope.${sourceName}<#if (fieldsFromSource?size>0) >, <#list fieldsFromSource as field>${field.fieldName}<#if field_has_next>, </#if></#list></#if>);
     }
 
     public static class Builder implements StorageBuilder<${metricName}Indicator> {
diff --git a/oal-parser/src/test/resources/expectedFiles/IndicatorImplementorExpected.java b/oal-parser/src/test/resources/expectedFiles/IndicatorImplementorExpected.java
index 9b8f134..f9fc4a6 100644
--- a/oal-parser/src/test/resources/expectedFiles/IndicatorImplementorExpected.java
+++ b/oal-parser/src/test/resources/expectedFiles/IndicatorImplementorExpected.java
@@ -99,6 +99,8 @@ public class ServiceAvgIndicator extends LongAvgIndicator implements AlarmSuppor
 
         setId(remoteData.getDataIntegers(0));
         setCount(remoteData.getDataIntegers(1));
+
+
     }
 
     @Override public AlarmMeta getAlarmMeta() {
diff --git a/oal-parser/src/test/resources/oal_test.oal b/oal-parser/src/test/resources/oal_test.oal
index 8a8ec03..22e4347 100644
--- a/oal-parser/src/test/resources/oal_test.oal
+++ b/oal-parser/src/test/resources/oal_test.oal
@@ -16,6 +16,8 @@
  *
  */
 
+All_p99 = from(All.latency).p99(10);
+
 Service_Avg = from(Service.latency).longAvg();
 
 ServiceInstance_RespTime= from(ServiceInstance.latency).longAvg();
diff --git a/oal-syntax/src/main/antlr4/org/apache/skywalking/oal/tool/grammar/OALLexer.g4 b/oal-syntax/src/main/antlr4/org/apache/skywalking/oal/tool/grammar/OALLexer.g4
index 8ac4682..be2f5d7 100644
--- a/oal-syntax/src/main/antlr4/org/apache/skywalking/oal/tool/grammar/OALLexer.g4
+++ b/oal-syntax/src/main/antlr4/org/apache/skywalking/oal/tool/grammar/OALLexer.g4
@@ -40,12 +40,12 @@ SRC_SERVICE_INSTANCE_JVM_GC: 'ServiceInstanceJVMGC';
 
 // Literals
 
-DECIMAL_LITERAL:    ('0' | [1-9] (Digits? | '_'+ Digits)) [lL]?;
-
 BOOL_LITERAL:       'true'
             |       'false'
             ;
 
+INT_LITERAL :   Digits+;
+
 CHAR_LITERAL:       '\'' (~['\\\r\n] | EscapeSequence) '\'';
 
 STRING_LITERAL:     '"' (~["\\\r\n] | EscapeSequence)* '"';
diff --git a/oal-syntax/src/main/antlr4/org/apache/skywalking/oal/tool/grammar/OALLexer.tokens b/oal-syntax/src/main/antlr4/org/apache/skywalking/oal/tool/grammar/OALLexer.tokens
index 88f421b..3813bcf 100644
--- a/oal-syntax/src/main/antlr4/org/apache/skywalking/oal/tool/grammar/OALLexer.tokens
+++ b/oal-syntax/src/main/antlr4/org/apache/skywalking/oal/tool/grammar/OALLexer.tokens
@@ -11,8 +11,8 @@ SRC_SERVICE_INSTANCE_JVM_CPU=10
 SRC_SERVICE_INSTANCE_JVM_MEMORY=11
 SRC_SERVICE_INSTANCE_JVM_MEMORY_POOL=12
 SRC_SERVICE_INSTANCE_JVM_GC=13
-DECIMAL_LITERAL=14
-BOOL_LITERAL=15
+BOOL_LITERAL=14
+INT_LITERAL=15
 CHAR_LITERAL=16
 STRING_LITERAL=17
 DelimitedComment=18
diff --git a/oal-syntax/src/main/antlr4/org/apache/skywalking/oal/tool/grammar/OALParser.g4 b/oal-syntax/src/main/antlr4/org/apache/skywalking/oal/tool/grammar/OALParser.g4
index 7dcbea5..b225d3c 100644
--- a/oal-syntax/src/main/antlr4/org/apache/skywalking/oal/tool/grammar/OALParser.g4
+++ b/oal-syntax/src/main/antlr4/org/apache/skywalking/oal/tool/grammar/OALParser.g4
@@ -60,7 +60,7 @@ variable
     ;
 
 aggregateFunction
-    : functionName LR_BRACKET (funcParamExpression)? RR_BRACKET
+    : functionName LR_BRACKET (funcParamExpression | literalExpression)? RR_BRACKET
     ;
 
 functionName
@@ -71,6 +71,10 @@ funcParamExpression
     : expression
     ;
 
+literalExpression
+    : BOOL_LITERAL | INT_LITERAL
+    ;
+
 expression
     : booleanMatch | stringMatch
     ;