You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@skywalking.apache.org by ke...@apache.org on 2020/08/08 10:09:37 UTC

[skywalking] branch oal/filter-expression created (now b15dda4)

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

kezhenxu94 pushed a change to branch oal/filter-expression
in repository https://gitbox.apache.org/repos/asf/skywalking.git.


      at b15dda4  Feature: support !=, regexp filter expressions

This branch includes the following new commits:

     new b15dda4  Feature: support !=, regexp filter expressions

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



[skywalking] 01/01: Feature: support !=, regexp filter expressions

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

kezhenxu94 pushed a commit to branch oal/filter-expression
in repository https://gitbox.apache.org/repos/asf/skywalking.git

commit b15dda4dc86d48f775ef6187d22d3344003fbbc2
Author: kezhenxu94 <ke...@163.com>
AuthorDate: Sat Aug 8 18:09:03 2020 +0800

    Feature: support !=, regexp filter expressions
    
    And slightly refactor the matchers
    
    resolves https://github.com/apache/skywalking/issues/5234
---
 .gitignore                                         |  7 +-
 .../apache/skywalking/oal/rt/grammar/OALLexer.g4   |  4 +-
 .../apache/skywalking/oal/rt/grammar/OALParser.g4  | 16 +++-
 .../org/apache/skywalking/oal/rt/OALRuntime.java   |  7 ++
 .../oal/rt/parser/ConditionExpression.java         |  4 +
 .../skywalking/oal/rt/parser/DeepAnalysis.java     | 92 ++++++----------------
 .../skywalking/oal/rt/parser/FilterMatchers.java   | 69 ++++++++++++++++
 .../skywalking/oal/rt/parser/MetricsHolder.java    |  6 +-
 .../code-templates/dispatcher/doMetrics.ftl        |  4 +-
 .../skywalking/oal/rt/parser/DeepAnalysisTest.java | 55 ++++++++++++-
 .../skywalking/oal/rt/parser/ScriptParserTest.java |  2 +
 .../analysis/metrics/annotation/FilterMatcher.java | 46 +++++++++++
 .../analysis/metrics/expression/BooleanMatch.java} | 21 ++---
 .../metrics/expression/BooleanNotEqualMatch.java}  | 21 ++---
 .../analysis/metrics/expression/EqualMatch.java    | 42 +---------
 .../metrics/expression/GreaterEqualMatch.java      |  3 +
 .../analysis/metrics/expression/GreaterMatch.java  |  3 +
 .../metrics/expression/LessEqualMatch.java         |  3 +
 .../analysis/metrics/expression/LessMatch.java     |  3 +
 .../metrics/expression/NotEqualMatch.java}         | 18 ++---
 .../analysis/metrics/expression/RegexpMatch.java}  | 17 ++--
 21 files changed, 283 insertions(+), 160 deletions(-)

diff --git a/.gitignore b/.gitignore
index cd2d1bd..181769e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -14,11 +14,12 @@ packages/
 /docker/snapshot/*.gz
 .mvn/wrapper/*.jar
 OALLexer.tokens
-.factorypath  
-.vscode 
+.factorypath
+.vscode
 .checkstyle
 .externalToolBuilders
 /test/plugin/dist
 /test/plugin/workspace
 /test/jacoco/classes
-/test/jacoco/*.exec
\ No newline at end of file
+/test/jacoco/*.exec
+oap-server/oal-grammar/**/gen/
diff --git a/oap-server/oal-grammar/src/main/antlr4/org/apache/skywalking/oal/rt/grammar/OALLexer.g4 b/oap-server/oal-grammar/src/main/antlr4/org/apache/skywalking/oal/rt/grammar/OALLexer.g4
index 8ed3398..2a755cd 100644
--- a/oap-server/oal-grammar/src/main/antlr4/org/apache/skywalking/oal/rt/grammar/OALLexer.g4
+++ b/oap-server/oal-grammar/src/main/antlr4/org/apache/skywalking/oal/rt/grammar/OALLexer.g4
@@ -133,4 +133,6 @@ ALL:                                 '*';
 GREATER:                             '>';
 LESS:                                '<';
 GREATER_EQUAL:                       '>=';
-LESS_EQUAL:                          '<=';
\ No newline at end of file
+LESS_EQUAL:                          '<=';
+NOT_EQUAL:                           '!=';
+REGEXP:                              'regexp';
diff --git a/oap-server/oal-grammar/src/main/antlr4/org/apache/skywalking/oal/rt/grammar/OALParser.g4 b/oap-server/oal-grammar/src/main/antlr4/org/apache/skywalking/oal/rt/grammar/OALParser.g4
index 46818ee..8c6c8cb 100644
--- a/oap-server/oal-grammar/src/main/antlr4/org/apache/skywalking/oal/rt/grammar/OALParser.g4
+++ b/oap-server/oal-grammar/src/main/antlr4/org/apache/skywalking/oal/rt/grammar/OALParser.g4
@@ -88,7 +88,7 @@ literalExpression
     ;
 
 expression
-    : booleanMatch | stringMatch | greaterMatch | lessMatch | greaterEqualMatch | lessEqualMatch
+    : booleanMatch | stringMatch | greaterMatch | lessMatch | greaterEqualMatch | lessEqualMatch | notEqualMatch | booleanNotEqualMatch | regexpMatch
     ;
 
 booleanMatch
@@ -115,6 +115,18 @@ lessEqualMatch
     :  conditionAttribute LESS_EQUAL numberConditionValue
     ;
 
+booleanNotEqualMatch
+    :  conditionAttribute NOT_EQUAL booleanConditionValue
+    ;
+
+notEqualMatch
+    :  conditionAttribute NOT_EQUAL (numberConditionValue | stringConditionValue | enumConditionValue)
+    ;
+
+regexpMatch
+    :  conditionAttribute REGEXP stringConditionValue
+    ;
+
 conditionAttribute
     : IDENTIFIER
     ;
@@ -133,4 +145,4 @@ enumConditionValue
 
 numberConditionValue
     : NUMBER_LITERAL
-    ;
\ No newline at end of file
+    ;
diff --git a/oap-server/oal-rt/src/main/java/org/apache/skywalking/oal/rt/OALRuntime.java b/oap-server/oal-rt/src/main/java/org/apache/skywalking/oal/rt/OALRuntime.java
index 6175f81..c55c11a 100644
--- a/oap-server/oal-rt/src/main/java/org/apache/skywalking/oal/rt/OALRuntime.java
+++ b/oap-server/oal-rt/src/main/java/org/apache/skywalking/oal/rt/OALRuntime.java
@@ -53,6 +53,7 @@ import org.apache.skywalking.apm.util.StringUtil;
 import org.apache.skywalking.oal.rt.output.AllDispatcherContext;
 import org.apache.skywalking.oal.rt.output.DispatcherContext;
 import org.apache.skywalking.oal.rt.parser.AnalysisResult;
+import org.apache.skywalking.oal.rt.parser.FilterMatchers;
 import org.apache.skywalking.oal.rt.parser.MetricsHolder;
 import org.apache.skywalking.oal.rt.parser.OALScripts;
 import org.apache.skywalking.oal.rt.parser.ScriptParser;
@@ -151,6 +152,12 @@ public class OALRuntime implements OALEngine {
         }
 
         try {
+            FilterMatchers.INSTANCE.init();
+        } catch (IOException e) {
+            throw new ModuleStartException("failed to load filter matchers.", e);
+        }
+
+        try {
             read = ResourceUtils.read(oalDefine.getConfigFile());
         } catch (FileNotFoundException e) {
             throw new ModuleStartException("Can't locate " + oalDefine.getConfigFile(), e);
diff --git a/oap-server/oal-rt/src/main/java/org/apache/skywalking/oal/rt/parser/ConditionExpression.java b/oap-server/oal-rt/src/main/java/org/apache/skywalking/oal/rt/parser/ConditionExpression.java
index c562a70..60e90dc 100644
--- a/oap-server/oal-rt/src/main/java/org/apache/skywalking/oal/rt/parser/ConditionExpression.java
+++ b/oap-server/oal-rt/src/main/java/org/apache/skywalking/oal/rt/parser/ConditionExpression.java
@@ -18,11 +18,15 @@
 
 package org.apache.skywalking.oal.rt.parser;
 
+import lombok.AllArgsConstructor;
 import lombok.Getter;
+import lombok.NoArgsConstructor;
 import lombok.Setter;
 
 @Getter
 @Setter
+@NoArgsConstructor
+@AllArgsConstructor
 public class ConditionExpression {
     // original from script
     private String expressionType;
diff --git a/oap-server/oal-rt/src/main/java/org/apache/skywalking/oal/rt/parser/DeepAnalysis.java b/oap-server/oal-rt/src/main/java/org/apache/skywalking/oal/rt/parser/DeepAnalysis.java
index 344b7aa..e4ab453 100644
--- a/oap-server/oal-rt/src/main/java/org/apache/skywalking/oal/rt/parser/DeepAnalysis.java
+++ b/oap-server/oal-rt/src/main/java/org/apache/skywalking/oal/rt/parser/DeepAnalysis.java
@@ -24,6 +24,7 @@ import java.lang.reflect.Method;
 import java.lang.reflect.Parameter;
 import java.util.List;
 import org.apache.skywalking.oal.rt.util.ClassMethodUtil;
+import org.apache.skywalking.oap.server.core.analysis.metrics.Metrics;
 import org.apache.skywalking.oap.server.core.analysis.metrics.annotation.Arg;
 import org.apache.skywalking.oap.server.core.analysis.metrics.annotation.ConstOne;
 import org.apache.skywalking.oap.server.core.analysis.metrics.annotation.Entrance;
@@ -35,8 +36,7 @@ public class DeepAnalysis {
         // 1. Set sub package name by source.metrics
         result.setPackageName(result.getSourceName().toLowerCase());
 
-        Class<? extends org.apache.skywalking.oap.server.core.analysis.metrics.Metrics> metricsClass = MetricsHolder.find(result
-            .getAggregationFunctionName());
+        Class<? extends Metrics> metricsClass = MetricsHolder.find(result.getAggregationFunctionName());
         String metricsClassSimpleName = metricsClass.getSimpleName();
 
         result.setMetricsClassName(metricsClassSimpleName);
@@ -45,45 +45,22 @@ public class DeepAnalysis {
         List<ConditionExpression> expressions = result.getFilterExpressionsParserResult();
         if (expressions != null && expressions.size() > 0) {
             for (ConditionExpression expression : expressions) {
-                Expression filterExpression = new Expression();
-                if ("booleanMatch".equals(expression.getExpressionType())) {
-                    filterExpression.setExpressionObject("EqualMatch");
-                    filterExpression.setLeft("source." + ClassMethodUtil.toIsMethod(expression.getAttribute()) + "()");
-                    filterExpression.setRight(expression.getValue());
-                    result.addFilterExpressions(filterExpression);
-                } else if ("stringMatch".equals(expression.getExpressionType())) {
-                    filterExpression.setExpressionObject("EqualMatch");
-                    filterExpression.setLeft("source." + ClassMethodUtil.toGetMethod(expression.getAttribute()) + "()");
-                    filterExpression.setRight(expression.getValue());
-                    result.addFilterExpressions(filterExpression);
-                } else if ("greaterMatch".equals(expression.getExpressionType())) {
-                    filterExpression.setExpressionObject("GreaterMatch");
-                    filterExpression.setLeft("source." + ClassMethodUtil.toGetMethod(expression.getAttribute()) + "()");
-                    filterExpression.setRight(expression.getValue());
-                    result.addFilterExpressions(filterExpression);
-                } else if ("lessMatch".equals(expression.getExpressionType())) {
-                    filterExpression.setExpressionObject("LessMatch");
-                    filterExpression.setLeft("source." + ClassMethodUtil.toGetMethod(expression.getAttribute()) + "()");
-                    filterExpression.setRight(expression.getValue());
-                    result.addFilterExpressions(filterExpression);
-                } else if ("greaterEqualMatch".equals(expression.getExpressionType())) {
-                    filterExpression.setExpressionObject("GreaterEqualMatch");
-                    filterExpression.setLeft("source." + ClassMethodUtil.toGetMethod(expression.getAttribute()) + "()");
-                    filterExpression.setRight(expression.getValue());
-                    result.addFilterExpressions(filterExpression);
-                } else if ("lessEqualMatch".equals(expression.getExpressionType())) {
-                    filterExpression.setExpressionObject("LessEqualMatch");
-                    filterExpression.setLeft("source." + ClassMethodUtil.toGetMethod(expression.getAttribute()) + "()");
-                    filterExpression.setRight(expression.getValue());
-                    result.addFilterExpressions(filterExpression);
-                } else {
-                    throw new IllegalArgumentException("filter expression [" + expression.getExpressionType() + "] not found");
-                }
+                final FilterMatchers.MatcherInfo matcherClass = FilterMatchers.INSTANCE.find(expression.getExpressionType());
+
+                final String getter = matcherClass.getType() == boolean.class || matcherClass.getType() == Boolean.class
+                    ? ClassMethodUtil.toIsMethod(expression.getAttribute())
+                    : ClassMethodUtil.toGetMethod(expression.getAttribute());
+
+                final Expression filterExpression = new Expression();
+                filterExpression.setExpressionObject(matcherClass.getMatcher().getName());
+                filterExpression.setLeft("source." + getter + "()");
+                filterExpression.setRight(expression.getValue());
+                result.addFilterExpressions(filterExpression);
             }
         }
 
         // 3. Find Entrance method of this metrics
-        Class c = metricsClass;
+        Class<?> c = metricsClass;
         Method entranceMethod = null;
         SearchEntrance:
         while (!c.equals(Object.class)) {
@@ -117,36 +94,17 @@ public class DeepAnalysis {
                 entryMethod.addArg(parameterType, "1");
             } else if (annotation instanceof org.apache.skywalking.oap.server.core.analysis.metrics.annotation.Expression) {
                 if (result.getFuncConditionExpressions().size() == 1) {
-                    ConditionExpression expression = result.getFuncConditionExpressions().get(0);
-
-                    Expression argExpression = new Expression();
-                    if ("booleanMatch".equals(expression.getExpressionType())) {
-                        argExpression.setExpressionObject("EqualMatch");
-                        argExpression.setLeft("source." + ClassMethodUtil.toIsMethod(expression.getAttribute()) + "()");
-                        argExpression.setRight(expression.getValue());
-                    } else if ("stringMatch".equals(expression.getExpressionType())) {
-                        argExpression.setExpressionObject("EqualMatch");
-                        argExpression.setLeft("source." + ClassMethodUtil.toGetMethod(expression.getAttribute()) + "()");
-                        argExpression.setRight(expression.getValue());
-                    } else if ("greaterMatch".equals(expression.getExpressionType())) {
-                        argExpression.setExpressionObject("GreaterMatch");
-                        argExpression.setLeft("source." + ClassMethodUtil.toGetMethod(expression.getAttribute()) + "()");
-                        argExpression.setRight(expression.getValue());
-                    } else if ("lessMatch".equals(expression.getExpressionType())) {
-                        argExpression.setExpressionObject("LessMatch");
-                        argExpression.setLeft("source." + ClassMethodUtil.toGetMethod(expression.getAttribute()) + "()");
-                        argExpression.setRight(expression.getValue());
-                    } else if ("greaterEqualMatch".equals(expression.getExpressionType())) {
-                        argExpression.setExpressionObject("GreaterEqualMatch");
-                        argExpression.setLeft("source." + ClassMethodUtil.toGetMethod(expression.getAttribute()) + "()");
-                        argExpression.setRight(expression.getValue());
-                    } else if ("lessEqualMatch".equals(expression.getExpressionType())) {
-                        argExpression.setExpressionObject("LessEqualMatch");
-                        argExpression.setLeft("source." + ClassMethodUtil.toGetMethod(expression.getAttribute()) + "()");
-                        argExpression.setRight(expression.getValue());
-                    } else {
-                        throw new IllegalArgumentException("filter expression [" + expression.getExpressionType() + "] not found");
-                    }
+                    final ConditionExpression expression = result.getFuncConditionExpressions().get(0);
+                    final FilterMatchers.MatcherInfo matcherClass = FilterMatchers.INSTANCE.find(expression.getExpressionType());
+
+                    final String getter = matcherClass.getType() == boolean.class || matcherClass.getType() == Boolean.class
+                        ? ClassMethodUtil.toIsMethod(expression.getAttribute())
+                        : ClassMethodUtil.toGetMethod(expression.getAttribute());
+
+                    final Expression argExpression = new Expression();
+                    argExpression.setRight(expression.getValue());
+                    argExpression.setExpressionObject(matcherClass.getMatcher().getName());
+                    argExpression.setLeft("source." + getter + "()");
 
                     entryMethod.addArg(argExpression);
                 } else {
diff --git a/oap-server/oal-rt/src/main/java/org/apache/skywalking/oal/rt/parser/FilterMatchers.java b/oap-server/oal-rt/src/main/java/org/apache/skywalking/oal/rt/parser/FilterMatchers.java
new file mode 100644
index 0000000..c8b7efe
--- /dev/null
+++ b/oap-server/oal-rt/src/main/java/org/apache/skywalking/oal/rt/parser/FilterMatchers.java
@@ -0,0 +1,69 @@
+/*
+ * 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.oal.rt.parser;
+
+import com.google.common.reflect.ClassPath;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.skywalking.oap.server.core.analysis.metrics.annotation.FilterMatcher;
+
+@SuppressWarnings("UnstableApiUsage")
+public enum FilterMatchers {
+    INSTANCE;
+
+    private final Map<String, MatcherInfo> matchersKeyedByType = new HashMap<>();
+
+    public void init() throws IOException {
+        final ClassPath classpath = ClassPath.from(FilterMatchers.class.getClassLoader());
+        final Set<ClassPath.ClassInfo> classes = classpath.getTopLevelClassesRecursive("org.apache.skywalking");
+        for (ClassPath.ClassInfo classInfo : classes) {
+            final Class<?> clazz = classInfo.load();
+
+            if (clazz.isAnnotationPresent(FilterMatcher.class)) {
+                final FilterMatcher filterMatcher = clazz.getAnnotation(FilterMatcher.class);
+                for (final String type : filterMatcher.value()) {
+                    matchersKeyedByType.put(type, new MatcherInfo(clazz, filterMatcher.type()));
+                }
+                if (filterMatcher.value().length == 0) {
+                    final String defaultTypeName = StringUtils.uncapitalize(clazz.getSimpleName());
+                    matchersKeyedByType.put(defaultTypeName, new MatcherInfo(clazz, filterMatcher.type()));
+                }
+            }
+        }
+    }
+
+    public MatcherInfo find(final String type) {
+        if (!matchersKeyedByType.containsKey(type)) {
+            throw new IllegalArgumentException("filter expression [" + type + "] not found");
+        }
+        return matchersKeyedByType.get(type);
+    }
+
+    @Getter
+    @AllArgsConstructor
+    public static class MatcherInfo {
+        private final Class<?> matcher;
+        private final Class<?> type;
+    }
+}
diff --git a/oap-server/oal-rt/src/main/java/org/apache/skywalking/oal/rt/parser/MetricsHolder.java b/oap-server/oal-rt/src/main/java/org/apache/skywalking/oal/rt/parser/MetricsHolder.java
index 05efde2..d514f65 100644
--- a/oap-server/oal-rt/src/main/java/org/apache/skywalking/oal/rt/parser/MetricsHolder.java
+++ b/oap-server/oal-rt/src/main/java/org/apache/skywalking/oal/rt/parser/MetricsHolder.java
@@ -45,11 +45,9 @@ public class MetricsHolder {
         }
     }
 
-    public static Class<? extends Metrics> find(
-        String functionName) {
+    public static Class<? extends Metrics> find(String functionName) {
         String func = functionName;
-        Class<? extends Metrics> metricsClass = REGISTER.get(
-            func);
+        Class<? extends Metrics> metricsClass = REGISTER.get(func);
         if (metricsClass == null) {
             throw new IllegalArgumentException("Can't find metrics, " + func);
         }
diff --git a/oap-server/oal-rt/src/main/resources/code-templates/dispatcher/doMetrics.ftl b/oap-server/oal-rt/src/main/resources/code-templates/dispatcher/doMetrics.ftl
index 88f6494..45ee4c4 100644
--- a/oap-server/oal-rt/src/main/resources/code-templates/dispatcher/doMetrics.ftl
+++ b/oap-server/oal-rt/src/main/resources/code-templates/dispatcher/doMetrics.ftl
@@ -3,7 +3,7 @@ ${metricsClassPackage}${metricsName}Metrics metrics = new ${metricsClassPackage}
 
 <#if filterExpressions??>
     <#list filterExpressions as filterExpression>
-        if (!new org.apache.skywalking.oap.server.core.analysis.metrics.expression.${filterExpression.expressionObject}().match(${filterExpression.left}, ${filterExpression.right})) {
+        if (!new ${filterExpression.expressionObject}().match(${filterExpression.left}, ${filterExpression.right})) {
         return;
         }
     </#list>
@@ -18,7 +18,7 @@ metrics.${entryMethod.methodName}(
     <#if entryMethod.argTypes[arg_index] < 3>
         ${arg}
     <#else>
-        new org.apache.skywalking.oap.server.core.analysis.metrics.expression.${arg.expressionObject}().match(${arg.left}, ${arg.right})
+        new ${arg.expressionObject}().match(${arg.left}, ${arg.right})
     </#if><#if arg_has_next>, </#if>
 </#list>);
 
diff --git a/oap-server/oal-rt/src/test/java/org/apache/skywalking/oal/rt/parser/DeepAnalysisTest.java b/oap-server/oal-rt/src/test/java/org/apache/skywalking/oal/rt/parser/DeepAnalysisTest.java
index c869125..a5dd950 100644
--- a/oap-server/oal-rt/src/test/java/org/apache/skywalking/oal/rt/parser/DeepAnalysisTest.java
+++ b/oap-server/oal-rt/src/test/java/org/apache/skywalking/oal/rt/parser/DeepAnalysisTest.java
@@ -20,6 +20,10 @@ package org.apache.skywalking.oal.rt.parser;
 
 import java.io.IOException;
 import java.util.List;
+import org.apache.skywalking.oap.server.core.analysis.metrics.expression.BooleanMatch;
+import org.apache.skywalking.oap.server.core.analysis.metrics.expression.BooleanNotEqualMatch;
+import org.apache.skywalking.oap.server.core.analysis.metrics.expression.EqualMatch;
+import org.apache.skywalking.oap.server.core.analysis.metrics.expression.NotEqualMatch;
 import org.apache.skywalking.oap.server.core.annotation.AnnotationScan;
 import org.apache.skywalking.oap.server.core.source.DefaultScopeDefine;
 import org.apache.skywalking.oap.server.core.storage.StorageException;
@@ -28,6 +32,9 @@ import org.junit.Assert;
 import org.junit.BeforeClass;
 import org.junit.Test;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
 public class DeepAnalysisTest {
     @BeforeClass
     public static void init() throws IOException, StorageException {
@@ -36,6 +43,7 @@ public class DeepAnalysisTest {
         scopeScan.scan();
 
         MetricsHolder.init();
+        FilterMatchers.INSTANCE.init();
     }
 
     @AfterClass
@@ -122,8 +130,53 @@ public class DeepAnalysisTest {
         List<Expression> filterExpressions = result.getFilterExpressions();
         Assert.assertEquals(1, filterExpressions.size());
         Expression filterExpression = filterExpressions.get(0);
-        Assert.assertEquals("EqualMatch", filterExpression.getExpressionObject());
+        Assert.assertEquals(EqualMatch.class.getName(), filterExpression.getExpressionObject());
         Assert.assertEquals("source.getName()", filterExpression.getLeft());
         Assert.assertEquals("\"/service/prod/save\"", filterExpression.getRight());
     }
+
+    @Test
+    public void shouldUseCorrectMatcher() {
+
+        AnalysisResult result = new AnalysisResult();
+        result.setSourceName("Endpoint");
+        result.setPackageName("endpoint.endpointavg");
+        result.setSourceAttribute("latency");
+        result.setMetricsName("EndpointAvg");
+        result.setAggregationFunctionName("longAvg");
+
+        DeepAnalysis analysis = new DeepAnalysis();
+
+        result.setFilterExpressions(null);
+        result.setFilterExpressionsParserResult(null);
+        result.addFilterExpressionsParserResult(new ConditionExpression("booleanMatch", "valid", ""));
+        result = analysis.analysis(result);
+        assertTrue(result.getFilterExpressions().size() > 0);
+        assertEquals(BooleanMatch.class.getName(), result.getFilterExpressions().get(0).getExpressionObject());
+        assertEquals("source.isValid()", result.getFilterExpressions().get(0).getLeft());
+
+        result.setFilterExpressions(null);
+        result.setFilterExpressionsParserResult(null);
+        result.addFilterExpressionsParserResult(new ConditionExpression("stringMatch", "type", ""));
+        result = analysis.analysis(result);
+        assertTrue(result.getFilterExpressions().size() > 0);
+        assertEquals(EqualMatch.class.getName(), result.getFilterExpressions().get(0).getExpressionObject());
+        assertEquals("source.getType()", result.getFilterExpressions().get(0).getLeft());
+
+        result.setFilterExpressions(null);
+        result.setFilterExpressionsParserResult(null);
+        result.addFilterExpressionsParserResult(new ConditionExpression("notEqualMatch", "type", ""));
+        result = analysis.analysis(result);
+        assertTrue(result.getFilterExpressions().size() > 0);
+        assertEquals(NotEqualMatch.class.getName(), result.getFilterExpressions().get(0).getExpressionObject());
+        assertEquals("source.getType()", result.getFilterExpressions().get(0).getLeft());
+
+        result.setFilterExpressions(null);
+        result.setFilterExpressionsParserResult(null);
+        result.addFilterExpressionsParserResult(new ConditionExpression("booleanNotEqualMatch", "type", ""));
+        result = analysis.analysis(result);
+        assertTrue(result.getFilterExpressions().size() > 0);
+        assertEquals(BooleanNotEqualMatch.class.getName(), result.getFilterExpressions().get(0).getExpressionObject());
+        assertEquals("source.isType()", result.getFilterExpressions().get(0).getLeft());
+    }
 }
diff --git a/oap-server/oal-rt/src/test/java/org/apache/skywalking/oal/rt/parser/ScriptParserTest.java b/oap-server/oal-rt/src/test/java/org/apache/skywalking/oal/rt/parser/ScriptParserTest.java
index b2eb371..6b3e5f0 100644
--- a/oap-server/oal-rt/src/test/java/org/apache/skywalking/oal/rt/parser/ScriptParserTest.java
+++ b/oap-server/oal-rt/src/test/java/org/apache/skywalking/oal/rt/parser/ScriptParserTest.java
@@ -20,6 +20,7 @@ package org.apache.skywalking.oal.rt.parser;
 
 import java.io.IOException;
 import java.util.List;
+import org.apache.skywalking.oap.server.core.analysis.metrics.annotation.FilterMatcher;
 import org.apache.skywalking.oap.server.core.annotation.AnnotationScan;
 import org.apache.skywalking.oap.server.core.source.DefaultScopeDefine;
 import org.apache.skywalking.oap.server.core.storage.StorageException;
@@ -35,6 +36,7 @@ public class ScriptParserTest {
     @BeforeClass
     public static void init() throws IOException, StorageException {
         MetricsHolder.init();
+        FilterMatchers.INSTANCE.init();
 
         AnnotationScan scopeScan = new AnnotationScan();
         scopeScan.registerListener(new DefaultScopeDefine.Listener());
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/annotation/FilterMatcher.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/annotation/FilterMatcher.java
new file mode 100644
index 0000000..c297300
--- /dev/null
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/annotation/FilterMatcher.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.skywalking.oap.server.core.analysis.metrics.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import org.apache.skywalking.oap.server.core.analysis.metrics.expression.BooleanMatch;
+
+/**
+ * Classes annotated with {@code FilterMatcher} are processors of the expressions in {@code filter} of the OAL script.
+ * Take {@link BooleanMatch} as an example.
+ */
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface FilterMatcher {
+    /**
+     * @return the operator name(s) defined in the .g4 files, such as {@code lessEqualMatch} and {@code notEqualMatch},
+     * the default value is the name of the class annotated with {@link FilterMatcher}, with the first letter being
+     * lowercase.
+     */
+    String[] value() default {};
+
+    /**
+     * @return the type of the filter operand, which decides the getter of the operands, i.e. getter of {@code Boolean}
+     * and {@code boolean} type is {@code isArg}, otherwise {@code getArg}.
+     */
+    Class<?> type() default Object.class;
+}
diff --git a/oap-server/oal-rt/src/main/java/org/apache/skywalking/oal/rt/parser/ConditionExpression.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/expression/BooleanMatch.java
similarity index 66%
copy from oap-server/oal-rt/src/main/java/org/apache/skywalking/oal/rt/parser/ConditionExpression.java
copy to oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/expression/BooleanMatch.java
index c562a70..49ad514 100644
--- a/oap-server/oal-rt/src/main/java/org/apache/skywalking/oal/rt/parser/ConditionExpression.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/expression/BooleanMatch.java
@@ -16,16 +16,17 @@
  *
  */
 
-package org.apache.skywalking.oal.rt.parser;
+package org.apache.skywalking.oap.server.core.analysis.metrics.expression;
 
-import lombok.Getter;
-import lombok.Setter;
+import org.apache.skywalking.oap.server.core.analysis.metrics.annotation.FilterMatcher;
 
-@Getter
-@Setter
-public class ConditionExpression {
-    // original from script
-    private String expressionType;
-    private String attribute;
-    private String value;
+@FilterMatcher(type = boolean.class)
+public class BooleanMatch {
+    public boolean match(Boolean left, Boolean right) {
+        return left == right;
+    }
+
+    public boolean match(boolean left, boolean right) {
+        return left == right;
+    }
 }
diff --git a/oap-server/oal-rt/src/main/java/org/apache/skywalking/oal/rt/parser/ConditionExpression.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/expression/BooleanNotEqualMatch.java
similarity index 65%
copy from oap-server/oal-rt/src/main/java/org/apache/skywalking/oal/rt/parser/ConditionExpression.java
copy to oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/expression/BooleanNotEqualMatch.java
index c562a70..99a8a80 100644
--- a/oap-server/oal-rt/src/main/java/org/apache/skywalking/oal/rt/parser/ConditionExpression.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/expression/BooleanNotEqualMatch.java
@@ -16,16 +16,17 @@
  *
  */
 
-package org.apache.skywalking.oal.rt.parser;
+package org.apache.skywalking.oap.server.core.analysis.metrics.expression;
 
-import lombok.Getter;
-import lombok.Setter;
+import org.apache.skywalking.oap.server.core.analysis.metrics.annotation.FilterMatcher;
 
-@Getter
-@Setter
-public class ConditionExpression {
-    // original from script
-    private String expressionType;
-    private String attribute;
-    private String value;
+@FilterMatcher(type = boolean.class)
+public class BooleanNotEqualMatch {
+    public boolean match(Boolean left, Boolean right) {
+        return left != right;
+    }
+
+    public boolean match(boolean left, boolean right) {
+        return left != right;
+    }
 }
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/expression/EqualMatch.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/expression/EqualMatch.java
index 952d4c5..46ce2ed 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/expression/EqualMatch.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/expression/EqualMatch.java
@@ -19,48 +19,10 @@
 package org.apache.skywalking.oap.server.core.analysis.metrics.expression;
 
 import java.util.Objects;
+import org.apache.skywalking.oap.server.core.analysis.metrics.annotation.FilterMatcher;
 
+@FilterMatcher("stringMatch")
 public class EqualMatch {
-    public boolean match(int left, int right) {
-        return left == right;
-    }
-
-    public boolean match(long left, long right) {
-        return left == right;
-    }
-
-    public boolean match(float left, float right) {
-        return left == right;
-    }
-
-    public boolean match(double left, double right) {
-        return left == right;
-    }
-
-    public boolean match(Integer left, Integer right) {
-        return Objects.equals(left, right);
-    }
-
-    public boolean match(Long left, Long right) {
-        return Objects.equals(left, right);
-    }
-
-    public boolean match(Float left, Float right) {
-        return Objects.equals(left, right);
-    }
-
-    public boolean match(Double left, Double right) {
-        return Objects.equals(left, right);
-    }
-
-    public boolean match(Boolean left, Boolean right) {
-        return left == right;
-    }
-
-    public boolean match(boolean left, boolean right) {
-        return left == right;
-    }
-
     public boolean match(Object left, Object right) {
         return Objects.equals(left, right);
     }
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/expression/GreaterEqualMatch.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/expression/GreaterEqualMatch.java
index 5839591..0512663 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/expression/GreaterEqualMatch.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/expression/GreaterEqualMatch.java
@@ -18,6 +18,9 @@
 
 package org.apache.skywalking.oap.server.core.analysis.metrics.expression;
 
+import org.apache.skywalking.oap.server.core.analysis.metrics.annotation.FilterMatcher;
+
+@FilterMatcher
 public class GreaterEqualMatch {
     public boolean match(int left, int right) {
         return left >= right;
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/expression/GreaterMatch.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/expression/GreaterMatch.java
index 1b8b479..6d077dc 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/expression/GreaterMatch.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/expression/GreaterMatch.java
@@ -18,6 +18,9 @@
 
 package org.apache.skywalking.oap.server.core.analysis.metrics.expression;
 
+import org.apache.skywalking.oap.server.core.analysis.metrics.annotation.FilterMatcher;
+
+@FilterMatcher
 public class GreaterMatch {
     public boolean match(int left, int right) {
         return left > right;
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/expression/LessEqualMatch.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/expression/LessEqualMatch.java
index 95276c8..35782e9 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/expression/LessEqualMatch.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/expression/LessEqualMatch.java
@@ -18,6 +18,9 @@
 
 package org.apache.skywalking.oap.server.core.analysis.metrics.expression;
 
+import org.apache.skywalking.oap.server.core.analysis.metrics.annotation.FilterMatcher;
+
+@FilterMatcher
 public class LessEqualMatch {
     public boolean match(int left, int right) {
         return left <= right;
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/expression/LessMatch.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/expression/LessMatch.java
index bfee306..62a0edb 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/expression/LessMatch.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/expression/LessMatch.java
@@ -18,6 +18,9 @@
 
 package org.apache.skywalking.oap.server.core.analysis.metrics.expression;
 
+import org.apache.skywalking.oap.server.core.analysis.metrics.annotation.FilterMatcher;
+
+@FilterMatcher
 public class LessMatch {
     public boolean match(int left, int right) {
         return left < right;
diff --git a/oap-server/oal-rt/src/main/java/org/apache/skywalking/oal/rt/parser/ConditionExpression.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/expression/NotEqualMatch.java
similarity index 70%
copy from oap-server/oal-rt/src/main/java/org/apache/skywalking/oal/rt/parser/ConditionExpression.java
copy to oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/expression/NotEqualMatch.java
index c562a70..6475bc5 100644
--- a/oap-server/oal-rt/src/main/java/org/apache/skywalking/oal/rt/parser/ConditionExpression.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/expression/NotEqualMatch.java
@@ -16,16 +16,14 @@
  *
  */
 
-package org.apache.skywalking.oal.rt.parser;
+package org.apache.skywalking.oap.server.core.analysis.metrics.expression;
 
-import lombok.Getter;
-import lombok.Setter;
+import java.util.Objects;
+import org.apache.skywalking.oap.server.core.analysis.metrics.annotation.FilterMatcher;
 
-@Getter
-@Setter
-public class ConditionExpression {
-    // original from script
-    private String expressionType;
-    private String attribute;
-    private String value;
+@FilterMatcher
+public class NotEqualMatch {
+    public boolean match(Object left, Object right) {
+        return !Objects.equals(left, right);
+    }
 }
diff --git a/oap-server/oal-rt/src/main/java/org/apache/skywalking/oal/rt/parser/ConditionExpression.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/expression/RegexpMatch.java
similarity index 70%
copy from oap-server/oal-rt/src/main/java/org/apache/skywalking/oal/rt/parser/ConditionExpression.java
copy to oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/expression/RegexpMatch.java
index c562a70..dfd6a09 100644
--- a/oap-server/oal-rt/src/main/java/org/apache/skywalking/oal/rt/parser/ConditionExpression.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/metrics/expression/RegexpMatch.java
@@ -16,16 +16,13 @@
  *
  */
 
-package org.apache.skywalking.oal.rt.parser;
+package org.apache.skywalking.oap.server.core.analysis.metrics.expression;
 
-import lombok.Getter;
-import lombok.Setter;
+import org.apache.skywalking.oap.server.core.analysis.metrics.annotation.FilterMatcher;
 
-@Getter
-@Setter
-public class ConditionExpression {
-    // original from script
-    private String expressionType;
-    private String attribute;
-    private String value;
+@FilterMatcher
+public class RegexpMatch {
+    public boolean match(String left, String right) {
+        return left != null && right != null && left.matches(right);
+    }
 }