You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by wu...@apache.org on 2018/06/05 07:29:42 UTC

[incubator-servicecomb-java-chassis] branch master updated (cb2be07 -> b6ec548)

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

wujimin pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-servicecomb-java-chassis.git.


    from cb2be07  Client Request Timeout support for operation/schema/service level:Review fix
     new 7b768e2  [SCB-616] remove old access log parse logic
     new 7895939  [SCB-616] define new AccessLogPatternParser
     new 62647a9  [SCB-616] add AccessLogItemMeta compare logic
     new 34cf795  [SCB-616] finish parse logic refactor
     new 2b15544  [SCB-616] make VertxRestAccessLogItemCreator extensible
     new b6ec548  [SCB-616] refactor access log extension

The 6 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.


Summary of changes:
 .../transport/rest/vertx/RestServerVerticle.java   |   7 +-
 .../rest/vertx/accesslog/AccessLogGenerator.java   |  15 +-
 .../accesslog/element/AccessLogItemFactory.java    |  67 ----
 .../PercentagePrefixConfigurableItemCreator.java   |  68 ----
 .../creator/SimpleAccessLogItemCreator.java        |  76 -----
 .../accesslog/element/impl/ResponseSizeItem.java   |   4 +
 .../vertx/accesslog/impl/AccessLogHandler.java     |   5 +-
 .../creator => parser}/AccessLogItemCreator.java   |  14 +-
 .../accesslog/parser/AccessLogItemLocation.java    |  86 -----
 .../vertx/accesslog/parser/AccessLogItemMeta.java  |  74 +++++
 .../accesslog/parser/AccessLogPatternParser.java   |  12 +-
 ...va => CompositeVertxRestAccessLogItemMeta.java} |  19 +-
 ...Parser.java => VertxRestAccessLogItemMeta.java} |  26 +-
 .../parser/impl/DefaultAccessLogPatternParser.java | 125 --------
 ...DefaultCompositeVertxRestAccessLogItemMeta.java |  87 +++++
 .../impl/VertxRestAccessLogPatternParser.java      | 350 +++++++++++++++++++++
 .../PercentagePrefixConfigurableMatcher.java       |  84 -----
 .../parser/matcher/SimpleItemMatcher.java          |  78 -----
 ...rtx.accesslog.parser.VertxRestAccessLogItemMeta |   4 +-
 .../vertx/accesslog/AccessLogGeneratorTest.java    |  14 +-
 .../element/AccessLogItemFactoryTest.java          |  56 ----
 ...ercentagePrefixConfigurableItemCreatorTest.java | 106 -------
 .../element/impl/UserDefinedAccessLogItem.java}    |  12 +-
 .../impl/UserDefinedAccessLogItemLowPriority.java} |  12 +-
 .../vertx/accesslog/impl/AccessLogHandlerTest.java | 104 ++++++
 .../impl/DefaultAccessLogPatternParserTest.java    | 119 -------
 .../TestCompositeExtendedAccessLogItemMeta.java}   |  26 +-
 .../impl/TestSingleExtendedAccessLogItemMeta.java} |  15 +-
 .../impl/VertxRestAccessLogPatternParserTest.java  | 322 +++++++++++++++++++
 .../PercentagePrefixConfigurableMatcherTest.java   |  73 -----
 .../parser/matcher/SimpleItemMatcherTest.java      |  58 ----
 ...rtx.accesslog.parser.VertxRestAccessLogItemMeta |   5 +-
 32 files changed, 1042 insertions(+), 1081 deletions(-)
 delete mode 100644 transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/AccessLogItemFactory.java
 delete mode 100644 transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/creator/PercentagePrefixConfigurableItemCreator.java
 delete mode 100644 transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/creator/SimpleAccessLogItemCreator.java
 copy transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/{element/creator => parser}/AccessLogItemCreator.java (59%)
 delete mode 100644 transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/AccessLogItemLocation.java
 create mode 100644 transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/AccessLogItemMeta.java
 rename transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/{matcher/AccessLogItemMatcher.java => CompositeVertxRestAccessLogItemMeta.java} (60%)
 copy transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/{AccessLogPatternParser.java => VertxRestAccessLogItemMeta.java} (51%)
 delete mode 100644 transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/DefaultAccessLogPatternParser.java
 create mode 100644 transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/DefaultCompositeVertxRestAccessLogItemMeta.java
 create mode 100644 transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/VertxRestAccessLogPatternParser.java
 delete mode 100644 transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/matcher/PercentagePrefixConfigurableMatcher.java
 delete mode 100644 transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/matcher/SimpleItemMatcher.java
 copy common/common-rest/src/test/resources/config/test.properties => transports/transport-rest/transport-rest-vertx/src/main/resources/META-INF/services/org.apache.servicecomb.transport.rest.vertx.accesslog.parser.VertxRestAccessLogItemMeta (87%)
 delete mode 100644 transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/AccessLogItemFactoryTest.java
 delete mode 100644 transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/creator/PercentagePrefixConfigurableItemCreatorTest.java
 copy transports/transport-rest/transport-rest-vertx/src/{main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/impl/PlainTextItem.java => test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/impl/UserDefinedAccessLogItem.java} (82%)
 copy transports/transport-rest/transport-rest-vertx/src/{main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/impl/PlainTextItem.java => test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/impl/UserDefinedAccessLogItemLowPriority.java} (83%)
 create mode 100644 transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/impl/AccessLogHandlerTest.java
 delete mode 100644 transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/DefaultAccessLogPatternParserTest.java
 copy transports/transport-rest/transport-rest-vertx/src/{main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/creator/AccessLogItemCreator.java => test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/TestCompositeExtendedAccessLogItemMeta.java} (56%)
 rename transports/transport-rest/transport-rest-vertx/src/{main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/creator/AccessLogItemCreator.java => test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/TestSingleExtendedAccessLogItemMeta.java} (71%)
 create mode 100644 transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/VertxRestAccessLogPatternParserTest.java
 delete mode 100644 transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/matcher/PercentagePrefixConfigurableMatcherTest.java
 delete mode 100644 transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/matcher/SimpleItemMatcherTest.java
 copy common/common-rest/src/test/resources/config/test.properties => transports/transport-rest/transport-rest-vertx/src/test/resources/META-INF/services/org.apache.servicecomb.transport.rest.vertx.accesslog.parser.VertxRestAccessLogItemMeta (79%)

-- 
To stop receiving notification emails like this one, please contact
wujimin@apache.org.

[incubator-servicecomb-java-chassis] 03/06: [SCB-616] add AccessLogItemMeta compare logic

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

wujimin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-servicecomb-java-chassis.git

commit 62647a9b77113ae6e0569cc1b69127a1acd6851e
Author: yaohaishi <ya...@huawei.com>
AuthorDate: Sun May 27 15:11:13 2018 +0800

    [SCB-616] add AccessLogItemMeta compare logic
---
 .../impl/VertxRestAccessLogPatternParser.java      |  86 +++++++++++++++-
 .../impl/VertxRestAccessLogPatternParserTest.java  | 110 ++++++++++++++++++++-
 2 files changed, 192 insertions(+), 4 deletions(-)

diff --git a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/VertxRestAccessLogPatternParser.java b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/VertxRestAccessLogPatternParser.java
index 666d9a9..5295f10 100644
--- a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/VertxRestAccessLogPatternParser.java
+++ b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/VertxRestAccessLogPatternParser.java
@@ -18,6 +18,7 @@
 package org.apache.servicecomb.transport.rest.vertx.accesslog.parser.impl;
 
 import java.util.ArrayList;
+import java.util.Comparator;
 import java.util.List;
 
 import org.apache.servicecomb.transport.rest.vertx.accesslog.element.AccessLogItem;
@@ -31,11 +32,30 @@ import io.vertx.ext.web.RoutingContext;
  * The parser is used for rest-over-vertx transport.
  */
 public class VertxRestAccessLogPatternParser implements AccessLogPatternParser<RoutingContext> {
+  public static final Comparator<AccessLogItemMetaWrapper> accessLogItemMetaWrapperComparator = (w1, w2) -> {
+    AccessLogItemMeta meta1 = w1.getAccessLogItemMeta();
+    AccessLogItemMeta meta2 = w2.getAccessLogItemMeta();
+    int result = meta1.getOrder() - meta2.getOrder();
+    if (result != 0) {
+      return result;
+    }
+
+    // one of meta1 & meta2 has suffix, but the other one doesn't have
+    if (meta1.getSuffix() == null ^ meta2.getSuffix() == null) {
+      return meta1.getSuffix() == null ? 1 : -1;
+    }
+
+    if (null != meta1.getSuffix()) {
+      result = comparePlaceholderString(meta1.getSuffix(), meta2.getSuffix());
+    }
+
+    return 0 == result ?
+        comparePlaceholderString(meta1.getPrefix(), meta2.getPrefix())
+        : result;
+  };
+
   private List<VertxRestAccessLogItemCreator> creators = new ArrayList<>();
 
-  /**
-   * All of the {@linkplain AccessLogItemMeta} will be wrapped into {@linkplain AccessLogItemMetaWrapper}.
-   */
   private List<AccessLogItemMetaWrapper> accessLogItemMetaWrappers = new ArrayList<>();
 
   public VertxRestAccessLogPatternParser() {
@@ -44,6 +64,28 @@ public class VertxRestAccessLogPatternParser implements AccessLogPatternParser<R
         accessLogItemMetaWrappers.add(new AccessLogItemMetaWrapper(accessLogItemMeta, creator));
       }
     }
+    sortAccessLogItemMetaWrapper(accessLogItemMetaWrappers);
+  }
+
+  /**
+   * Behavior of this compare:
+   * 1. comparePlaceholderString("abc","bbc") < 0
+   * 2. comparePlaceholderString("abc","ab") < 0
+   * 3. comparePlaceholderString("abc","abc) = 0
+   */
+  public static int comparePlaceholderString(String s1, String s2) {
+    int result = s1.compareTo(s2);
+    if (0 == result) {
+      return result;
+    }
+
+    // there are two possible cases:
+    // 1. s1="ab", s2="def"
+    // 2. s1="ab", s2="abc"
+    // in the case1 just return the result, but int the case2 the result should be reversed
+    return result < 0 ?
+        (s2.startsWith(s1) ? -result : result)
+        : (s1.startsWith(s2) ? -result : result);
   }
 
   /**
@@ -57,6 +99,44 @@ public class VertxRestAccessLogPatternParser implements AccessLogPatternParser<R
     return itemList;
   }
 
+  /**
+   * Sort all of the {@link AccessLogItemMetaWrapper}, the wrapper that is in front of the others has higher priority.
+   * <p/>
+   * Sort rule(priority decreased):
+   * <ol>
+   *   <li>compare the {@link AccessLogItemMeta#order}</li>
+   *   <li>compare the {@link AccessLogItemMeta#suffix} in lexicographic order, if one's suffix is start with
+   *   the other one's suffix, this one(who's suffix is longer) has higher priority</li>
+   *   <li>compare the {@link AccessLogItemMeta#prefix}, compare rule is the same as suffix.</li>
+   * </ol>
+   * <p/>
+   * e.g. given a list of {@link AccessLogItemMeta} like below:
+   * <ol>
+   * <li>(%ac{,}bcd)</li>
+   * <li>(%ac{,}bc)</li>
+   * <li>(%ac{,}a)</li>
+   * <li>(%ac,)</li>
+   * <li>(%b,)</li>
+   * <li>(%a)</li>
+   * <li>(%{,}b)</li>
+   * <li>(%{,}bc)</li>
+   * </ol>
+   * the result is:
+   * <ol>
+   * <li>(%ac{,}a)</li>
+   * <li>(%ac{,}bcd)</li>
+   * <li>(%ac{,}bc)</li>
+   * <li>(%{,}bc)</li>
+   * <li>(%{,}b)</li>
+   * <li>(%ac,)</li>
+   * <li>(%a)</li>
+   * <li>(%b,)</li>
+   * </ol>
+   */
+  private void sortAccessLogItemMetaWrapper(List<AccessLogItemMetaWrapper> accessLogItemMetaWrapperList) {
+    accessLogItemMetaWrapperList.sort(accessLogItemMetaWrapperComparator);
+  }
+
   public static class AccessLogItemMetaWrapper {
     private AccessLogItemMeta accessLogItemMeta;
 
diff --git a/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/VertxRestAccessLogPatternParserTest.java b/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/VertxRestAccessLogPatternParserTest.java
index c27503e..2fdcc2d 100644
--- a/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/VertxRestAccessLogPatternParserTest.java
+++ b/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/VertxRestAccessLogPatternParserTest.java
@@ -17,5 +17,113 @@
 
 package org.apache.servicecomb.transport.rest.vertx.accesslog.parser.impl;
 
+import java.util.Comparator;
+import java.util.function.Function;
+
+import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.AccessLogItemMeta;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.impl.VertxRestAccessLogPatternParser.AccessLogItemMetaWrapper;
+import org.junit.Assert;
+import org.junit.Test;
+
 public class VertxRestAccessLogPatternParserTest {
-}
\ No newline at end of file
+
+  Comparator<AccessLogItemMetaWrapper> comparator = VertxRestAccessLogPatternParser.accessLogItemMetaWrapperComparator;
+
+  Function<AccessLogItemMeta, AccessLogItemMetaWrapper> wrapper =
+      accessLogItemMeta -> new AccessLogItemMetaWrapper(accessLogItemMeta, null);
+
+  /**
+   * one factor test
+   */
+  @Test
+  public void testCompareMetaSimple() {
+    Assert.assertTrue(
+        comparator.compare(
+            wrapper.apply(new AccessLogItemMeta(null, null, 0)),
+            wrapper.apply(new AccessLogItemMeta(null, null, 1))
+        ) < 0
+    );
+    Assert.assertTrue(
+        comparator.compare(
+            wrapper.apply(new AccessLogItemMeta(null, "}abc")),
+            wrapper.apply(new AccessLogItemMeta(null, null))
+        ) < 0
+    );
+    Assert.assertTrue(
+        comparator.compare(
+            wrapper.apply(new AccessLogItemMeta(null, "}abc")),
+            wrapper.apply(new AccessLogItemMeta(null, "}de"))
+        ) < 0
+    );
+    Assert.assertTrue(
+        comparator.compare(
+            wrapper.apply(new AccessLogItemMeta(null, "}abc")),
+            wrapper.apply(new AccessLogItemMeta(null, "}ab"))
+        ) < 0
+    );
+    Assert.assertTrue(
+        comparator.compare(
+            wrapper.apply(new AccessLogItemMeta("%abc", null)),
+            wrapper.apply(new AccessLogItemMeta("%de", null))
+        ) < 0
+    );
+    Assert.assertTrue(
+        comparator.compare(
+            wrapper.apply(new AccessLogItemMeta("%abc", null)),
+            wrapper.apply(new AccessLogItemMeta("%ab", null))
+        ) < 0
+    );
+    Assert.assertEquals(0, comparator.compare(
+        wrapper.apply(new AccessLogItemMeta("%abc", null)),
+        wrapper.apply(new AccessLogItemMeta("%abc", null))
+    ));
+  }
+
+  /**
+   * multiple factors test
+   */
+  @Test
+  public void testCompareMetaComplex() {
+    Assert.assertTrue(
+        comparator.compare(
+            wrapper.apply(new AccessLogItemMeta("%bcd", "}ab", 0)),
+            wrapper.apply(new AccessLogItemMeta("%abc", "}abc", 0))
+        ) > 0
+    );
+    Assert.assertTrue(
+        comparator.compare(
+            wrapper.apply(new AccessLogItemMeta("%abc", null, 0)),
+            wrapper.apply(new AccessLogItemMeta("%bcd", "}ab", 0))
+        ) > 0
+    );
+    Assert.assertTrue(
+        comparator.compare(
+            wrapper.apply(new AccessLogItemMeta("%bcd", "}abc")),
+            wrapper.apply(new AccessLogItemMeta("%abc", "}abc"))
+        ) > 0
+    );
+    Assert.assertTrue(
+        comparator.compare(
+            wrapper.apply(new AccessLogItemMeta("%abc", "}abc", 1)),
+            wrapper.apply(new AccessLogItemMeta("%ab", "}ab", 0))
+        ) > 0
+    );
+  }
+
+  @Test
+  public void testComparePlaceholderString() {
+    Assert.assertTrue(
+        VertxRestAccessLogPatternParser.comparePlaceholderString("abc", "bbc") < 0
+    );
+    Assert.assertTrue(
+        VertxRestAccessLogPatternParser.comparePlaceholderString("abc", "ab") < 0
+    );
+    Assert.assertEquals(0, VertxRestAccessLogPatternParser.comparePlaceholderString("abc", "abc"));
+    Assert.assertTrue(
+        VertxRestAccessLogPatternParser.comparePlaceholderString("bbc", "abc") > 0
+    );
+    Assert.assertTrue(
+        VertxRestAccessLogPatternParser.comparePlaceholderString("ab", "abc") > 0
+    );
+  }
+}

-- 
To stop receiving notification emails like this one, please contact
wujimin@apache.org.

[incubator-servicecomb-java-chassis] 06/06: [SCB-616] refactor access log extension

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

wujimin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-servicecomb-java-chassis.git

commit b6ec5487c573f90986faa8f314e2bdb9379fb8cc
Author: yaohaishi <ya...@huawei.com>
AuthorDate: Mon Jun 4 11:13:20 2018 +0800

    [SCB-616] refactor access log extension
---
 ...gItemCreator.java => AccessLogItemCreator.java} |  19 +--
 .../vertx/accesslog/parser/AccessLogItemMeta.java  |  43 ++++--
 ...va => CompositeVertxRestAccessLogItemMeta.java} |  42 ++----
 ...emMeta.java => VertxRestAccessLogItemMeta.java} |  38 ++----
 .../parser/impl/DefaultAccessLogItemCreator.java   | 137 -------------------
 ...DefaultCompositeVertxRestAccessLogItemMeta.java |  87 ++++++++++++
 .../impl/VertxRestAccessLogPatternParser.java      | 126 +++++++----------
 ...tx.accesslog.parser.VertxRestAccessLogItemMeta} |   2 +-
 .../element/impl/UserDefinedAccessLogItem.java}    |  42 ++----
 .../impl/UserDefinedAccessLogItemLowPriority.java} |  42 ++----
 .../vertx/accesslog/impl/AccessLogHandlerTest.java | 104 ++++++++++++++
 .../TestCompositeExtendedAccessLogItemMeta.java}   |  45 ++----
 .../impl/TestSingleExtendedAccessLogItemMeta.java} |  42 +-----
 .../impl/VertxRestAccessLogPatternParserTest.java  | 151 +++++++++------------
 ...tx.accesslog.parser.VertxRestAccessLogItemMeta} |   3 +-
 15 files changed, 405 insertions(+), 518 deletions(-)

diff --git a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/VertxRestAccessLogItemCreator.java b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/AccessLogItemCreator.java
similarity index 66%
rename from transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/VertxRestAccessLogItemCreator.java
rename to transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/AccessLogItemCreator.java
index f1917eb..ebd522b 100644
--- a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/VertxRestAccessLogItemCreator.java
+++ b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/AccessLogItemCreator.java
@@ -17,29 +17,18 @@
 
 package org.apache.servicecomb.transport.rest.vertx.accesslog.parser;
 
-import java.util.List;
-
 import org.apache.servicecomb.transport.rest.vertx.accesslog.element.AccessLogItem;
 
-import io.vertx.ext.web.RoutingContext;
-
 /**
- * The {@linkplain VertxRestAccessLogItemCreator}s are able to instantiate a group of {@linkplain AccessLogItem}.
+ * The {@linkplain AccessLogItemCreator}s are able to instantiate a group of {@linkplain AccessLogItem}.
  */
-public interface VertxRestAccessLogItemCreator {
-  /**
-   * @return A list of {@linkplain AccessLogItemMeta} to show that what kinds of {@linkplain AccessLogItem}
-   * this creator is able to instantiate.
-   */
-  List<AccessLogItemMeta> getAccessLogItemMeta();
-
+public interface AccessLogItemCreator<T> {
   /**
-   * Create an instance of {@linkplain AccessLogItem} which is specified by {@linkplain AccessLogItemMeta} and config.
-   * @param accessLogItemMeta determine which kind of {@linkplain AccessLogItem} is created.
+   * Create an instance of {@linkplain AccessLogItem} which is specified by the config.
    * @param config
    * e.g. For {@linkplain org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.CookieItem CookieItem},
    * the pattern may be "%{varName}C", and it's config is "varName". Some {@linkplain AccessLogItem} with no configurable
    * pattern (like "%m") will receive {@code null} as config.
    */
-  AccessLogItem<RoutingContext> createItem(AccessLogItemMeta accessLogItemMeta, String config);
+  AccessLogItem<T> createItem(String config);
 }
diff --git a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/AccessLogItemMeta.java b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/AccessLogItemMeta.java
index 131743e..b47e5d1 100644
--- a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/AccessLogItemMeta.java
+++ b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/AccessLogItemMeta.java
@@ -22,36 +22,53 @@ import org.apache.servicecomb.transport.rest.vertx.accesslog.element.AccessLogIt
 /**
  * The meta data of {@linkplain AccessLogItem}.
  */
-public class AccessLogItemMeta {
-  private String prefix;
+public class AccessLogItemMeta<T> {
+  protected String prefix;
 
-  private String suffix;
+  protected String suffix;
 
   /**
    * Used for sorting {@linkplain AccessLogItemMeta}. Default value is 0.
    * Smaller one has higher priority.
    */
-  private int order;
+  protected int order;
 
-  public AccessLogItemMeta(String prefix, String suffix, int order) {
-    this.prefix = prefix;
-    this.suffix = suffix;
-    this.order = order;
-  }
-
-  public AccessLogItemMeta(String prefix, String suffix) {
-    this(prefix, suffix, 0);
-  }
+  protected AccessLogItemCreator<T> accessLogItemCreator;
 
   public String getPrefix() {
     return prefix;
   }
 
+  public AccessLogItemMeta<T> setPrefix(String prefix) {
+    this.prefix = prefix;
+    return this;
+  }
+
   public String getSuffix() {
     return suffix;
   }
 
+  public AccessLogItemMeta<T> setSuffix(String suffix) {
+    this.suffix = suffix;
+    return this;
+  }
+
   public int getOrder() {
     return order;
   }
+
+  public AccessLogItemMeta<T> setOrder(int order) {
+    this.order = order;
+    return this;
+  }
+
+  public AccessLogItemCreator<T> getAccessLogItemCreator() {
+    return accessLogItemCreator;
+  }
+
+  public AccessLogItemMeta<T> setAccessLogItemCreator(
+      AccessLogItemCreator<T> accessLogItemCreator) {
+    this.accessLogItemCreator = accessLogItemCreator;
+    return this;
+  }
 }
diff --git a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/AccessLogItemMeta.java b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/CompositeVertxRestAccessLogItemMeta.java
similarity index 53%
copy from transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/AccessLogItemMeta.java
copy to transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/CompositeVertxRestAccessLogItemMeta.java
index 131743e..2ad687f 100644
--- a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/AccessLogItemMeta.java
+++ b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/CompositeVertxRestAccessLogItemMeta.java
@@ -17,41 +17,15 @@
 
 package org.apache.servicecomb.transport.rest.vertx.accesslog.parser;
 
-import org.apache.servicecomb.transport.rest.vertx.accesslog.element.AccessLogItem;
+import java.util.List;
 
 /**
- * The meta data of {@linkplain AccessLogItem}.
+ * Hold a group of {@link VertxRestAccessLogItemMeta} so that user can define
+ * only one VertxRestAccessLogItemMeta in spi loading file and load a group of meta.
+ * <p/>
+ * Once the access log loading mechanism finds that a meta is CompositeVertxRestAccessLogItemMeta,
+ * the meta hold by it will be used in access log while this meta itself will be ignored.
  */
-public class AccessLogItemMeta {
-  private String prefix;
-
-  private String suffix;
-
-  /**
-   * Used for sorting {@linkplain AccessLogItemMeta}. Default value is 0.
-   * Smaller one has higher priority.
-   */
-  private int order;
-
-  public AccessLogItemMeta(String prefix, String suffix, int order) {
-    this.prefix = prefix;
-    this.suffix = suffix;
-    this.order = order;
-  }
-
-  public AccessLogItemMeta(String prefix, String suffix) {
-    this(prefix, suffix, 0);
-  }
-
-  public String getPrefix() {
-    return prefix;
-  }
-
-  public String getSuffix() {
-    return suffix;
-  }
-
-  public int getOrder() {
-    return order;
-  }
+public abstract class CompositeVertxRestAccessLogItemMeta extends VertxRestAccessLogItemMeta {
+  public abstract List<VertxRestAccessLogItemMeta> getAccessLogItemMetas();
 }
diff --git a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/AccessLogItemMeta.java b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/VertxRestAccessLogItemMeta.java
similarity index 56%
copy from transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/AccessLogItemMeta.java
copy to transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/VertxRestAccessLogItemMeta.java
index 131743e..7f7916f 100644
--- a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/AccessLogItemMeta.java
+++ b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/VertxRestAccessLogItemMeta.java
@@ -17,41 +17,29 @@
 
 package org.apache.servicecomb.transport.rest.vertx.accesslog.parser;
 
-import org.apache.servicecomb.transport.rest.vertx.accesslog.element.AccessLogItem;
+import io.vertx.ext.web.RoutingContext;
 
 /**
- * The meta data of {@linkplain AccessLogItem}.
+ * For vertx-rest transport way.
  */
-public class AccessLogItemMeta {
-  private String prefix;
-
-  private String suffix;
-
-  /**
-   * Used for sorting {@linkplain AccessLogItemMeta}. Default value is 0.
-   * Smaller one has higher priority.
-   */
-  private int order;
+public class VertxRestAccessLogItemMeta extends AccessLogItemMeta<RoutingContext> {
+  public VertxRestAccessLogItemMeta() {
+  }
 
-  public AccessLogItemMeta(String prefix, String suffix, int order) {
+  public VertxRestAccessLogItemMeta(String prefix, String suffix,
+      AccessLogItemCreator<RoutingContext> accessLogItemCreator, int order) {
     this.prefix = prefix;
     this.suffix = suffix;
+    this.accessLogItemCreator = accessLogItemCreator;
     this.order = order;
   }
 
-  public AccessLogItemMeta(String prefix, String suffix) {
-    this(prefix, suffix, 0);
-  }
-
-  public String getPrefix() {
-    return prefix;
-  }
-
-  public String getSuffix() {
-    return suffix;
+  public VertxRestAccessLogItemMeta(String prefix, AccessLogItemCreator<RoutingContext> accessLogItemCreator) {
+    this(prefix, null, accessLogItemCreator, 0);
   }
 
-  public int getOrder() {
-    return order;
+  public VertxRestAccessLogItemMeta(String prefix, String suffix,
+      AccessLogItemCreator<RoutingContext> accessLogItemCreator) {
+    this(prefix, suffix, accessLogItemCreator, 0);
   }
 }
diff --git a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/DefaultAccessLogItemCreator.java b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/DefaultAccessLogItemCreator.java
deleted file mode 100644
index 6a2a6fd..0000000
--- a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/DefaultAccessLogItemCreator.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.servicecomb.transport.rest.vertx.accesslog.parser.impl;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.servicecomb.transport.rest.vertx.accesslog.element.AccessLogItem;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.CookieItem;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.DatetimeConfigurableItem;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.DurationMillisecondItem;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.DurationSecondItem;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.FirstLineOfRequestItem;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.HttpMethodItem;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.HttpStatusItem;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.InvocationContextItem;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.LocalHostItem;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.LocalPortItem;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.QueryStringItem;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.RemoteHostItem;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.RequestHeaderItem;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.RequestProtocolItem;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.ResponseHeaderItem;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.ResponseSizeItem;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.TraceIdItem;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.UrlPathItem;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.UrlPathWithQueryItem;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.AccessLogItemMeta;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.VertxRestAccessLogItemCreator;
-
-import io.vertx.ext.web.RoutingContext;
-
-public class DefaultAccessLogItemCreator implements VertxRestAccessLogItemCreator {
-  private static final Map<String, AccessLogItem<RoutingContext>> SIMPLE_ACCESS_LOG_ITEM_MAP = new HashMap<>();
-
-  private static final List<AccessLogItemMeta> SUPPORTED_META_LIST = new ArrayList<>();
-
-  static {
-    AccessLogItem<RoutingContext> item = new HttpMethodItem();
-    SIMPLE_ACCESS_LOG_ITEM_MAP.put("%m", item);
-    SIMPLE_ACCESS_LOG_ITEM_MAP.put("cs-method", item);
-    item = new HttpStatusItem();
-    SIMPLE_ACCESS_LOG_ITEM_MAP.put("%s", item);
-    SIMPLE_ACCESS_LOG_ITEM_MAP.put("sc-status", item);
-    SIMPLE_ACCESS_LOG_ITEM_MAP.put("%T", new DurationSecondItem());
-    SIMPLE_ACCESS_LOG_ITEM_MAP.put("%D", new DurationMillisecondItem());
-    SIMPLE_ACCESS_LOG_ITEM_MAP.put("%h", new RemoteHostItem());
-    SIMPLE_ACCESS_LOG_ITEM_MAP.put("%v", new LocalHostItem());
-    SIMPLE_ACCESS_LOG_ITEM_MAP.put("%p", new LocalPortItem());
-    SIMPLE_ACCESS_LOG_ITEM_MAP.put("%B", new ResponseSizeItem("0"));
-    SIMPLE_ACCESS_LOG_ITEM_MAP.put("%b", new ResponseSizeItem("-"));
-    SIMPLE_ACCESS_LOG_ITEM_MAP.put("%r", new FirstLineOfRequestItem());
-    item = new UrlPathItem();
-    SIMPLE_ACCESS_LOG_ITEM_MAP.put("%U", item);
-    SIMPLE_ACCESS_LOG_ITEM_MAP.put("cs-uri-stem", item);
-    item = new QueryStringItem();
-    SIMPLE_ACCESS_LOG_ITEM_MAP.put("%q", item);
-    SIMPLE_ACCESS_LOG_ITEM_MAP.put("cs-uri-query", item);
-    SIMPLE_ACCESS_LOG_ITEM_MAP.put("cs-uri", new UrlPathWithQueryItem());
-    SIMPLE_ACCESS_LOG_ITEM_MAP.put("%H", new RequestProtocolItem());
-    SIMPLE_ACCESS_LOG_ITEM_MAP.put("%t", new DatetimeConfigurableItem());
-    SIMPLE_ACCESS_LOG_ITEM_MAP.put("%SCB-traceId", new TraceIdItem());
-
-    SUPPORTED_META_LIST.add(new AccessLogItemMeta("%m", null));
-    SUPPORTED_META_LIST.add(new AccessLogItemMeta("cs-method", null));
-    SUPPORTED_META_LIST.add(new AccessLogItemMeta("%s", null));
-    SUPPORTED_META_LIST.add(new AccessLogItemMeta("sc-status", null));
-    SUPPORTED_META_LIST.add(new AccessLogItemMeta("%T", null));
-    SUPPORTED_META_LIST.add(new AccessLogItemMeta("%D", null));
-    SUPPORTED_META_LIST.add(new AccessLogItemMeta("%h", null));
-    SUPPORTED_META_LIST.add(new AccessLogItemMeta("%v", null));
-    SUPPORTED_META_LIST.add(new AccessLogItemMeta("%p", null));
-    SUPPORTED_META_LIST.add(new AccessLogItemMeta("%B", null));
-    SUPPORTED_META_LIST.add(new AccessLogItemMeta("%b", null));
-    SUPPORTED_META_LIST.add(new AccessLogItemMeta("%r", null));
-    SUPPORTED_META_LIST.add(new AccessLogItemMeta("%U", null));
-    SUPPORTED_META_LIST.add(new AccessLogItemMeta("cs-uri-stem", null));
-    SUPPORTED_META_LIST.add(new AccessLogItemMeta("%q", null));
-    SUPPORTED_META_LIST.add(new AccessLogItemMeta("cs-uri-query", null));
-    SUPPORTED_META_LIST.add(new AccessLogItemMeta("cs-uri", null));
-    SUPPORTED_META_LIST.add(new AccessLogItemMeta("%H", null));
-    SUPPORTED_META_LIST.add(new AccessLogItemMeta("%t", null));
-    SUPPORTED_META_LIST.add(new AccessLogItemMeta("%SCB-traceId", null));
-    SUPPORTED_META_LIST.add(new AccessLogItemMeta("%{", "}t"));
-    SUPPORTED_META_LIST.add(new AccessLogItemMeta("%{", "}i"));
-    SUPPORTED_META_LIST.add(new AccessLogItemMeta("%{", "}o"));
-    SUPPORTED_META_LIST.add(new AccessLogItemMeta("%{", "}C"));
-    SUPPORTED_META_LIST.add(new AccessLogItemMeta("%{", "}SCB-ctx"));
-  }
-
-  @Override
-  public AccessLogItem<RoutingContext> createItem(AccessLogItemMeta accessLogItemMeta, String config) {
-    if (null == accessLogItemMeta.getSuffix()) {
-      // For the simple AccessLogItem
-      return SIMPLE_ACCESS_LOG_ITEM_MAP.get(accessLogItemMeta.getPrefix());
-    }
-
-    // For the configurable AccessLogItem
-    switch (accessLogItemMeta.getSuffix()) {
-      case "}t":
-        return new DatetimeConfigurableItem(config);
-      case "}i":
-        return new RequestHeaderItem(config);
-      case "}o":
-        return new ResponseHeaderItem(config);
-      case "}C":
-        return new CookieItem(config);
-      case "}SCB-ctx":
-        return new InvocationContextItem(config);
-      default:
-        // unexpected situation
-        return null;
-    }
-  }
-
-  @Override
-  public List<AccessLogItemMeta> getAccessLogItemMeta() {
-    return SUPPORTED_META_LIST;
-  }
-}
diff --git a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/DefaultCompositeVertxRestAccessLogItemMeta.java b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/DefaultCompositeVertxRestAccessLogItemMeta.java
new file mode 100644
index 0000000..aaaf9f0
--- /dev/null
+++ b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/DefaultCompositeVertxRestAccessLogItemMeta.java
@@ -0,0 +1,87 @@
+/*
+ * 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.servicecomb.transport.rest.vertx.accesslog.parser.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.AccessLogItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.CookieItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.DatetimeConfigurableItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.DurationMillisecondItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.DurationSecondItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.FirstLineOfRequestItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.HttpMethodItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.HttpStatusItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.InvocationContextItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.LocalHostItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.LocalPortItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.QueryStringItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.RemoteHostItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.RequestHeaderItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.RequestProtocolItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.ResponseHeaderItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.ResponseSizeItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.TraceIdItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.UrlPathItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.UrlPathWithQueryItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.CompositeVertxRestAccessLogItemMeta;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.VertxRestAccessLogItemMeta;
+
+import io.vertx.ext.web.RoutingContext;
+
+public class DefaultCompositeVertxRestAccessLogItemMeta extends CompositeVertxRestAccessLogItemMeta {
+  private static final List<VertxRestAccessLogItemMeta> SUPPORTED_META = new ArrayList<>();
+
+  static {
+    final AccessLogItem<RoutingContext> httpMethodItem = new HttpMethodItem();
+    SUPPORTED_META.add(new VertxRestAccessLogItemMeta("%m", config -> httpMethodItem));
+    SUPPORTED_META.add(new VertxRestAccessLogItemMeta("cs-method", config -> httpMethodItem));
+    SUPPORTED_META.add(new VertxRestAccessLogItemMeta("%s", config -> new HttpStatusItem()));
+    SUPPORTED_META.add(new VertxRestAccessLogItemMeta("sc-status", config -> new HttpStatusItem()));
+    SUPPORTED_META.add(new VertxRestAccessLogItemMeta("%T", config -> new DurationSecondItem()));
+    SUPPORTED_META.add(new VertxRestAccessLogItemMeta("%D", config -> new DurationMillisecondItem()));
+    SUPPORTED_META.add(new VertxRestAccessLogItemMeta("%h", config -> new RemoteHostItem()));
+    SUPPORTED_META.add(new VertxRestAccessLogItemMeta("%v", config -> new LocalHostItem()));
+    SUPPORTED_META.add(new VertxRestAccessLogItemMeta("%p", config -> new LocalPortItem()));
+    SUPPORTED_META.add(new VertxRestAccessLogItemMeta("%B", config -> new ResponseSizeItem("0")));
+    SUPPORTED_META.add(new VertxRestAccessLogItemMeta("%b", config -> new ResponseSizeItem("-")));
+    SUPPORTED_META.add(new VertxRestAccessLogItemMeta("%r", config -> new FirstLineOfRequestItem()));
+    final AccessLogItem<RoutingContext> urlPathItem = new UrlPathItem();
+    SUPPORTED_META.add(new VertxRestAccessLogItemMeta("%U", config -> urlPathItem));
+    SUPPORTED_META.add(new VertxRestAccessLogItemMeta("cs-uri-stem", config -> urlPathItem));
+    final AccessLogItem<RoutingContext> queryStringItem = new QueryStringItem();
+    SUPPORTED_META.add(new VertxRestAccessLogItemMeta("%q", config -> queryStringItem));
+    SUPPORTED_META.add(new VertxRestAccessLogItemMeta("cs-uri-query", config -> queryStringItem));
+    SUPPORTED_META.add(new VertxRestAccessLogItemMeta("cs-uri", config -> new UrlPathWithQueryItem()));
+    SUPPORTED_META.add(new VertxRestAccessLogItemMeta("%H", config -> new RequestProtocolItem()));
+    SUPPORTED_META.add(new VertxRestAccessLogItemMeta("%t", config -> new DatetimeConfigurableItem()));
+    SUPPORTED_META.add(new VertxRestAccessLogItemMeta("%SCB-traceId", config -> new TraceIdItem()));
+
+    SUPPORTED_META.add(new VertxRestAccessLogItemMeta("%{", "}t", DatetimeConfigurableItem::new));
+    SUPPORTED_META.add(new VertxRestAccessLogItemMeta("%{", "}i", RequestHeaderItem::new));
+    SUPPORTED_META.add(new VertxRestAccessLogItemMeta("%{", "}o", ResponseHeaderItem::new));
+    SUPPORTED_META.add(new VertxRestAccessLogItemMeta("%{", "}C", CookieItem::new));
+    SUPPORTED_META.add(new VertxRestAccessLogItemMeta("%{", "}SCB-ctx", InvocationContextItem::new));
+  }
+
+  @Override
+  public List<VertxRestAccessLogItemMeta> getAccessLogItemMetas() {
+    return SUPPORTED_META;
+  }
+}
diff --git a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/VertxRestAccessLogPatternParser.java b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/VertxRestAccessLogPatternParser.java
index 69776cc..7fdb2f9 100644
--- a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/VertxRestAccessLogPatternParser.java
+++ b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/VertxRestAccessLogPatternParser.java
@@ -27,7 +27,8 @@ import org.apache.servicecomb.transport.rest.vertx.accesslog.element.AccessLogIt
 import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.PlainTextItem;
 import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.AccessLogItemMeta;
 import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.AccessLogPatternParser;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.VertxRestAccessLogItemCreator;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.CompositeVertxRestAccessLogItemMeta;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.VertxRestAccessLogItemMeta;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -39,55 +40,53 @@ import io.vertx.ext.web.RoutingContext;
 public class VertxRestAccessLogPatternParser implements AccessLogPatternParser<RoutingContext> {
   private static final Logger LOGGER = LoggerFactory.getLogger(VertxRestAccessLogPatternParser.class);
 
-  public static final Comparator<AccessLogItemMetaWrapper> accessLogItemMetaWrapperComparator = (w1, w2) -> {
-    AccessLogItemMeta meta1 = w1.getAccessLogItemMeta();
-    AccessLogItemMeta meta2 = w2.getAccessLogItemMeta();
-    int result = meta1.getOrder() - meta2.getOrder();
+  public static final Comparator<VertxRestAccessLogItemMeta> accessLogItemMetaComparator = (m1, m2) -> {
+    int result = m1.getOrder() - m2.getOrder();
     if (result != 0) {
       return result;
     }
 
-    // one of meta1 & meta2 has suffix, but the other one doesn't have
-    if (meta1.getSuffix() == null ^ meta2.getSuffix() == null) {
-      return meta1.getSuffix() == null ? 1 : -1;
+    // one of m1 & m2 has suffix, but the other one doesn't have
+    if (m1.getSuffix() == null ^ m2.getSuffix() == null) {
+      return m1.getSuffix() == null ? 1 : -1;
     }
 
-    if (null != meta1.getSuffix()) {
-      result = comparePlaceholderString(meta1.getSuffix(), meta2.getSuffix());
+    if (null != m1.getSuffix()) {
+      result = comparePlaceholderString(m1.getSuffix(), m2.getSuffix());
     }
 
     return 0 == result ?
-        comparePlaceholderString(meta1.getPrefix(), meta2.getPrefix())
+        comparePlaceholderString(m1.getPrefix(), m2.getPrefix())
         : result;
   };
 
-  private List<VertxRestAccessLogItemCreator> creators;
-
-  private List<AccessLogItemMetaWrapper> accessLogItemMetaWrappers = new ArrayList<>();
+  private List<VertxRestAccessLogItemMeta> metaList = new ArrayList<>();
 
   public VertxRestAccessLogPatternParser() {
-    List<VertxRestAccessLogItemCreator> creators = loadVertxRestAccessLogItemCreators();
-    this.creators = creators;
-    if (null == creators) {
-      LOGGER.error("cannot load VertxRestAccessLogItemCreator!");
+    List<VertxRestAccessLogItemMeta> loadedMeta = loadVertxRestAccessLogItemMeta();
+    if (null == loadedMeta || loadedMeta.isEmpty()) {
+      LOGGER.error("cannot load AccessLogItemMeta!");
+      throw new IllegalStateException("cannot load AccessLogItemMeta!");
     }
-    for (VertxRestAccessLogItemCreator creator : this.creators) {
-      for (AccessLogItemMeta accessLogItemMeta : creator.getAccessLogItemMeta()) {
-        accessLogItemMetaWrappers.add(new AccessLogItemMetaWrapper(accessLogItemMeta, creator));
+    for (VertxRestAccessLogItemMeta meta : loadedMeta) {
+      if (CompositeVertxRestAccessLogItemMeta.class.isAssignableFrom(meta.getClass())) {
+        this.metaList.addAll(((CompositeVertxRestAccessLogItemMeta) meta).getAccessLogItemMetas());
+      } else {
+        this.metaList.add(meta);
       }
     }
-    sortAccessLogItemMetaWrapper(accessLogItemMetaWrappers);
+    sortAccessLogItemMeta(this.metaList);
   }
 
-  private List<VertxRestAccessLogItemCreator> loadVertxRestAccessLogItemCreators() {
-    return SPIServiceUtils.getOrLoadSortedService(VertxRestAccessLogItemCreator.class);
+  private List<VertxRestAccessLogItemMeta> loadVertxRestAccessLogItemMeta() {
+    return SPIServiceUtils.getOrLoadSortedService(VertxRestAccessLogItemMeta.class);
   }
 
   /**
    * Behavior of this compare:
    * 1. comparePlaceholderString("abc","bbc") < 0
    * 2. comparePlaceholderString("abc","ab") < 0
-   * 3. comparePlaceholderString("abc","abc) = 0
+   * 3. comparePlaceholderString("abc","abc") = 0
    */
   public static int comparePlaceholderString(String s1, String s2) {
     int result = s1.compareTo(s2);
@@ -105,7 +104,7 @@ public class VertxRestAccessLogPatternParser implements AccessLogPatternParser<R
   }
 
   /**
-   * Sort all of the {@link AccessLogItemMetaWrapper}, the wrapper that is in front of the others has higher priority.
+   * Sort all of the {@link AccessLogItemMeta}, the meta that is in front of the others has higher priority.
    * <p/>
    * Sort rule(priority decreased):
    * <ol>
@@ -138,8 +137,8 @@ public class VertxRestAccessLogPatternParser implements AccessLogPatternParser<R
    * <li>(%b,)</li>
    * </ol>
    */
-  public static void sortAccessLogItemMetaWrapper(List<AccessLogItemMetaWrapper> accessLogItemMetaWrapperList) {
-    accessLogItemMetaWrapperList.sort(accessLogItemMetaWrapperComparator);
+  public static void sortAccessLogItemMeta(List<VertxRestAccessLogItemMeta> accessLogItemMetaList) {
+    accessLogItemMetaList.sort(accessLogItemMetaComparator);
   }
 
   /**
@@ -156,7 +155,7 @@ public class VertxRestAccessLogPatternParser implements AccessLogPatternParser<R
   }
 
   /**
-   * Use the {@link #accessLogItemMetaWrappers} to match rawPattern.
+   * Use the {@link #metaList} to match rawPattern.
    * Return a list of {@link AccessLogItemLocation}.
    * Plain text is ignored.
    */
@@ -165,8 +164,8 @@ public class VertxRestAccessLogPatternParser implements AccessLogPatternParser<R
     int cursor = 0;
     while (cursor < rawPattern.length()) {
       AccessLogItemLocation candidate = null;
-      for (AccessLogItemMetaWrapper wrapper : accessLogItemMetaWrappers) {
-        if (null != candidate && null == wrapper.getSuffix()) {
+      for (VertxRestAccessLogItemMeta meta : metaList) {
+        if (null != candidate && null == meta.getSuffix()) {
           // TODO:
           // if user define item("%{","}ab") and item("%{_","}abc") and the pattern is "%{_var}ab}abc"
           // currently the result is item("%{","_var","}ab"), plaintext("}abc")
@@ -177,10 +176,10 @@ public class VertxRestAccessLogPatternParser implements AccessLogPatternParser<R
           cursor = candidate.tail;
           break;
         }
-        if (rawPattern.startsWith(wrapper.getPrefix(), cursor)) {
-          if (null == wrapper.getSuffix()) {
+        if (rawPattern.startsWith(meta.getPrefix(), cursor)) {
+          if (null == meta.getSuffix()) {
             // for simple type AccessLogItem, there is no need to try to match the next item.
-            candidate = new AccessLogItemLocation(cursor, wrapper);
+            candidate = new AccessLogItemLocation(cursor, meta);
             cursor = candidate.tail;
             break;
           }
@@ -188,12 +187,12 @@ public class VertxRestAccessLogPatternParser implements AccessLogPatternParser<R
           // e.g. "%{varName1}o ${varName2}i" should be divided into
           // ResponseHeaderItem with varName="varName1" and RequestHeaderItem with varName="varName2"
           // INSTEAD OF RequestHeaderItem with varName="varName1}o ${varName2"
-          int rear = rawPattern.indexOf(wrapper.getSuffix(), cursor);
+          int rear = rawPattern.indexOf(meta.getSuffix(), cursor);
           if (rear < 0) {
             continue;
           }
           if (null == candidate || rear < candidate.suffixIndex) {
-            candidate = new AccessLogItemLocation(cursor, rear, wrapper);
+            candidate = new AccessLogItemLocation(cursor, rear, meta);
           }
           // There is a matched item which is in front of this item, so this item is ignored.
         }
@@ -258,8 +257,8 @@ public class VertxRestAccessLogPatternParser implements AccessLogPatternParser<R
     List<AccessLogItem<RoutingContext>> itemList = new ArrayList<>();
 
     for (AccessLogItemLocation accessLogItemLocation : locationList) {
-      AccessLogItemMetaWrapper accessLogItemMetaWrapper = accessLogItemLocation.accessLogItemMetaWrapper;
-      if (null == accessLogItemMetaWrapper) {
+      VertxRestAccessLogItemMeta accessLogItemMeta = accessLogItemLocation.accessLogItemMeta;
+      if (null == accessLogItemMeta) {
         // a PlainTextItem location
         itemList.add(new PlainTextItem(rawPattern.substring(
             accessLogItemLocation.prefixIndex, accessLogItemLocation.tail
@@ -268,8 +267,7 @@ public class VertxRestAccessLogPatternParser implements AccessLogPatternParser<R
       }
 
       itemList.add(
-          accessLogItemMetaWrapper.getVertxRestAccessLogItemCreator().createItem(
-              accessLogItemMetaWrapper.getAccessLogItemMeta(),
+          accessLogItemMeta.getAccessLogItemCreator().createItem(
               getConfigString(rawPattern, accessLogItemLocation))
       );
     }
@@ -304,7 +302,7 @@ public class VertxRestAccessLogPatternParser implements AccessLogPatternParser<R
      */
     int tail;
 
-    AccessLogItemMetaWrapper accessLogItemMetaWrapper;
+    VertxRestAccessLogItemMeta accessLogItemMeta;
 
     /**
      * for {@link PlainTextItem} only
@@ -318,62 +316,34 @@ public class VertxRestAccessLogPatternParser implements AccessLogPatternParser<R
     /**
      * for configurable type AccessLogItem
      */
-    AccessLogItemLocation(int prefixIndex, int suffixIndex, AccessLogItemMetaWrapper accessLogItemMetaWrapper) {
+    AccessLogItemLocation(int prefixIndex, int suffixIndex, VertxRestAccessLogItemMeta accessLogItemMeta) {
       this.prefixIndex = prefixIndex;
       this.suffixIndex = suffixIndex;
-      this.tail = suffixIndex + accessLogItemMetaWrapper.getSuffix().length();
-      this.accessLogItemMetaWrapper = accessLogItemMetaWrapper;
+      this.tail = suffixIndex + accessLogItemMeta.getSuffix().length();
+      this.accessLogItemMeta = accessLogItemMeta;
     }
 
     /**
      * for simple type AccessLogItem
      */
-    AccessLogItemLocation(int prefixIndex, AccessLogItemMetaWrapper accessLogItemMetaWrapper) {
+    AccessLogItemLocation(int prefixIndex, VertxRestAccessLogItemMeta accessLogItemMeta) {
       this.prefixIndex = prefixIndex;
-      this.suffixIndex = prefixIndex + accessLogItemMetaWrapper.getPrefix().length();
+      this.suffixIndex = prefixIndex + accessLogItemMeta.getPrefix().length();
       this.tail = this.suffixIndex;
-      this.accessLogItemMetaWrapper = accessLogItemMetaWrapper;
+      this.accessLogItemMeta = accessLogItemMeta;
     }
 
     public String getPrefix() {
-      if (null == accessLogItemMetaWrapper) {
+      if (null == accessLogItemMeta) {
         return null;
       }
-      return accessLogItemMetaWrapper.getPrefix();
+      return accessLogItemMeta.getPrefix();
     }
 
     public String getSuffix() {
-      if (null == accessLogItemMetaWrapper) {
+      if (null == accessLogItemMeta) {
         return null;
       }
-      return accessLogItemMetaWrapper.getSuffix();
-    }
-  }
-
-  public static class AccessLogItemMetaWrapper {
-    private AccessLogItemMeta accessLogItemMeta;
-
-    private VertxRestAccessLogItemCreator vertxRestAccessLogItemCreator;
-
-    public AccessLogItemMetaWrapper(AccessLogItemMeta accessLogItemMeta,
-        VertxRestAccessLogItemCreator vertxRestAccessLogItemCreator) {
-      this.accessLogItemMeta = accessLogItemMeta;
-      this.vertxRestAccessLogItemCreator = vertxRestAccessLogItemCreator;
-    }
-
-    public AccessLogItemMeta getAccessLogItemMeta() {
-      return accessLogItemMeta;
-    }
-
-    public VertxRestAccessLogItemCreator getVertxRestAccessLogItemCreator() {
-      return vertxRestAccessLogItemCreator;
-    }
-
-    public String getPrefix() {
-      return accessLogItemMeta.getPrefix();
-    }
-
-    public String getSuffix() {
       return accessLogItemMeta.getSuffix();
     }
   }
diff --git a/transports/transport-rest/transport-rest-vertx/src/main/resources/META-INF/services/org.apache.servicecomb.transport.rest.vertx.accesslog.parser.VertxRestAccessLogItemCreator b/transports/transport-rest/transport-rest-vertx/src/main/resources/META-INF/services/org.apache.servicecomb.transport.rest.vertx.accesslog.parser.VertxRestAccessLogItemMeta
similarity index 95%
copy from transports/transport-rest/transport-rest-vertx/src/main/resources/META-INF/services/org.apache.servicecomb.transport.rest.vertx.accesslog.parser.VertxRestAccessLogItemCreator
copy to transports/transport-rest/transport-rest-vertx/src/main/resources/META-INF/services/org.apache.servicecomb.transport.rest.vertx.accesslog.parser.VertxRestAccessLogItemMeta
index 92e596a..7a9f86c 100644
--- a/transports/transport-rest/transport-rest-vertx/src/main/resources/META-INF/services/org.apache.servicecomb.transport.rest.vertx.accesslog.parser.VertxRestAccessLogItemCreator
+++ b/transports/transport-rest/transport-rest-vertx/src/main/resources/META-INF/services/org.apache.servicecomb.transport.rest.vertx.accesslog.parser.VertxRestAccessLogItemMeta
@@ -15,4 +15,4 @@
 # limitations under the License.
 #
 
-org.apache.servicecomb.transport.rest.vertx.accesslog.parser.impl.DefaultAccessLogItemCreator
\ No newline at end of file
+org.apache.servicecomb.transport.rest.vertx.accesslog.parser.impl.DefaultCompositeVertxRestAccessLogItemMeta
\ No newline at end of file
diff --git a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/AccessLogItemMeta.java b/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/impl/UserDefinedAccessLogItem.java
similarity index 55%
copy from transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/AccessLogItemMeta.java
copy to transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/impl/UserDefinedAccessLogItem.java
index 131743e..a2559c6 100644
--- a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/AccessLogItemMeta.java
+++ b/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/impl/UserDefinedAccessLogItem.java
@@ -15,43 +15,25 @@
  * limitations under the License.
  */
 
-package org.apache.servicecomb.transport.rest.vertx.accesslog.parser;
+package org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl;
 
+import org.apache.servicecomb.transport.rest.vertx.accesslog.AccessLogParam;
 import org.apache.servicecomb.transport.rest.vertx.accesslog.element.AccessLogItem;
 
+import io.vertx.ext.web.RoutingContext;
+
 /**
- * The meta data of {@linkplain AccessLogItem}.
+ * For access log extension test
  */
-public class AccessLogItemMeta {
-  private String prefix;
-
-  private String suffix;
-
-  /**
-   * Used for sorting {@linkplain AccessLogItemMeta}. Default value is 0.
-   * Smaller one has higher priority.
-   */
-  private int order;
-
-  public AccessLogItemMeta(String prefix, String suffix, int order) {
-    this.prefix = prefix;
-    this.suffix = suffix;
-    this.order = order;
-  }
-
-  public AccessLogItemMeta(String prefix, String suffix) {
-    this(prefix, suffix, 0);
-  }
-
-  public String getPrefix() {
-    return prefix;
-  }
+public class UserDefinedAccessLogItem implements AccessLogItem<RoutingContext> {
+  private String config;
 
-  public String getSuffix() {
-    return suffix;
+  public UserDefinedAccessLogItem(String config) {
+    this.config = config;
   }
 
-  public int getOrder() {
-    return order;
+  @Override
+  public String getFormattedItem(AccessLogParam<RoutingContext> accessLogParam) {
+    return "user-defined-" + config;
   }
 }
diff --git a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/AccessLogItemMeta.java b/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/impl/UserDefinedAccessLogItemLowPriority.java
similarity index 54%
copy from transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/AccessLogItemMeta.java
copy to transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/impl/UserDefinedAccessLogItemLowPriority.java
index 131743e..eec7b29 100644
--- a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/AccessLogItemMeta.java
+++ b/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/impl/UserDefinedAccessLogItemLowPriority.java
@@ -15,43 +15,21 @@
  * limitations under the License.
  */
 
-package org.apache.servicecomb.transport.rest.vertx.accesslog.parser;
+package org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl;
 
+import org.apache.servicecomb.transport.rest.vertx.accesslog.AccessLogParam;
 import org.apache.servicecomb.transport.rest.vertx.accesslog.element.AccessLogItem;
 
+import io.vertx.ext.web.RoutingContext;
+
 /**
- * The meta data of {@linkplain AccessLogItem}.
+ * For access log extension test, will be overridden by {@link RemoteHostItem}("%h"),
+ * and takes no effect.
  */
-public class AccessLogItemMeta {
-  private String prefix;
-
-  private String suffix;
-
-  /**
-   * Used for sorting {@linkplain AccessLogItemMeta}. Default value is 0.
-   * Smaller one has higher priority.
-   */
-  private int order;
-
-  public AccessLogItemMeta(String prefix, String suffix, int order) {
-    this.prefix = prefix;
-    this.suffix = suffix;
-    this.order = order;
-  }
-
-  public AccessLogItemMeta(String prefix, String suffix) {
-    this(prefix, suffix, 0);
-  }
-
-  public String getPrefix() {
-    return prefix;
-  }
-
-  public String getSuffix() {
-    return suffix;
-  }
+public class UserDefinedAccessLogItemLowPriority implements AccessLogItem<RoutingContext> {
 
-  public int getOrder() {
-    return order;
+  @Override
+  public String getFormattedItem(AccessLogParam<RoutingContext> accessLogParam) {
+    return "OverriddenItem";
   }
 }
diff --git a/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/impl/AccessLogHandlerTest.java b/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/impl/AccessLogHandlerTest.java
new file mode 100644
index 0000000..ce96d49
--- /dev/null
+++ b/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/impl/AccessLogHandlerTest.java
@@ -0,0 +1,104 @@
+/*
+ * 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.servicecomb.transport.rest.vertx.accesslog.impl;
+
+import java.util.HashSet;
+
+import javax.xml.ws.Holder;
+
+import org.apache.log4j.Level;
+import org.apache.servicecomb.foundation.test.scaffolding.log.LogCollector;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import io.vertx.core.Handler;
+import io.vertx.core.http.HttpServerRequest;
+import io.vertx.core.http.HttpServerResponse;
+import io.vertx.core.net.SocketAddress;
+import io.vertx.ext.web.Cookie;
+import io.vertx.ext.web.RoutingContext;
+import mockit.Mock;
+import mockit.MockUp;
+
+public class AccessLogHandlerTest {
+  private static final AccessLogHandler ACCESS_LOG_HANDLER = new AccessLogHandler(
+      "%h - - %s durationMillisecond=[%D] %{test-config}user-defined %{cookie-name}C");
+
+  private LogCollector logCollector;
+
+  @Before
+  public void setUp() {
+    logCollector = new LogCollector();
+    logCollector.setLogLevel("accesslog", Level.INFO);
+  }
+
+  @After
+  public void tearDown() {
+    logCollector.teardown();
+  }
+
+  @Test
+  public void testHandle() {
+    RoutingContext routingContext = Mockito.mock(RoutingContext.class);
+    HashSet<Cookie> cookies = new HashSet<>();
+    Cookie cookie = Mockito.mock(Cookie.class);
+    HttpServerResponse httpServerResponse = new MockUp<HttpServerResponse>() {
+      @Mock
+      public HttpServerResponse endHandler(Handler<Void> handler) {
+        handler.handle(null);
+        return null;
+      }
+
+      @Mock
+      public int getStatusCode() {
+        return 200;
+      }
+    }.getMockInstance();
+    HttpServerRequest httpServerRequest = Mockito.mock(HttpServerRequest.class);
+    SocketAddress socketAddress = Mockito.mock(SocketAddress.class);
+
+    Holder<Integer> counter = new Holder<>();
+    counter.value = 0;
+    new MockUp<System>() {
+      @Mock
+      long currentTimeMillis() {
+        if (counter.value < 1) {
+          ++counter.value;
+          return 1L;
+        }
+        return 123L;
+      }
+    };
+    cookies.add(cookie);
+    Mockito.when(cookie.getName()).thenReturn("cookie-name");
+    Mockito.when(cookie.getValue()).thenReturn("cookie-value");
+    Mockito.when(routingContext.cookies()).thenReturn(cookies);
+    Mockito.when(routingContext.response()).thenReturn(httpServerResponse);
+    Mockito.when(routingContext.request()).thenReturn(httpServerRequest);
+    Mockito.when(httpServerRequest.remoteAddress()).thenReturn(socketAddress);
+    Mockito.when(socketAddress.host()).thenReturn("localhost");
+
+    ACCESS_LOG_HANDLER.handle(routingContext);
+
+    Assert.assertEquals("localhost - - 200 durationMillisecond=[122] user-defined-test-config cookie-value",
+        logCollector.getEvents().get(0).getMessage());
+  }
+}
\ No newline at end of file
diff --git a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/AccessLogItemMeta.java b/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/TestCompositeExtendedAccessLogItemMeta.java
similarity index 57%
copy from transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/AccessLogItemMeta.java
copy to transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/TestCompositeExtendedAccessLogItemMeta.java
index 131743e..c226bab 100644
--- a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/AccessLogItemMeta.java
+++ b/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/TestCompositeExtendedAccessLogItemMeta.java
@@ -15,43 +15,24 @@
  * limitations under the License.
  */
 
-package org.apache.servicecomb.transport.rest.vertx.accesslog.parser;
+package org.apache.servicecomb.transport.rest.vertx.accesslog.parser.impl;
 
-import org.apache.servicecomb.transport.rest.vertx.accesslog.element.AccessLogItem;
+import java.util.ArrayList;
+import java.util.List;
 
-/**
- * The meta data of {@linkplain AccessLogItem}.
- */
-public class AccessLogItemMeta {
-  private String prefix;
-
-  private String suffix;
-
-  /**
-   * Used for sorting {@linkplain AccessLogItemMeta}. Default value is 0.
-   * Smaller one has higher priority.
-   */
-  private int order;
-
-  public AccessLogItemMeta(String prefix, String suffix, int order) {
-    this.prefix = prefix;
-    this.suffix = suffix;
-    this.order = order;
-  }
-
-  public AccessLogItemMeta(String prefix, String suffix) {
-    this(prefix, suffix, 0);
-  }
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.UserDefinedAccessLogItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.CompositeVertxRestAccessLogItemMeta;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.VertxRestAccessLogItemMeta;
 
-  public String getPrefix() {
-    return prefix;
-  }
+public class TestCompositeExtendedAccessLogItemMeta extends CompositeVertxRestAccessLogItemMeta {
+  private static final List<VertxRestAccessLogItemMeta> META_LIST = new ArrayList<>();
 
-  public String getSuffix() {
-    return suffix;
+  static {
+    META_LIST.add(new VertxRestAccessLogItemMeta("%{", "}user-defined", UserDefinedAccessLogItem::new));
   }
 
-  public int getOrder() {
-    return order;
+  @Override
+  public List<VertxRestAccessLogItemMeta> getAccessLogItemMetas() {
+    return META_LIST;
   }
 }
diff --git a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/AccessLogItemMeta.java b/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/TestSingleExtendedAccessLogItemMeta.java
similarity index 56%
copy from transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/AccessLogItemMeta.java
copy to transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/TestSingleExtendedAccessLogItemMeta.java
index 131743e..9a2a1c7 100644
--- a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/AccessLogItemMeta.java
+++ b/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/TestSingleExtendedAccessLogItemMeta.java
@@ -15,43 +15,13 @@
  * limitations under the License.
  */
 
-package org.apache.servicecomb.transport.rest.vertx.accesslog.parser;
+package org.apache.servicecomb.transport.rest.vertx.accesslog.parser.impl;
 
-import org.apache.servicecomb.transport.rest.vertx.accesslog.element.AccessLogItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.UserDefinedAccessLogItemLowPriority;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.VertxRestAccessLogItemMeta;
 
-/**
- * The meta data of {@linkplain AccessLogItem}.
- */
-public class AccessLogItemMeta {
-  private String prefix;
-
-  private String suffix;
-
-  /**
-   * Used for sorting {@linkplain AccessLogItemMeta}. Default value is 0.
-   * Smaller one has higher priority.
-   */
-  private int order;
-
-  public AccessLogItemMeta(String prefix, String suffix, int order) {
-    this.prefix = prefix;
-    this.suffix = suffix;
-    this.order = order;
-  }
-
-  public AccessLogItemMeta(String prefix, String suffix) {
-    this(prefix, suffix, 0);
-  }
-
-  public String getPrefix() {
-    return prefix;
-  }
-
-  public String getSuffix() {
-    return suffix;
-  }
-
-  public int getOrder() {
-    return order;
+public class TestSingleExtendedAccessLogItemMeta extends VertxRestAccessLogItemMeta {
+  public TestSingleExtendedAccessLogItemMeta() {
+    super("%h", null, config -> new UserDefinedAccessLogItemLowPriority(), 1);
   }
 }
diff --git a/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/VertxRestAccessLogPatternParserTest.java b/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/VertxRestAccessLogPatternParserTest.java
index 57e9100..cf31d15 100644
--- a/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/VertxRestAccessLogPatternParserTest.java
+++ b/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/VertxRestAccessLogPatternParserTest.java
@@ -25,7 +25,6 @@ import java.util.Comparator;
 import java.util.List;
 import java.util.Locale;
 import java.util.TimeZone;
-import java.util.function.Function;
 
 import org.apache.servicecomb.transport.rest.vertx.accesslog.element.AccessLogItem;
 import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.CookieItem;
@@ -47,9 +46,8 @@ import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.Respon
 import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.TraceIdItem;
 import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.UrlPathItem;
 import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.UrlPathWithQueryItem;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.AccessLogItemMeta;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.VertxRestAccessLogItemCreator;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.impl.VertxRestAccessLogPatternParser.AccessLogItemMetaWrapper;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.CompositeVertxRestAccessLogItemMeta;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.VertxRestAccessLogItemMeta;
 import org.junit.Assert;
 import org.junit.Test;
 
@@ -169,10 +167,7 @@ public class VertxRestAccessLogPatternParserTest {
     assertEquals(UrlPathWithQueryItem.class, result.get(11).getClass());
   }
 
-  Comparator<AccessLogItemMetaWrapper> comparator = VertxRestAccessLogPatternParser.accessLogItemMetaWrapperComparator;
-
-  Function<AccessLogItemMeta, AccessLogItemMetaWrapper> wrapper =
-      accessLogItemMeta -> new AccessLogItemMetaWrapper(accessLogItemMeta, null);
+  Comparator<VertxRestAccessLogItemMeta> comparator = VertxRestAccessLogPatternParser.accessLogItemMetaComparator;
 
   /**
    * one factor test
@@ -181,43 +176,43 @@ public class VertxRestAccessLogPatternParserTest {
   public void testCompareMetaSimple() {
     Assert.assertTrue(
         comparator.compare(
-            wrapper.apply(new AccessLogItemMeta(null, null, 0)),
-            wrapper.apply(new AccessLogItemMeta(null, null, 1))
+            new VertxRestAccessLogItemMeta(null, null, null, 0),
+            new VertxRestAccessLogItemMeta(null, null, null, 1)
         ) < 0
     );
     Assert.assertTrue(
         comparator.compare(
-            wrapper.apply(new AccessLogItemMeta(null, "}abc")),
-            wrapper.apply(new AccessLogItemMeta(null, null))
+            new VertxRestAccessLogItemMeta(null, "}abc", null, 0),
+            new VertxRestAccessLogItemMeta(null, null, null, 0)
         ) < 0
     );
     Assert.assertTrue(
         comparator.compare(
-            wrapper.apply(new AccessLogItemMeta(null, "}abc")),
-            wrapper.apply(new AccessLogItemMeta(null, "}de"))
+            new VertxRestAccessLogItemMeta(null, "}abc", null, 0),
+            new VertxRestAccessLogItemMeta(null, "}de", null, 0)
         ) < 0
     );
     Assert.assertTrue(
         comparator.compare(
-            wrapper.apply(new AccessLogItemMeta(null, "}abc")),
-            wrapper.apply(new AccessLogItemMeta(null, "}ab"))
+            new VertxRestAccessLogItemMeta(null, "}abc", null, 0),
+            new VertxRestAccessLogItemMeta(null, "}ab", null, 0)
         ) < 0
     );
     Assert.assertTrue(
         comparator.compare(
-            wrapper.apply(new AccessLogItemMeta("%abc", null)),
-            wrapper.apply(new AccessLogItemMeta("%de", null))
+            new VertxRestAccessLogItemMeta("%abc", null, null, 0),
+            new VertxRestAccessLogItemMeta("%de", null, null, 0)
         ) < 0
     );
     Assert.assertTrue(
         comparator.compare(
-            wrapper.apply(new AccessLogItemMeta("%abc", null)),
-            wrapper.apply(new AccessLogItemMeta("%ab", null))
+            new VertxRestAccessLogItemMeta("%abc", null, null, 0),
+            new VertxRestAccessLogItemMeta("%ab", null, null, 0)
         ) < 0
     );
     Assert.assertEquals(0, comparator.compare(
-        wrapper.apply(new AccessLogItemMeta("%abc", null)),
-        wrapper.apply(new AccessLogItemMeta("%abc", null))
+        new VertxRestAccessLogItemMeta("%abc", null, null, 0),
+        new VertxRestAccessLogItemMeta("%abc", null, null, 0)
     ));
   }
 
@@ -228,26 +223,26 @@ public class VertxRestAccessLogPatternParserTest {
   public void testCompareMetaComplex() {
     Assert.assertTrue(
         comparator.compare(
-            wrapper.apply(new AccessLogItemMeta("%bcd", "}ab", 0)),
-            wrapper.apply(new AccessLogItemMeta("%abc", "}abc", 0))
+            new VertxRestAccessLogItemMeta("%bcd", "}ab", null, 0),
+            new VertxRestAccessLogItemMeta("%abc", "}abc", null, 0)
         ) > 0
     );
     Assert.assertTrue(
         comparator.compare(
-            wrapper.apply(new AccessLogItemMeta("%abc", null, 0)),
-            wrapper.apply(new AccessLogItemMeta("%bcd", "}ab", 0))
+            new VertxRestAccessLogItemMeta("%abc", null, null, 0),
+            new VertxRestAccessLogItemMeta("%bcd", "}ab", null, 0)
         ) > 0
     );
     Assert.assertTrue(
         comparator.compare(
-            wrapper.apply(new AccessLogItemMeta("%bcd", "}abc")),
-            wrapper.apply(new AccessLogItemMeta("%abc", "}abc"))
+            new VertxRestAccessLogItemMeta("%bcd", "}abc", null, 0),
+            new VertxRestAccessLogItemMeta("%abc", "}abc", null, 0)
         ) > 0
     );
     Assert.assertTrue(
         comparator.compare(
-            wrapper.apply(new AccessLogItemMeta("%abc", "}abc", 1)),
-            wrapper.apply(new AccessLogItemMeta("%ab", "}ab", 0))
+            new VertxRestAccessLogItemMeta("%abc", "}abc", null, 1),
+            new VertxRestAccessLogItemMeta("%ab", "}ab", null, 0)
         ) > 0
     );
   }
@@ -271,69 +266,57 @@ public class VertxRestAccessLogPatternParserTest {
 
   @Test
   public void testExtendedVertxRestAccessLogItemCreator() {
-    final List<AccessLogItemMeta> metaList0 = new ArrayList<>();
-    metaList0.add(new AccessLogItemMeta("%{", "}abc"));
-    metaList0.add(new AccessLogItemMeta("%{", "}a"));
-    metaList0.add(new AccessLogItemMeta("%{", null));
-    metaList0.add(new AccessLogItemMeta("%_", null, -1));
-
-    final List<AccessLogItemMeta> metaList1 = new ArrayList<>();
-    metaList0.add(new AccessLogItemMeta("%a", "}abc"));
-    metaList0.add(new AccessLogItemMeta("%0", "}abc", 1));
-    metaList0.add(new AccessLogItemMeta("%m", null));
-
-    final VertxRestAccessLogItemCreator accessLogItemCreator0 = new VertxRestAccessLogItemCreator() {
-      @Override
-      public List<AccessLogItemMeta> getAccessLogItemMeta() {
-        return metaList0;
-      }
+    final List<VertxRestAccessLogItemMeta> metaList0 = new ArrayList<>();
+    metaList0.add(new VertxRestAccessLogItemMeta("%{", "}abc", null));
+    metaList0.add(new VertxRestAccessLogItemMeta("%{", "}a", null));
+    metaList0.add(new VertxRestAccessLogItemMeta("%_", null, null, -1));
 
-      @Override
-      public AccessLogItem<RoutingContext> createItem(AccessLogItemMeta accessLogItemMeta, String config) {
-        return null;
-      }
-    };
-
-    final VertxRestAccessLogItemCreator accessLogItemCreator1 = new VertxRestAccessLogItemCreator() {
-      @Override
-      public List<AccessLogItemMeta> getAccessLogItemMeta() {
-        return metaList1;
-      }
-
-      @Override
-      public AccessLogItem<RoutingContext> createItem(AccessLogItemMeta accessLogItemMeta, String config) {
-        return null;
-      }
-    };
+    final List<VertxRestAccessLogItemMeta> metaList1 = new ArrayList<>();
+    metaList0.add(new VertxRestAccessLogItemMeta("%a", "}abc", null));
+    metaList0.add(new VertxRestAccessLogItemMeta("%0", "}abc", null, 1));
+    metaList0.add(new VertxRestAccessLogItemMeta("%m", null, null));
 
     new MockUp<VertxRestAccessLogPatternParser>() {
       @Mock
-      List<VertxRestAccessLogItemCreator> loadVertxRestAccessLogItemCreators() {
-        List<VertxRestAccessLogItemCreator> creators = new ArrayList<>(1);
-        creators.add(accessLogItemCreator0);
-        creators.add(accessLogItemCreator1);
-        return creators;
+      List<VertxRestAccessLogItemMeta> loadVertxRestAccessLogItemMeta() {
+        List<VertxRestAccessLogItemMeta> metaList = new ArrayList<>(1);
+        CompositeVertxRestAccessLogItemMeta compositeMeta0 = new CompositeVertxRestAccessLogItemMeta() {
+          @Override
+          public List<VertxRestAccessLogItemMeta> getAccessLogItemMetas() {
+            return metaList0;
+          }
+        };
+        CompositeVertxRestAccessLogItemMeta compositeMeta1 = new CompositeVertxRestAccessLogItemMeta() {
+          @Override
+          public List<VertxRestAccessLogItemMeta> getAccessLogItemMetas() {
+            return metaList1;
+          }
+        };
+        metaList.add(compositeMeta0);
+        metaList.add(compositeMeta1);
+        metaList.add(new VertxRestAccessLogItemMeta("%{", null, null));
+        return metaList;
       }
     };
 
     VertxRestAccessLogPatternParser parser = new VertxRestAccessLogPatternParser();
 
-    List<AccessLogItemMetaWrapper> accessLogItemMetaWrappers =
-        Deencapsulation.getField(parser, "accessLogItemMetaWrappers");
+    List<VertxRestAccessLogItemMeta> accessLogItemMetaList =
+        Deencapsulation.getField(parser, "metaList");
 
-    assertEquals(7, accessLogItemMetaWrappers.size());
-    assertEquals("%_", accessLogItemMetaWrappers.get(0).getPrefix());
-    assertEquals("%a", accessLogItemMetaWrappers.get(1).getPrefix());
-    assertEquals("}abc", accessLogItemMetaWrappers.get(1).getSuffix());
-    assertEquals("%{", accessLogItemMetaWrappers.get(2).getPrefix());
-    assertEquals("}abc", accessLogItemMetaWrappers.get(2).getSuffix());
-    assertEquals("%{", accessLogItemMetaWrappers.get(3).getPrefix());
-    assertEquals("}a", accessLogItemMetaWrappers.get(3).getSuffix());
-    assertEquals("%m", accessLogItemMetaWrappers.get(4).getPrefix());
-    assertNull(accessLogItemMetaWrappers.get(4).getSuffix());
-    assertEquals("%{", accessLogItemMetaWrappers.get(5).getPrefix());
-    assertNull(accessLogItemMetaWrappers.get(5).getSuffix());
-    assertEquals("%0", accessLogItemMetaWrappers.get(6).getPrefix());
-    assertEquals("}abc", accessLogItemMetaWrappers.get(6).getSuffix());
+    assertEquals(7, accessLogItemMetaList.size());
+    assertEquals("%_", accessLogItemMetaList.get(0).getPrefix());
+    assertEquals("%a", accessLogItemMetaList.get(1).getPrefix());
+    assertEquals("}abc", accessLogItemMetaList.get(1).getSuffix());
+    assertEquals("%{", accessLogItemMetaList.get(2).getPrefix());
+    assertEquals("}abc", accessLogItemMetaList.get(2).getSuffix());
+    assertEquals("%{", accessLogItemMetaList.get(3).getPrefix());
+    assertEquals("}a", accessLogItemMetaList.get(3).getSuffix());
+    assertEquals("%m", accessLogItemMetaList.get(4).getPrefix());
+    assertNull(accessLogItemMetaList.get(4).getSuffix());
+    assertEquals("%{", accessLogItemMetaList.get(5).getPrefix());
+    assertNull(accessLogItemMetaList.get(5).getSuffix());
+    assertEquals("%0", accessLogItemMetaList.get(6).getPrefix());
+    assertEquals("}abc", accessLogItemMetaList.get(6).getSuffix());
   }
 }
diff --git a/transports/transport-rest/transport-rest-vertx/src/main/resources/META-INF/services/org.apache.servicecomb.transport.rest.vertx.accesslog.parser.VertxRestAccessLogItemCreator b/transports/transport-rest/transport-rest-vertx/src/test/resources/META-INF/services/org.apache.servicecomb.transport.rest.vertx.accesslog.parser.VertxRestAccessLogItemMeta
similarity index 85%
rename from transports/transport-rest/transport-rest-vertx/src/main/resources/META-INF/services/org.apache.servicecomb.transport.rest.vertx.accesslog.parser.VertxRestAccessLogItemCreator
rename to transports/transport-rest/transport-rest-vertx/src/test/resources/META-INF/services/org.apache.servicecomb.transport.rest.vertx.accesslog.parser.VertxRestAccessLogItemMeta
index 92e596a..b539f7c 100644
--- a/transports/transport-rest/transport-rest-vertx/src/main/resources/META-INF/services/org.apache.servicecomb.transport.rest.vertx.accesslog.parser.VertxRestAccessLogItemCreator
+++ b/transports/transport-rest/transport-rest-vertx/src/test/resources/META-INF/services/org.apache.servicecomb.transport.rest.vertx.accesslog.parser.VertxRestAccessLogItemMeta
@@ -15,4 +15,5 @@
 # limitations under the License.
 #
 
-org.apache.servicecomb.transport.rest.vertx.accesslog.parser.impl.DefaultAccessLogItemCreator
\ No newline at end of file
+org.apache.servicecomb.transport.rest.vertx.accesslog.parser.impl.TestSingleExtendedAccessLogItemMeta
+org.apache.servicecomb.transport.rest.vertx.accesslog.parser.impl.TestCompositeExtendedAccessLogItemMeta
\ No newline at end of file

-- 
To stop receiving notification emails like this one, please contact
wujimin@apache.org.

[incubator-servicecomb-java-chassis] 05/06: [SCB-616] make VertxRestAccessLogItemCreator extensible

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

wujimin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-servicecomb-java-chassis.git

commit 2b15544f8a7f0532180dbb1b8f20742b76328da2
Author: yaohaishi <ya...@huawei.com>
AuthorDate: Tue May 29 15:38:14 2018 +0800

    [SCB-616] make VertxRestAccessLogItemCreator extensible
---
 .../impl/VertxRestAccessLogPatternParser.java      | 21 ++++--
 ....accesslog.parser.VertxRestAccessLogItemCreator | 18 ++++++
 .../impl/VertxRestAccessLogPatternParserTest.java  | 74 ++++++++++++++++++++++
 3 files changed, 109 insertions(+), 4 deletions(-)

diff --git a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/VertxRestAccessLogPatternParser.java b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/VertxRestAccessLogPatternParser.java
index f299426..69776cc 100644
--- a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/VertxRestAccessLogPatternParser.java
+++ b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/VertxRestAccessLogPatternParser.java
@@ -22,11 +22,14 @@ import java.util.Comparator;
 import java.util.Iterator;
 import java.util.List;
 
+import org.apache.servicecomb.foundation.common.utils.SPIServiceUtils;
 import org.apache.servicecomb.transport.rest.vertx.accesslog.element.AccessLogItem;
 import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.PlainTextItem;
 import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.AccessLogItemMeta;
 import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.AccessLogPatternParser;
 import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.VertxRestAccessLogItemCreator;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import io.vertx.ext.web.RoutingContext;
 
@@ -34,6 +37,8 @@ import io.vertx.ext.web.RoutingContext;
  * The parser is used for rest-over-vertx transport.
  */
 public class VertxRestAccessLogPatternParser implements AccessLogPatternParser<RoutingContext> {
+  private static final Logger LOGGER = LoggerFactory.getLogger(VertxRestAccessLogPatternParser.class);
+
   public static final Comparator<AccessLogItemMetaWrapper> accessLogItemMetaWrapperComparator = (w1, w2) -> {
     AccessLogItemMeta meta1 = w1.getAccessLogItemMeta();
     AccessLogItemMeta meta2 = w2.getAccessLogItemMeta();
@@ -56,13 +61,17 @@ public class VertxRestAccessLogPatternParser implements AccessLogPatternParser<R
         : result;
   };
 
-  private List<VertxRestAccessLogItemCreator> creators = new ArrayList<>();
+  private List<VertxRestAccessLogItemCreator> creators;
 
   private List<AccessLogItemMetaWrapper> accessLogItemMetaWrappers = new ArrayList<>();
 
   public VertxRestAccessLogPatternParser() {
-    creators.add(new DefaultAccessLogItemCreator());
-    for (VertxRestAccessLogItemCreator creator : creators) {
+    List<VertxRestAccessLogItemCreator> creators = loadVertxRestAccessLogItemCreators();
+    this.creators = creators;
+    if (null == creators) {
+      LOGGER.error("cannot load VertxRestAccessLogItemCreator!");
+    }
+    for (VertxRestAccessLogItemCreator creator : this.creators) {
       for (AccessLogItemMeta accessLogItemMeta : creator.getAccessLogItemMeta()) {
         accessLogItemMetaWrappers.add(new AccessLogItemMetaWrapper(accessLogItemMeta, creator));
       }
@@ -70,6 +79,10 @@ public class VertxRestAccessLogPatternParser implements AccessLogPatternParser<R
     sortAccessLogItemMetaWrapper(accessLogItemMetaWrappers);
   }
 
+  private List<VertxRestAccessLogItemCreator> loadVertxRestAccessLogItemCreators() {
+    return SPIServiceUtils.getOrLoadSortedService(VertxRestAccessLogItemCreator.class);
+  }
+
   /**
    * Behavior of this compare:
    * 1. comparePlaceholderString("abc","bbc") < 0
@@ -135,6 +148,7 @@ public class VertxRestAccessLogPatternParser implements AccessLogPatternParser<R
    */
   @Override
   public List<AccessLogItem<RoutingContext>> parsePattern(String rawPattern) {
+    LOGGER.info("parse the pattern of access log: [{}]", rawPattern);
     List<AccessLogItemLocation> locationList = matchAccessLogItem(rawPattern);
     locationList = fillInPlainTextLocation(rawPattern, locationList);
 
@@ -364,4 +378,3 @@ public class VertxRestAccessLogPatternParser implements AccessLogPatternParser<R
     }
   }
 }
-
diff --git a/transports/transport-rest/transport-rest-vertx/src/main/resources/META-INF/services/org.apache.servicecomb.transport.rest.vertx.accesslog.parser.VertxRestAccessLogItemCreator b/transports/transport-rest/transport-rest-vertx/src/main/resources/META-INF/services/org.apache.servicecomb.transport.rest.vertx.accesslog.parser.VertxRestAccessLogItemCreator
new file mode 100644
index 0000000..92e596a
--- /dev/null
+++ b/transports/transport-rest/transport-rest-vertx/src/main/resources/META-INF/services/org.apache.servicecomb.transport.rest.vertx.accesslog.parser.VertxRestAccessLogItemCreator
@@ -0,0 +1,18 @@
+#
+# 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.
+#
+
+org.apache.servicecomb.transport.rest.vertx.accesslog.parser.impl.DefaultAccessLogItemCreator
\ No newline at end of file
diff --git a/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/VertxRestAccessLogPatternParserTest.java b/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/VertxRestAccessLogPatternParserTest.java
index 0cfd2cd..57e9100 100644
--- a/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/VertxRestAccessLogPatternParserTest.java
+++ b/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/VertxRestAccessLogPatternParserTest.java
@@ -18,7 +18,9 @@
 package org.apache.servicecomb.transport.rest.vertx.accesslog.parser.impl;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
 
+import java.util.ArrayList;
 import java.util.Comparator;
 import java.util.List;
 import java.util.Locale;
@@ -46,11 +48,15 @@ import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.TraceI
 import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.UrlPathItem;
 import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.UrlPathWithQueryItem;
 import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.AccessLogItemMeta;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.VertxRestAccessLogItemCreator;
 import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.impl.VertxRestAccessLogPatternParser.AccessLogItemMetaWrapper;
 import org.junit.Assert;
 import org.junit.Test;
 
 import io.vertx.ext.web.RoutingContext;
+import mockit.Deencapsulation;
+import mockit.Mock;
+import mockit.MockUp;
 
 public class VertxRestAccessLogPatternParserTest {
   private static final String ROW_PATTERN = "[cs-method] %m %s%T%D%h%v%p%B%b%r%U%q"
@@ -262,4 +268,72 @@ public class VertxRestAccessLogPatternParserTest {
         VertxRestAccessLogPatternParser.comparePlaceholderString("ab", "abc") > 0
     );
   }
+
+  @Test
+  public void testExtendedVertxRestAccessLogItemCreator() {
+    final List<AccessLogItemMeta> metaList0 = new ArrayList<>();
+    metaList0.add(new AccessLogItemMeta("%{", "}abc"));
+    metaList0.add(new AccessLogItemMeta("%{", "}a"));
+    metaList0.add(new AccessLogItemMeta("%{", null));
+    metaList0.add(new AccessLogItemMeta("%_", null, -1));
+
+    final List<AccessLogItemMeta> metaList1 = new ArrayList<>();
+    metaList0.add(new AccessLogItemMeta("%a", "}abc"));
+    metaList0.add(new AccessLogItemMeta("%0", "}abc", 1));
+    metaList0.add(new AccessLogItemMeta("%m", null));
+
+    final VertxRestAccessLogItemCreator accessLogItemCreator0 = new VertxRestAccessLogItemCreator() {
+      @Override
+      public List<AccessLogItemMeta> getAccessLogItemMeta() {
+        return metaList0;
+      }
+
+      @Override
+      public AccessLogItem<RoutingContext> createItem(AccessLogItemMeta accessLogItemMeta, String config) {
+        return null;
+      }
+    };
+
+    final VertxRestAccessLogItemCreator accessLogItemCreator1 = new VertxRestAccessLogItemCreator() {
+      @Override
+      public List<AccessLogItemMeta> getAccessLogItemMeta() {
+        return metaList1;
+      }
+
+      @Override
+      public AccessLogItem<RoutingContext> createItem(AccessLogItemMeta accessLogItemMeta, String config) {
+        return null;
+      }
+    };
+
+    new MockUp<VertxRestAccessLogPatternParser>() {
+      @Mock
+      List<VertxRestAccessLogItemCreator> loadVertxRestAccessLogItemCreators() {
+        List<VertxRestAccessLogItemCreator> creators = new ArrayList<>(1);
+        creators.add(accessLogItemCreator0);
+        creators.add(accessLogItemCreator1);
+        return creators;
+      }
+    };
+
+    VertxRestAccessLogPatternParser parser = new VertxRestAccessLogPatternParser();
+
+    List<AccessLogItemMetaWrapper> accessLogItemMetaWrappers =
+        Deencapsulation.getField(parser, "accessLogItemMetaWrappers");
+
+    assertEquals(7, accessLogItemMetaWrappers.size());
+    assertEquals("%_", accessLogItemMetaWrappers.get(0).getPrefix());
+    assertEquals("%a", accessLogItemMetaWrappers.get(1).getPrefix());
+    assertEquals("}abc", accessLogItemMetaWrappers.get(1).getSuffix());
+    assertEquals("%{", accessLogItemMetaWrappers.get(2).getPrefix());
+    assertEquals("}abc", accessLogItemMetaWrappers.get(2).getSuffix());
+    assertEquals("%{", accessLogItemMetaWrappers.get(3).getPrefix());
+    assertEquals("}a", accessLogItemMetaWrappers.get(3).getSuffix());
+    assertEquals("%m", accessLogItemMetaWrappers.get(4).getPrefix());
+    assertNull(accessLogItemMetaWrappers.get(4).getSuffix());
+    assertEquals("%{", accessLogItemMetaWrappers.get(5).getPrefix());
+    assertNull(accessLogItemMetaWrappers.get(5).getSuffix());
+    assertEquals("%0", accessLogItemMetaWrappers.get(6).getPrefix());
+    assertEquals("}abc", accessLogItemMetaWrappers.get(6).getSuffix());
+  }
 }

-- 
To stop receiving notification emails like this one, please contact
wujimin@apache.org.

[incubator-servicecomb-java-chassis] 04/06: [SCB-616] finish parse logic refactor

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

wujimin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-servicecomb-java-chassis.git

commit 34cf795db6383e125f2802bd555dc3b6d42fef1d
Author: yaohaishi <ya...@huawei.com>
AuthorDate: Sun May 27 22:34:13 2018 +0800

    [SCB-616] finish parse logic refactor
---
 .../rest/vertx/accesslog/AccessLogGenerator.java   |   9 +-
 .../accesslog/element/impl/ResponseSizeItem.java   |   4 +
 .../parser/impl/DefaultAccessLogItemCreator.java   | 137 ++++++++++++
 .../impl/VertxRestAccessLogPatternParser.java      | 232 +++++++++++++++++++--
 .../impl/VertxRestAccessLogPatternParserTest.java  | 136 ++++++++++++
 5 files changed, 505 insertions(+), 13 deletions(-)

diff --git a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/AccessLogGenerator.java b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/AccessLogGenerator.java
index f05e8d4..a2079eb 100644
--- a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/AccessLogGenerator.java
+++ b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/AccessLogGenerator.java
@@ -17,7 +17,11 @@
 
 package org.apache.servicecomb.transport.rest.vertx.accesslog;
 
+import java.util.List;
+
 import org.apache.servicecomb.transport.rest.vertx.accesslog.element.AccessLogItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.AccessLogPatternParser;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.impl.VertxRestAccessLogPatternParser;
 
 import io.vertx.ext.web.RoutingContext;
 
@@ -32,9 +36,12 @@ public class AccessLogGenerator {
    */
   private AccessLogItem<RoutingContext>[] accessLogItems;
 
+  private AccessLogPatternParser<RoutingContext> accessLogPatternParser = new VertxRestAccessLogPatternParser();
+
   @SuppressWarnings("unchecked")
   public AccessLogGenerator(String rawPattern) {
-    accessLogItems = new AccessLogItem[0];
+    List<AccessLogItem<RoutingContext>> accessLogItemList = accessLogPatternParser.parsePattern(rawPattern);
+    accessLogItems = accessLogItemList.toArray(new AccessLogItem[0]);
   }
 
   public String generateLog(AccessLogParam<RoutingContext> accessLogParam) {
diff --git a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/impl/ResponseSizeItem.java b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/impl/ResponseSizeItem.java
index 0d58226..cb43bd5 100644
--- a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/impl/ResponseSizeItem.java
+++ b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/impl/ResponseSizeItem.java
@@ -41,4 +41,8 @@ public class ResponseSizeItem implements AccessLogItem<RoutingContext> {
     long bytesWritten = response.bytesWritten();
     return 0 == bytesWritten ? zeroBytes : String.valueOf(bytesWritten);
   }
+
+  public String getZeroBytes() {
+    return zeroBytes;
+  }
 }
diff --git a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/DefaultAccessLogItemCreator.java b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/DefaultAccessLogItemCreator.java
new file mode 100644
index 0000000..6a2a6fd
--- /dev/null
+++ b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/DefaultAccessLogItemCreator.java
@@ -0,0 +1,137 @@
+/*
+ * 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.servicecomb.transport.rest.vertx.accesslog.parser.impl;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.AccessLogItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.CookieItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.DatetimeConfigurableItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.DurationMillisecondItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.DurationSecondItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.FirstLineOfRequestItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.HttpMethodItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.HttpStatusItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.InvocationContextItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.LocalHostItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.LocalPortItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.QueryStringItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.RemoteHostItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.RequestHeaderItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.RequestProtocolItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.ResponseHeaderItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.ResponseSizeItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.TraceIdItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.UrlPathItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.UrlPathWithQueryItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.AccessLogItemMeta;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.VertxRestAccessLogItemCreator;
+
+import io.vertx.ext.web.RoutingContext;
+
+public class DefaultAccessLogItemCreator implements VertxRestAccessLogItemCreator {
+  private static final Map<String, AccessLogItem<RoutingContext>> SIMPLE_ACCESS_LOG_ITEM_MAP = new HashMap<>();
+
+  private static final List<AccessLogItemMeta> SUPPORTED_META_LIST = new ArrayList<>();
+
+  static {
+    AccessLogItem<RoutingContext> item = new HttpMethodItem();
+    SIMPLE_ACCESS_LOG_ITEM_MAP.put("%m", item);
+    SIMPLE_ACCESS_LOG_ITEM_MAP.put("cs-method", item);
+    item = new HttpStatusItem();
+    SIMPLE_ACCESS_LOG_ITEM_MAP.put("%s", item);
+    SIMPLE_ACCESS_LOG_ITEM_MAP.put("sc-status", item);
+    SIMPLE_ACCESS_LOG_ITEM_MAP.put("%T", new DurationSecondItem());
+    SIMPLE_ACCESS_LOG_ITEM_MAP.put("%D", new DurationMillisecondItem());
+    SIMPLE_ACCESS_LOG_ITEM_MAP.put("%h", new RemoteHostItem());
+    SIMPLE_ACCESS_LOG_ITEM_MAP.put("%v", new LocalHostItem());
+    SIMPLE_ACCESS_LOG_ITEM_MAP.put("%p", new LocalPortItem());
+    SIMPLE_ACCESS_LOG_ITEM_MAP.put("%B", new ResponseSizeItem("0"));
+    SIMPLE_ACCESS_LOG_ITEM_MAP.put("%b", new ResponseSizeItem("-"));
+    SIMPLE_ACCESS_LOG_ITEM_MAP.put("%r", new FirstLineOfRequestItem());
+    item = new UrlPathItem();
+    SIMPLE_ACCESS_LOG_ITEM_MAP.put("%U", item);
+    SIMPLE_ACCESS_LOG_ITEM_MAP.put("cs-uri-stem", item);
+    item = new QueryStringItem();
+    SIMPLE_ACCESS_LOG_ITEM_MAP.put("%q", item);
+    SIMPLE_ACCESS_LOG_ITEM_MAP.put("cs-uri-query", item);
+    SIMPLE_ACCESS_LOG_ITEM_MAP.put("cs-uri", new UrlPathWithQueryItem());
+    SIMPLE_ACCESS_LOG_ITEM_MAP.put("%H", new RequestProtocolItem());
+    SIMPLE_ACCESS_LOG_ITEM_MAP.put("%t", new DatetimeConfigurableItem());
+    SIMPLE_ACCESS_LOG_ITEM_MAP.put("%SCB-traceId", new TraceIdItem());
+
+    SUPPORTED_META_LIST.add(new AccessLogItemMeta("%m", null));
+    SUPPORTED_META_LIST.add(new AccessLogItemMeta("cs-method", null));
+    SUPPORTED_META_LIST.add(new AccessLogItemMeta("%s", null));
+    SUPPORTED_META_LIST.add(new AccessLogItemMeta("sc-status", null));
+    SUPPORTED_META_LIST.add(new AccessLogItemMeta("%T", null));
+    SUPPORTED_META_LIST.add(new AccessLogItemMeta("%D", null));
+    SUPPORTED_META_LIST.add(new AccessLogItemMeta("%h", null));
+    SUPPORTED_META_LIST.add(new AccessLogItemMeta("%v", null));
+    SUPPORTED_META_LIST.add(new AccessLogItemMeta("%p", null));
+    SUPPORTED_META_LIST.add(new AccessLogItemMeta("%B", null));
+    SUPPORTED_META_LIST.add(new AccessLogItemMeta("%b", null));
+    SUPPORTED_META_LIST.add(new AccessLogItemMeta("%r", null));
+    SUPPORTED_META_LIST.add(new AccessLogItemMeta("%U", null));
+    SUPPORTED_META_LIST.add(new AccessLogItemMeta("cs-uri-stem", null));
+    SUPPORTED_META_LIST.add(new AccessLogItemMeta("%q", null));
+    SUPPORTED_META_LIST.add(new AccessLogItemMeta("cs-uri-query", null));
+    SUPPORTED_META_LIST.add(new AccessLogItemMeta("cs-uri", null));
+    SUPPORTED_META_LIST.add(new AccessLogItemMeta("%H", null));
+    SUPPORTED_META_LIST.add(new AccessLogItemMeta("%t", null));
+    SUPPORTED_META_LIST.add(new AccessLogItemMeta("%SCB-traceId", null));
+    SUPPORTED_META_LIST.add(new AccessLogItemMeta("%{", "}t"));
+    SUPPORTED_META_LIST.add(new AccessLogItemMeta("%{", "}i"));
+    SUPPORTED_META_LIST.add(new AccessLogItemMeta("%{", "}o"));
+    SUPPORTED_META_LIST.add(new AccessLogItemMeta("%{", "}C"));
+    SUPPORTED_META_LIST.add(new AccessLogItemMeta("%{", "}SCB-ctx"));
+  }
+
+  @Override
+  public AccessLogItem<RoutingContext> createItem(AccessLogItemMeta accessLogItemMeta, String config) {
+    if (null == accessLogItemMeta.getSuffix()) {
+      // For the simple AccessLogItem
+      return SIMPLE_ACCESS_LOG_ITEM_MAP.get(accessLogItemMeta.getPrefix());
+    }
+
+    // For the configurable AccessLogItem
+    switch (accessLogItemMeta.getSuffix()) {
+      case "}t":
+        return new DatetimeConfigurableItem(config);
+      case "}i":
+        return new RequestHeaderItem(config);
+      case "}o":
+        return new ResponseHeaderItem(config);
+      case "}C":
+        return new CookieItem(config);
+      case "}SCB-ctx":
+        return new InvocationContextItem(config);
+      default:
+        // unexpected situation
+        return null;
+    }
+  }
+
+  @Override
+  public List<AccessLogItemMeta> getAccessLogItemMeta() {
+    return SUPPORTED_META_LIST;
+  }
+}
diff --git a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/VertxRestAccessLogPatternParser.java b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/VertxRestAccessLogPatternParser.java
index 5295f10..f299426 100644
--- a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/VertxRestAccessLogPatternParser.java
+++ b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/VertxRestAccessLogPatternParser.java
@@ -19,9 +19,11 @@ package org.apache.servicecomb.transport.rest.vertx.accesslog.parser.impl;
 
 import java.util.ArrayList;
 import java.util.Comparator;
+import java.util.Iterator;
 import java.util.List;
 
 import org.apache.servicecomb.transport.rest.vertx.accesslog.element.AccessLogItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.PlainTextItem;
 import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.AccessLogItemMeta;
 import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.AccessLogPatternParser;
 import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.VertxRestAccessLogItemCreator;
@@ -59,6 +61,7 @@ public class VertxRestAccessLogPatternParser implements AccessLogPatternParser<R
   private List<AccessLogItemMetaWrapper> accessLogItemMetaWrappers = new ArrayList<>();
 
   public VertxRestAccessLogPatternParser() {
+    creators.add(new DefaultAccessLogItemCreator());
     for (VertxRestAccessLogItemCreator creator : creators) {
       for (AccessLogItemMeta accessLogItemMeta : creator.getAccessLogItemMeta()) {
         accessLogItemMetaWrappers.add(new AccessLogItemMetaWrapper(accessLogItemMeta, creator));
@@ -89,17 +92,6 @@ public class VertxRestAccessLogPatternParser implements AccessLogPatternParser<R
   }
 
   /**
-   * @param rawPattern The access log pattern string specified by users.
-   * @return A list of {@linkplain AccessLogItem} which actually generate the content of access log.
-   */
-  @Override
-  public List<AccessLogItem<RoutingContext>> parsePattern(String rawPattern) {
-    List<AccessLogItem<RoutingContext>> itemList = new ArrayList<>();
-    // the algorithm is unimplemented.
-    return itemList;
-  }
-
-  /**
    * Sort all of the {@link AccessLogItemMetaWrapper}, the wrapper that is in front of the others has higher priority.
    * <p/>
    * Sort rule(priority decreased):
@@ -133,10 +125,217 @@ public class VertxRestAccessLogPatternParser implements AccessLogPatternParser<R
    * <li>(%b,)</li>
    * </ol>
    */
-  private void sortAccessLogItemMetaWrapper(List<AccessLogItemMetaWrapper> accessLogItemMetaWrapperList) {
+  public static void sortAccessLogItemMetaWrapper(List<AccessLogItemMetaWrapper> accessLogItemMetaWrapperList) {
     accessLogItemMetaWrapperList.sort(accessLogItemMetaWrapperComparator);
   }
 
+  /**
+   * @param rawPattern The access log pattern string specified by users.
+   * @return A list of {@linkplain AccessLogItem} which actually generate the content of access log.
+   */
+  @Override
+  public List<AccessLogItem<RoutingContext>> parsePattern(String rawPattern) {
+    List<AccessLogItemLocation> locationList = matchAccessLogItem(rawPattern);
+    locationList = fillInPlainTextLocation(rawPattern, locationList);
+
+    return convertToItemList(rawPattern, locationList);
+  }
+
+  /**
+   * Use the {@link #accessLogItemMetaWrappers} to match rawPattern.
+   * Return a list of {@link AccessLogItemLocation}.
+   * Plain text is ignored.
+   */
+  private List<AccessLogItemLocation> matchAccessLogItem(String rawPattern) {
+    List<AccessLogItemLocation> locationList = new ArrayList<>();
+    int cursor = 0;
+    while (cursor < rawPattern.length()) {
+      AccessLogItemLocation candidate = null;
+      for (AccessLogItemMetaWrapper wrapper : accessLogItemMetaWrappers) {
+        if (null != candidate && null == wrapper.getSuffix()) {
+          // TODO:
+          // if user define item("%{","}ab") and item("%{_","}abc") and the pattern is "%{_var}ab}abc"
+          // currently the result is item("%{","_var","}ab"), plaintext("}abc")
+          // is this acceptable?
+
+          // We've gotten an AccessLogItem with suffix, so there is no need to match those without suffix,
+          // just break this match loop
+          cursor = candidate.tail;
+          break;
+        }
+        if (rawPattern.startsWith(wrapper.getPrefix(), cursor)) {
+          if (null == wrapper.getSuffix()) {
+            // for simple type AccessLogItem, there is no need to try to match the next item.
+            candidate = new AccessLogItemLocation(cursor, wrapper);
+            cursor = candidate.tail;
+            break;
+          }
+          // for configurable type, like %{...}i, more check is needed
+          // e.g. "%{varName1}o ${varName2}i" should be divided into
+          // ResponseHeaderItem with varName="varName1" and RequestHeaderItem with varName="varName2"
+          // INSTEAD OF RequestHeaderItem with varName="varName1}o ${varName2"
+          int rear = rawPattern.indexOf(wrapper.getSuffix(), cursor);
+          if (rear < 0) {
+            continue;
+          }
+          if (null == candidate || rear < candidate.suffixIndex) {
+            candidate = new AccessLogItemLocation(cursor, rear, wrapper);
+          }
+          // There is a matched item which is in front of this item, so this item is ignored.
+        }
+      }
+
+      if (candidate == null) {
+        ++cursor;
+        continue;
+      }
+      locationList.add(candidate);
+    }
+
+    return locationList;
+  }
+
+  /**
+   * After processing of {@link #matchAccessLogItem(String)}, all of the placeholders of {@link AccessLogItem} have been
+   * picked out. So the rest part of rawPattern should be treated as plain text. Those parts will be located in this
+   * method and wrapped as {@link PlainTextItem}.
+   * @param rawPattern raw pattern string of access log
+   * @param locationList locations picked out by {@link #matchAccessLogItem(String)}
+   * @return all of the locations including {@link PlainTextItem}.
+   */
+  private List<AccessLogItemLocation> fillInPlainTextLocation(String rawPattern,
+      List<AccessLogItemLocation> locationList) {
+    List<AccessLogItemLocation> resultList = new ArrayList<>();
+    if (locationList.isEmpty()) {
+      resultList.add(createTextPlainItemLocation(0, rawPattern.length()));
+      return resultList;
+    }
+
+    Iterator<AccessLogItemLocation> itemLocationIterator = locationList.iterator();
+    AccessLogItemLocation previousItemLocation = itemLocationIterator.next();
+    if (previousItemLocation.prefixIndex > 0) {
+      resultList.add(createTextPlainItemLocation(0, previousItemLocation.prefixIndex));
+    }
+    resultList.add(previousItemLocation);
+
+    while (itemLocationIterator.hasNext()) {
+      AccessLogItemLocation thisItemLocation = itemLocationIterator.next();
+      if (previousItemLocation.tail < thisItemLocation.prefixIndex) {
+        resultList.add(createTextPlainItemLocation(previousItemLocation.tail, thisItemLocation.prefixIndex));
+      }
+      previousItemLocation = thisItemLocation;
+      resultList.add(previousItemLocation);
+    }
+
+    if (previousItemLocation.tail < rawPattern.length()) {
+      resultList.add(createTextPlainItemLocation(
+          previousItemLocation.tail,
+          rawPattern.length()));
+    }
+    return resultList;
+  }
+
+  private AccessLogItemLocation createTextPlainItemLocation(int front, int rear) {
+    return new AccessLogItemLocation(front, rear);
+  }
+
+  private List<AccessLogItem<RoutingContext>> convertToItemList(String rawPattern,
+      List<AccessLogItemLocation> locationList) {
+    List<AccessLogItem<RoutingContext>> itemList = new ArrayList<>();
+
+    for (AccessLogItemLocation accessLogItemLocation : locationList) {
+      AccessLogItemMetaWrapper accessLogItemMetaWrapper = accessLogItemLocation.accessLogItemMetaWrapper;
+      if (null == accessLogItemMetaWrapper) {
+        // a PlainTextItem location
+        itemList.add(new PlainTextItem(rawPattern.substring(
+            accessLogItemLocation.prefixIndex, accessLogItemLocation.tail
+        )));
+        continue;
+      }
+
+      itemList.add(
+          accessLogItemMetaWrapper.getVertxRestAccessLogItemCreator().createItem(
+              accessLogItemMetaWrapper.getAccessLogItemMeta(),
+              getConfigString(rawPattern, accessLogItemLocation))
+      );
+    }
+
+    return itemList;
+  }
+
+  private String getConfigString(String rawPattern, AccessLogItemLocation accessLogItemLocation) {
+    if (null == accessLogItemLocation.getSuffix()) {
+      // simple AccessLogItem
+      return null;
+    }
+
+    return rawPattern.substring(
+        accessLogItemLocation.prefixIndex + accessLogItemLocation.getPrefix().length(),
+        accessLogItemLocation.suffixIndex);
+  }
+
+  private static class AccessLogItemLocation {
+    /**
+     * prefixIndex = rawPattern.indexOf(prefix)
+     */
+    int prefixIndex;
+
+    /**
+     * suffixIndex = rawPattern.indexOf(suffix)
+     */
+    int suffixIndex;
+
+    /**
+     * tail = suffixIndex + suffix.length()
+     */
+    int tail;
+
+    AccessLogItemMetaWrapper accessLogItemMetaWrapper;
+
+    /**
+     * for {@link PlainTextItem} only
+     */
+    AccessLogItemLocation(int prefixIndex, int suffixIndex) {
+      this.prefixIndex = prefixIndex;
+      this.suffixIndex = suffixIndex;
+      this.tail = suffixIndex;
+    }
+
+    /**
+     * for configurable type AccessLogItem
+     */
+    AccessLogItemLocation(int prefixIndex, int suffixIndex, AccessLogItemMetaWrapper accessLogItemMetaWrapper) {
+      this.prefixIndex = prefixIndex;
+      this.suffixIndex = suffixIndex;
+      this.tail = suffixIndex + accessLogItemMetaWrapper.getSuffix().length();
+      this.accessLogItemMetaWrapper = accessLogItemMetaWrapper;
+    }
+
+    /**
+     * for simple type AccessLogItem
+     */
+    AccessLogItemLocation(int prefixIndex, AccessLogItemMetaWrapper accessLogItemMetaWrapper) {
+      this.prefixIndex = prefixIndex;
+      this.suffixIndex = prefixIndex + accessLogItemMetaWrapper.getPrefix().length();
+      this.tail = this.suffixIndex;
+      this.accessLogItemMetaWrapper = accessLogItemMetaWrapper;
+    }
+
+    public String getPrefix() {
+      if (null == accessLogItemMetaWrapper) {
+        return null;
+      }
+      return accessLogItemMetaWrapper.getPrefix();
+    }
+
+    public String getSuffix() {
+      if (null == accessLogItemMetaWrapper) {
+        return null;
+      }
+      return accessLogItemMetaWrapper.getSuffix();
+    }
+  }
+
   public static class AccessLogItemMetaWrapper {
     private AccessLogItemMeta accessLogItemMeta;
 
@@ -155,5 +354,14 @@ public class VertxRestAccessLogPatternParser implements AccessLogPatternParser<R
     public VertxRestAccessLogItemCreator getVertxRestAccessLogItemCreator() {
       return vertxRestAccessLogItemCreator;
     }
+
+    public String getPrefix() {
+      return accessLogItemMeta.getPrefix();
+    }
+
+    public String getSuffix() {
+      return accessLogItemMeta.getSuffix();
+    }
   }
 }
+
diff --git a/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/VertxRestAccessLogPatternParserTest.java b/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/VertxRestAccessLogPatternParserTest.java
index 2fdcc2d..0cfd2cd 100644
--- a/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/VertxRestAccessLogPatternParserTest.java
+++ b/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/VertxRestAccessLogPatternParserTest.java
@@ -17,15 +17,151 @@
 
 package org.apache.servicecomb.transport.rest.vertx.accesslog.parser.impl;
 
+import static org.junit.Assert.assertEquals;
+
 import java.util.Comparator;
+import java.util.List;
+import java.util.Locale;
+import java.util.TimeZone;
 import java.util.function.Function;
 
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.AccessLogItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.CookieItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.DatetimeConfigurableItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.DurationMillisecondItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.DurationSecondItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.FirstLineOfRequestItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.HttpMethodItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.HttpStatusItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.InvocationContextItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.LocalHostItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.LocalPortItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.QueryStringItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.RemoteHostItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.RequestHeaderItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.RequestProtocolItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.ResponseHeaderItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.ResponseSizeItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.TraceIdItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.UrlPathItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.UrlPathWithQueryItem;
 import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.AccessLogItemMeta;
 import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.impl.VertxRestAccessLogPatternParser.AccessLogItemMetaWrapper;
 import org.junit.Assert;
 import org.junit.Test;
 
+import io.vertx.ext.web.RoutingContext;
+
 public class VertxRestAccessLogPatternParserTest {
+  private static final String ROW_PATTERN = "[cs-method] %m %s%T%D%h%v%p%B%b%r%U%q"
+      + "cs-uri-stemcs-uri-querycs-uri%H%t%{yyyy MM dd HH:mm:ss zzz}t"
+      + "%{yyyy MM dd HH:mm:ss|GMT+0|en-US}t"
+      + "%{incoming-header}i"
+      + "%{outgoing-header}o"
+      + "%{cookie}C"
+      + "%SCB-traceId"
+      + "%{ctx}SCB-ctx";
+
+  private static VertxRestAccessLogPatternParser accessLogPatternParser = new VertxRestAccessLogPatternParser();
+
+  @Test
+  public void testParsePatternFullTest() {
+    List<AccessLogItem<RoutingContext>> result = accessLogPatternParser.parsePattern(ROW_PATTERN);
+    assertEquals(28, result.size());
+
+    assertEquals("[", result.get(0).getFormattedItem(null));
+    assertEquals(HttpMethodItem.class, result.get(1).getClass());
+    assertEquals("] ", result.get(2).getFormattedItem(null));
+    assertEquals(HttpMethodItem.class, result.get(3).getClass());
+    assertEquals(" ", result.get(4).getFormattedItem(null));
+    assertEquals(HttpStatusItem.class, result.get(5).getClass());
+    assertEquals(DurationSecondItem.class, result.get(6).getClass());
+    assertEquals(DurationMillisecondItem.class, result.get(7).getClass());
+    assertEquals(RemoteHostItem.class, result.get(8).getClass());
+    assertEquals(LocalHostItem.class, result.get(9).getClass());
+    assertEquals(LocalPortItem.class, result.get(10).getClass());
+    assertEquals(ResponseSizeItem.class, result.get(11).getClass());
+    assertEquals("0", ((ResponseSizeItem) result.get(11)).getZeroBytes());
+    assertEquals(ResponseSizeItem.class, result.get(12).getClass());
+    assertEquals("-", ((ResponseSizeItem) result.get(12)).getZeroBytes());
+    assertEquals(FirstLineOfRequestItem.class, result.get(13).getClass());
+    assertEquals(UrlPathItem.class, result.get(14).getClass());
+    assertEquals(QueryStringItem.class, result.get(15).getClass());
+    assertEquals(UrlPathItem.class, result.get(16).getClass());
+    assertEquals(QueryStringItem.class, result.get(17).getClass());
+    assertEquals(UrlPathWithQueryItem.class, result.get(18).getClass());
+    assertEquals(RequestProtocolItem.class, result.get(19).getClass());
+    assertEquals(DatetimeConfigurableItem.class, result.get(20).getClass());
+    assertEquals(DatetimeConfigurableItem.DEFAULT_DATETIME_PATTERN,
+        ((DatetimeConfigurableItem) result.get(20)).getPattern());
+    assertEquals(DatetimeConfigurableItem.DEFAULT_LOCALE, ((DatetimeConfigurableItem) result.get(20)).getLocale());
+    assertEquals(TimeZone.getDefault(), ((DatetimeConfigurableItem) result.get(20)).getTimezone());
+    assertEquals("yyyy MM dd HH:mm:ss zzz", ((DatetimeConfigurableItem) result.get(21)).getPattern());
+    assertEquals(DatetimeConfigurableItem.DEFAULT_LOCALE, ((DatetimeConfigurableItem) result.get(21)).getLocale());
+    assertEquals(TimeZone.getDefault(), ((DatetimeConfigurableItem) result.get(21)).getTimezone());
+    assertEquals("yyyy MM dd HH:mm:ss", ((DatetimeConfigurableItem) result.get(22)).getPattern());
+    assertEquals(Locale.forLanguageTag("en-US"), ((DatetimeConfigurableItem) result.get(22)).getLocale());
+    assertEquals(TimeZone.getTimeZone("GMT+0"), ((DatetimeConfigurableItem) result.get(22)).getTimezone());
+    assertEquals(RequestHeaderItem.class, result.get(23).getClass());
+    assertEquals("incoming-header", ((RequestHeaderItem) result.get(23)).getVarName());
+    assertEquals(ResponseHeaderItem.class, result.get(24).getClass());
+    assertEquals("outgoing-header", ((ResponseHeaderItem) result.get(24)).getVarName());
+    assertEquals(CookieItem.class, result.get(25).getClass());
+    assertEquals("cookie", ((CookieItem) result.get(25)).getVarName());
+    assertEquals(TraceIdItem.class, result.get(26).getClass());
+    assertEquals(InvocationContextItem.class, result.get(27).getClass());
+    assertEquals("ctx", ((InvocationContextItem) result.get(27)).getVarName());
+  }
+
+  @Test
+  public void testParsePattern() {
+    String pattern = " %m  cs-uri-stem %{response-header}o ";
+    List<AccessLogItem<RoutingContext>> result = accessLogPatternParser.parsePattern(pattern);
+    assertEquals(7, result.size());
+
+    assertEquals(" ", result.get(0).getFormattedItem(null));
+    assertEquals(HttpMethodItem.class, result.get(1).getClass());
+    assertEquals("  ", result.get(2).getFormattedItem(null));
+    assertEquals(UrlPathItem.class, result.get(3).getClass());
+    assertEquals(" ", result.get(4).getFormattedItem(null));
+    assertEquals(ResponseHeaderItem.class, result.get(5).getClass());
+    assertEquals("response-header", ((ResponseHeaderItem) result.get(5)).getVarName());
+    assertEquals(" ", result.get(6).getFormattedItem(null));
+  }
+
+  @Test
+  public void testParsePatternWithNoBlank() {
+    String pattern = "%mcs-uri-stem%{response-header}o";
+    List<AccessLogItem<RoutingContext>> result = accessLogPatternParser.parsePattern(pattern);
+    assertEquals(3, result.size());
+
+    assertEquals(HttpMethodItem.class, result.get(0).getClass());
+    assertEquals(UrlPathItem.class, result.get(1).getClass());
+    assertEquals(ResponseHeaderItem.class, result.get(2).getClass());
+    assertEquals("response-header", ((ResponseHeaderItem) result.get(2)).getVarName());
+  }
+
+  @Test
+  public void testParsePatternComplex() {
+    String pattern = "%m  cs-uri-stem %{response-header}o abc cs-uri-query %s%{request} header}i plain cs-uri";
+    List<AccessLogItem<RoutingContext>> result = accessLogPatternParser.parsePattern(pattern);
+    assertEquals(12, result.size());
+
+    assertEquals(HttpMethodItem.class, result.get(0).getClass());
+    assertEquals("  ", result.get(1).getFormattedItem(null));
+    assertEquals(UrlPathItem.class, result.get(2).getClass());
+    assertEquals(" ", result.get(3).getFormattedItem(null));
+    assertEquals(ResponseHeaderItem.class, result.get(4).getClass());
+    assertEquals("response-header", ((ResponseHeaderItem) result.get(4)).getVarName());
+    assertEquals(" abc ", result.get(5).getFormattedItem(null));
+    assertEquals(QueryStringItem.class, result.get(6).getClass());
+    assertEquals(" ", result.get(7).getFormattedItem(null));
+    assertEquals(HttpStatusItem.class, result.get(8).getClass());
+    assertEquals(RequestHeaderItem.class, result.get(9).getClass());
+    assertEquals("request} header", ((RequestHeaderItem) result.get(9)).getVarName());
+    assertEquals(" plain ", result.get(10).getFormattedItem(null));
+    assertEquals(UrlPathWithQueryItem.class, result.get(11).getClass());
+  }
 
   Comparator<AccessLogItemMetaWrapper> comparator = VertxRestAccessLogPatternParser.accessLogItemMetaWrapperComparator;
 

-- 
To stop receiving notification emails like this one, please contact
wujimin@apache.org.

[incubator-servicecomb-java-chassis] 01/06: [SCB-616] remove old access log parse logic

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

wujimin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-servicecomb-java-chassis.git

commit 7b768e2ad599e41dc8b6dffb1bc3897e52449246
Author: yaohaishi <ya...@huawei.com>
AuthorDate: Mon May 28 17:36:02 2018 +0800

    [SCB-616] remove old access log parse logic
---
 .../transport/rest/vertx/RestServerVerticle.java   |   7 +-
 .../rest/vertx/accesslog/AccessLogGenerator.java   |  16 +--
 .../accesslog/element/AccessLogItemFactory.java    |  67 -----------
 .../element/creator/AccessLogItemCreator.java      |  28 -----
 .../PercentagePrefixConfigurableItemCreator.java   |  68 -----------
 .../creator/SimpleAccessLogItemCreator.java        |  76 -------------
 .../vertx/accesslog/impl/AccessLogHandler.java     |   5 +-
 .../accesslog/parser/AccessLogItemLocation.java    |  86 --------------
 .../accesslog/parser/AccessLogPatternParser.java   |  27 -----
 .../parser/impl/DefaultAccessLogPatternParser.java | 125 ---------------------
 .../parser/matcher/AccessLogItemMatcher.java       |  28 -----
 .../PercentagePrefixConfigurableMatcher.java       |  84 --------------
 .../parser/matcher/SimpleItemMatcher.java          |  78 -------------
 .../vertx/accesslog/AccessLogGeneratorTest.java    |  14 +--
 .../element/AccessLogItemFactoryTest.java          |  56 ---------
 ...ercentagePrefixConfigurableItemCreatorTest.java | 106 -----------------
 .../impl/DefaultAccessLogPatternParserTest.java    | 119 --------------------
 .../PercentagePrefixConfigurableMatcherTest.java   |  73 ------------
 .../parser/matcher/SimpleItemMatcherTest.java      |  58 ----------
 19 files changed, 8 insertions(+), 1113 deletions(-)

diff --git a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/RestServerVerticle.java b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/RestServerVerticle.java
index 2075d15..f2ac2fb 100644
--- a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/RestServerVerticle.java
+++ b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/RestServerVerticle.java
@@ -29,7 +29,6 @@ import org.apache.servicecomb.foundation.ssl.SSLOptionFactory;
 import org.apache.servicecomb.foundation.vertx.VertxTLSBuilder;
 import org.apache.servicecomb.transport.rest.vertx.accesslog.AccessLogConfiguration;
 import org.apache.servicecomb.transport.rest.vertx.accesslog.impl.AccessLogHandler;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.impl.DefaultAccessLogPatternParser;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -86,15 +85,15 @@ public class RestServerVerticle extends AbstractVerticle {
       LOGGER.info("access log enabled, pattern = {}", pattern);
       mainRouter.route()
           .handler(new AccessLogHandler(
-              pattern,
-              new DefaultAccessLogPatternParser()));
+              pattern
+          ));
     }
   }
 
   private void initDispatcher(Router mainRouter) {
     List<VertxHttpDispatcher> dispatchers = SPIServiceUtils.getSortedService(VertxHttpDispatcher.class);
     for (VertxHttpDispatcher dispatcher : dispatchers) {
-      if(dispatcher.enabled()) {
+      if (dispatcher.enabled()) {
         dispatcher.init(mainRouter);
       }
     }
diff --git a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/AccessLogGenerator.java b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/AccessLogGenerator.java
index c44491e..f05e8d4 100644
--- a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/AccessLogGenerator.java
+++ b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/AccessLogGenerator.java
@@ -17,12 +17,7 @@
 
 package org.apache.servicecomb.transport.rest.vertx.accesslog;
 
-import java.util.List;
-
 import org.apache.servicecomb.transport.rest.vertx.accesslog.element.AccessLogItem;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.element.AccessLogItemFactory;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.AccessLogItemLocation;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.AccessLogPatternParser;
 
 import io.vertx.ext.web.RoutingContext;
 
@@ -37,15 +32,9 @@ public class AccessLogGenerator {
    */
   private AccessLogItem<RoutingContext>[] accessLogItems;
 
-  private AccessLogItemFactory accessLogItemFactory = new AccessLogItemFactory();
-
   @SuppressWarnings("unchecked")
-  public AccessLogGenerator(String rawPattern, AccessLogPatternParser accessLogPatternParser) {
-    List<AccessLogItemLocation> locationList = accessLogPatternParser.parsePattern(rawPattern);
-
-    List<AccessLogItem<RoutingContext>> itemList = accessLogItemFactory.createAccessLogItem(rawPattern, locationList);
-    accessLogItems = new AccessLogItem[itemList.size()];
-    accessLogItems = itemList.toArray(accessLogItems);
+  public AccessLogGenerator(String rawPattern) {
+    accessLogItems = new AccessLogItem[0];
   }
 
   public String generateLog(AccessLogParam<RoutingContext> accessLogParam) {
@@ -60,7 +49,6 @@ public class AccessLogGenerator {
     return log.toString();
   }
 
-
   private AccessLogItem<RoutingContext>[] getAccessLogItems() {
     return accessLogItems;
   }
diff --git a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/AccessLogItemFactory.java b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/AccessLogItemFactory.java
deleted file mode 100644
index df1c47c..0000000
--- a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/AccessLogItemFactory.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.servicecomb.transport.rest.vertx.accesslog.element;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import org.apache.servicecomb.transport.rest.vertx.accesslog.element.creator.AccessLogItemCreator;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.element.creator.PercentagePrefixConfigurableItemCreator;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.element.creator.SimpleAccessLogItemCreator;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.AccessLogItemLocation;
-
-import io.vertx.ext.web.RoutingContext;
-
-/**
- * The factory of {@link AccessLogItem}.
- * Using the {@link AccessLogItemCreator} to generate AccessLogItem, according to {@link AccessLogItemLocation}
- * and rawPattern.
- */
-public class AccessLogItemFactory {
-  private List<AccessLogItemCreator<RoutingContext>> creatorList = Arrays
-      .asList(new SimpleAccessLogItemCreator(), new PercentagePrefixConfigurableItemCreator());
-
-  public List<AccessLogItem<RoutingContext>> createAccessLogItem(String rawPattern,
-      List<AccessLogItemLocation> locationList) {
-    List<AccessLogItem<RoutingContext>> itemList = new ArrayList<>(locationList.size());
-    for (AccessLogItemLocation location : locationList) {
-      setItemList(rawPattern, itemList, location);
-    }
-
-    return itemList;
-  }
-
-  /**
-   * generate single AccessLogItem
-   */
-  private void setItemList(String rawPattern, List<AccessLogItem<RoutingContext>> itemList,
-      AccessLogItemLocation location) {
-    AccessLogItem<RoutingContext> item = null;
-    for (AccessLogItemCreator<RoutingContext> creator : creatorList) {
-      item = creator.create(rawPattern, location);
-      if (null != item) {
-        break;
-      }
-    }
-
-    if (null != item) {
-      itemList.add(item);
-    }
-  }
-}
diff --git a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/creator/AccessLogItemCreator.java b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/creator/AccessLogItemCreator.java
deleted file mode 100644
index 5a31f1f..0000000
--- a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/creator/AccessLogItemCreator.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.servicecomb.transport.rest.vertx.accesslog.element.creator;
-
-import org.apache.servicecomb.transport.rest.vertx.accesslog.element.AccessLogItem;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.AccessLogItemLocation;
-
-/**
- * The actual creator of AccessLogItem.
- */
-public interface AccessLogItemCreator<T> {
-  AccessLogItem<T> create(String rawPattern, AccessLogItemLocation location);
-}
diff --git a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/creator/PercentagePrefixConfigurableItemCreator.java b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/creator/PercentagePrefixConfigurableItemCreator.java
deleted file mode 100644
index a22d3b0..0000000
--- a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/creator/PercentagePrefixConfigurableItemCreator.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.servicecomb.transport.rest.vertx.accesslog.element.creator;
-
-import org.apache.servicecomb.transport.rest.vertx.accesslog.element.AccessLogItem;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.CookieItem;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.DatetimeConfigurableItem;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.InvocationContextItem;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.PlainTextItem;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.RequestHeaderItem;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.ResponseHeaderItem;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.AccessLogItemLocation;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.matcher.PercentagePrefixConfigurableMatcher;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.placeholder.AccessLogItemTypeEnum;
-
-import io.vertx.ext.web.RoutingContext;
-
-/**
- * Some access log item contains changeable part, so we should get it's configuration from rawPattern, and generate it
- * each time it is needed.
- */
-public class PercentagePrefixConfigurableItemCreator implements AccessLogItemCreator<RoutingContext> {
-  @Override
-  public AccessLogItem<RoutingContext> create(String rawPattern, AccessLogItemLocation location) {
-    String config = getConfig(rawPattern, location);
-    switch (location.getPlaceHolder()) {
-      case DATETIME_CONFIGURABLE:
-        return new DatetimeConfigurableItem(config);
-      case REQUEST_HEADER:
-        return new RequestHeaderItem(config);
-      case RESPONSE_HEADER:
-        return new ResponseHeaderItem(config);
-      case COOKIE:
-        return new CookieItem(config);
-      case TEXT_PLAIN:
-        return new PlainTextItem(config);
-      case SCB_INVOCATION_CONTEXT:
-        return new InvocationContextItem(config);
-      default:
-        // unexpected situation
-        return null;
-    }
-  }
-
-  private String getConfig(String rawPattern, AccessLogItemLocation location) {
-    if (location.getPlaceHolder() == AccessLogItemTypeEnum.TEXT_PLAIN) {
-      return rawPattern.substring(location.getStart(), location.getEnd());
-    }
-    return rawPattern.substring(location.getStart() + PercentagePrefixConfigurableMatcher.GENERAL_PREFIX.length(),
-        location.getEnd()
-            - PercentagePrefixConfigurableMatcher.getSuffix(location.getPlaceHolder()).length());
-  }
-}
diff --git a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/creator/SimpleAccessLogItemCreator.java b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/creator/SimpleAccessLogItemCreator.java
deleted file mode 100644
index 3e4983e..0000000
--- a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/creator/SimpleAccessLogItemCreator.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.servicecomb.transport.rest.vertx.accesslog.element.creator;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.servicecomb.transport.rest.vertx.accesslog.element.AccessLogItem;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.DatetimeConfigurableItem;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.DurationMillisecondItem;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.DurationSecondItem;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.FirstLineOfRequestItem;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.HttpMethodItem;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.HttpStatusItem;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.LocalHostItem;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.LocalPortItem;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.QueryStringItem;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.RemoteHostItem;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.RequestProtocolItem;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.ResponseSizeItem;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.TraceIdItem;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.UrlPathItem;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.UrlPathWithQueryItem;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.AccessLogItemLocation;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.placeholder.AccessLogItemTypeEnum;
-
-import io.vertx.ext.web.RoutingContext;
-
-/**
- * For some access log items, their placeholder contains no modifiable part, like "%s" or "sc-status".
- * So we can build a mapping relationship between the placeholder and item instances, when an item is needed, get it by
- * it's placeholder.
- */
-public class SimpleAccessLogItemCreator implements AccessLogItemCreator<RoutingContext> {
-  private static final Map<AccessLogItemTypeEnum, AccessLogItem<RoutingContext>> SIMPLE_ACCESSLOG_ITEM_MAP =
-      new HashMap<>();
-
-  static {
-    SIMPLE_ACCESSLOG_ITEM_MAP.put(AccessLogItemTypeEnum.HTTP_METHOD, new HttpMethodItem());
-    SIMPLE_ACCESSLOG_ITEM_MAP.put(AccessLogItemTypeEnum.HTTP_STATUS, new HttpStatusItem());
-    SIMPLE_ACCESSLOG_ITEM_MAP.put(AccessLogItemTypeEnum.DURATION_IN_SECOND, new DurationSecondItem());
-    SIMPLE_ACCESSLOG_ITEM_MAP.put(AccessLogItemTypeEnum.DURATION_IN_MILLISECOND, new DurationMillisecondItem());
-    SIMPLE_ACCESSLOG_ITEM_MAP.put(AccessLogItemTypeEnum.REMOTE_HOSTNAME, new RemoteHostItem());
-    SIMPLE_ACCESSLOG_ITEM_MAP.put(AccessLogItemTypeEnum.LOCAL_HOSTNAME, new LocalHostItem());
-    SIMPLE_ACCESSLOG_ITEM_MAP.put(AccessLogItemTypeEnum.LOCAL_PORT, new LocalPortItem());
-    SIMPLE_ACCESSLOG_ITEM_MAP.put(AccessLogItemTypeEnum.RESPONSE_SIZE, new ResponseSizeItem("0"));
-    SIMPLE_ACCESSLOG_ITEM_MAP.put(AccessLogItemTypeEnum.RESPONSE_SIZE_CLF, new ResponseSizeItem("-"));
-    SIMPLE_ACCESSLOG_ITEM_MAP.put(AccessLogItemTypeEnum.FIRST_LINE_OF_REQUEST, new FirstLineOfRequestItem());
-    SIMPLE_ACCESSLOG_ITEM_MAP.put(AccessLogItemTypeEnum.URL_PATH, new UrlPathItem());
-    SIMPLE_ACCESSLOG_ITEM_MAP.put(AccessLogItemTypeEnum.QUERY_STRING, new QueryStringItem());
-    SIMPLE_ACCESSLOG_ITEM_MAP.put(AccessLogItemTypeEnum.URL_PATH_WITH_QUERY, new UrlPathWithQueryItem());
-    SIMPLE_ACCESSLOG_ITEM_MAP.put(AccessLogItemTypeEnum.REQUEST_PROTOCOL, new RequestProtocolItem());
-    SIMPLE_ACCESSLOG_ITEM_MAP.put(AccessLogItemTypeEnum.DATETIME_DEFAULT, new DatetimeConfigurableItem());
-    SIMPLE_ACCESSLOG_ITEM_MAP.put(AccessLogItemTypeEnum.SCB_TRACE_ID, new TraceIdItem());
-  }
-
-  @Override
-  public AccessLogItem<RoutingContext> create(String rawPattern, AccessLogItemLocation location) {
-    return SIMPLE_ACCESSLOG_ITEM_MAP.get(location.getPlaceHolder());
-  }
-}
diff --git a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/impl/AccessLogHandler.java b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/impl/AccessLogHandler.java
index 2acacb6..01b5676 100644
--- a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/impl/AccessLogHandler.java
+++ b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/impl/AccessLogHandler.java
@@ -19,7 +19,6 @@ package org.apache.servicecomb.transport.rest.vertx.accesslog.impl;
 
 import org.apache.servicecomb.transport.rest.vertx.accesslog.AccessLogGenerator;
 import org.apache.servicecomb.transport.rest.vertx.accesslog.AccessLogParam;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.AccessLogPatternParser;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -31,8 +30,8 @@ public class AccessLogHandler implements Handler<RoutingContext> {
 
   private AccessLogGenerator accessLogGenerator;
 
-  public AccessLogHandler(String rawPattern, AccessLogPatternParser accessLogPatternParser) {
-    accessLogGenerator = new AccessLogGenerator(rawPattern, accessLogPatternParser);
+  public AccessLogHandler(String rawPattern) {
+    accessLogGenerator = new AccessLogGenerator(rawPattern);
   }
 
   @Override
diff --git a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/AccessLogItemLocation.java b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/AccessLogItemLocation.java
deleted file mode 100644
index 8389ea2..0000000
--- a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/AccessLogItemLocation.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.servicecomb.transport.rest.vertx.accesslog.parser;
-
-import org.apache.servicecomb.transport.rest.vertx.accesslog.placeholder.AccessLogItemTypeEnum;
-
-import com.google.common.base.Objects;
-
-public class AccessLogItemLocation {
-  private int start;
-
-  private int end;
-
-  private AccessLogItemTypeEnum placeHolder;
-
-  public int getStart() {
-    return start;
-  }
-
-  public AccessLogItemLocation setStart(int start) {
-    this.start = start;
-    return this;
-  }
-
-  public int getEnd() {
-    return end;
-  }
-
-  public AccessLogItemLocation setEnd(int end) {
-    this.end = end;
-    return this;
-  }
-
-  public AccessLogItemTypeEnum getPlaceHolder() {
-    return placeHolder;
-  }
-
-  public AccessLogItemLocation setPlaceHolder(AccessLogItemTypeEnum placeHolder) {
-    this.placeHolder = placeHolder;
-    return this;
-  }
-
-  @Override
-  public String toString() {
-    final StringBuilder sb = new StringBuilder("AccessLogItemLocation{");
-    sb.append("start=").append(start);
-    sb.append(", end=").append(end);
-    sb.append(", placeHolder=").append(placeHolder);
-    sb.append('}');
-    return sb.toString();
-  }
-
-  @Override
-  public boolean equals(Object o) {
-    if (this == o) {
-      return true;
-    }
-    if (o == null || !getClass().isAssignableFrom(o.getClass())) {
-      return false;
-    }
-    AccessLogItemLocation that = (AccessLogItemLocation) o;
-    return start == that.start
-        && end == that.end
-        && placeHolder == that.placeHolder;
-  }
-
-  @Override
-  public int hashCode() {
-    return Objects.hashCode(start, end, placeHolder);
-  }
-}
diff --git a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/AccessLogPatternParser.java b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/AccessLogPatternParser.java
deleted file mode 100644
index 4e3f3fc..0000000
--- a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/AccessLogPatternParser.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.servicecomb.transport.rest.vertx.accesslog.parser;
-
-import java.util.List;
-
-/**
- * Parse the raw pattern, and generate a list of information about each access log item.
- */
-public interface AccessLogPatternParser {
-  List<AccessLogItemLocation> parsePattern(String rawPattern);
-}
diff --git a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/DefaultAccessLogPatternParser.java b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/DefaultAccessLogPatternParser.java
deleted file mode 100644
index 05e5649..0000000
--- a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/DefaultAccessLogPatternParser.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.servicecomb.transport.rest.vertx.accesslog.parser.impl;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.AccessLogItemLocation;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.AccessLogPatternParser;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.matcher.AccessLogItemMatcher;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.matcher.PercentagePrefixConfigurableMatcher;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.matcher.SimpleItemMatcher;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.placeholder.AccessLogItemTypeEnum;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class DefaultAccessLogPatternParser implements AccessLogPatternParser {
-  private static final Logger LOGGER = LoggerFactory.getLogger(DefaultAccessLogPatternParser.class);
-
-  private static final List<AccessLogItemMatcher> matcherList = Arrays.asList(
-      new SimpleItemMatcher(), new PercentagePrefixConfigurableMatcher()
-  );
-
-  /**
-   * locate all kinds of access log item, and mark their type.
-   */
-  @Override
-  public List<AccessLogItemLocation> parsePattern(String rawPattern) {
-    LOGGER.info("parse access log pattern: [{}]", rawPattern);
-    List<AccessLogItemLocation> locationList = new ArrayList<>();
-    for (int i = 0; i < rawPattern.length(); ) {
-      AccessLogItemLocation location = match(rawPattern, i);
-      if (null == location) {
-        break;
-      }
-
-      locationList.add(location);
-      i = location.getEnd();
-    }
-
-    checkLocationList(rawPattern, locationList);
-
-    locationList = fillInTextPlain(rawPattern, locationList);
-
-    return locationList;
-  }
-
-  /**
-   * find out a placeholder that occurs firstly behind the offset index.
-   */
-  private AccessLogItemLocation match(String rawPattern, int offset) {
-    AccessLogItemLocation result = null;
-    for (AccessLogItemMatcher matcher : matcherList) {
-      AccessLogItemLocation location = matcher.match(rawPattern, offset);
-      if ((null == result) || (null != location && location.getStart() < result.getStart())) {
-        // if result is null or location is nearer to offset, use location as result
-        result = location;
-      }
-    }
-    return result;
-  }
-
-  /**
-   * The content not matched in rawPattern will be printed as it is, so should be converted to {@link AccessLogItemTypeEnum#TEXT_PLAIN}
-   * @param rawPattern access log string pattern
-   * @param locationList {@link AccessLogItemLocation} list indicating the position of each access log item
-   */
-  private List<AccessLogItemLocation> fillInTextPlain(String rawPattern, List<AccessLogItemLocation> locationList) {
-    int cursor = 0;
-    List<AccessLogItemLocation> result = new ArrayList<>();
-
-    for (AccessLogItemLocation location : locationList) {
-      if (cursor == location.getStart()) {
-        result.add(location);
-      } else if (cursor < location.getStart()) {
-        result.add(new AccessLogItemLocation().setStart(cursor).setEnd(location.getStart()).setPlaceHolder(
-            AccessLogItemTypeEnum.TEXT_PLAIN));
-        result.add(location);
-      }
-      cursor = location.getEnd();
-    }
-
-    if (cursor < rawPattern.length()) {
-      result.add(new AccessLogItemLocation().setStart(cursor).setEnd(rawPattern.length())
-          .setPlaceHolder(AccessLogItemTypeEnum.TEXT_PLAIN));
-    }
-
-    return result;
-  }
-
-  /**
-   * If the access log items' location overlaps or is illegal(exceeding the boundary of the rawPattern),
-   * a {@link IllegalArgumentException} will be thrown out.
-   */
-  private void checkLocationList(String rawPattern, List<AccessLogItemLocation> locationList) {
-    int preEnd = -1;
-    for (AccessLogItemLocation location : locationList) {
-      if (preEnd > location.getStart()) {
-        throw new IllegalArgumentException("access log pattern contains illegal placeholder, please check it.");
-      }
-
-      preEnd = location.getEnd();
-    }
-
-    if (preEnd > rawPattern.length()) {
-      throw new IllegalArgumentException("access log pattern contains illegal placeholder, please check it.");
-    }
-  }
-}
diff --git a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/matcher/AccessLogItemMatcher.java b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/matcher/AccessLogItemMatcher.java
deleted file mode 100644
index 67d8b67..0000000
--- a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/matcher/AccessLogItemMatcher.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.servicecomb.transport.rest.vertx.accesslog.parser.matcher;
-
-import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.AccessLogItemLocation;
-
-public interface AccessLogItemMatcher {
-  /*
-   * Return an {@link AccessLogItemLocation} which matches part of rawPattern and is nearest to the offset(That means
-   * the {@link AccessLogItemLocation#start} is no less than offset and is smallest among the potential matched Item).
-   */
-  AccessLogItemLocation match(String rawPattern, int offset);
-}
diff --git a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/matcher/PercentagePrefixConfigurableMatcher.java b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/matcher/PercentagePrefixConfigurableMatcher.java
deleted file mode 100644
index 55e9d6b..0000000
--- a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/matcher/PercentagePrefixConfigurableMatcher.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.servicecomb.transport.rest.vertx.accesslog.parser.matcher;
-
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.AccessLogItemLocation;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.placeholder.AccessLogItemTypeEnum;
-
-/**
- * for those access log item whose placeholder like "%{configpart}C"
- */
-public class PercentagePrefixConfigurableMatcher implements AccessLogItemMatcher {
-
-  public static final String GENERAL_PREFIX = "%{";
-
-  /**
-   * suffix to AccessLogItemTypeEnum
-   */
-  private static final Map<String, AccessLogItemTypeEnum> SUFFIX_PLACEHOLDER_ENUM_MAP = new LinkedHashMap<>();
-
-  /**
-   * AccessLogItemTypeEnum to suffix
-   */
-  private static final Map<AccessLogItemTypeEnum, String> ENUM_SUFFIX_MAP = new HashMap<>();
-
-  public static final String SUFFIX_HEAD = "}";
-
-  static {
-    SUFFIX_PLACEHOLDER_ENUM_MAP.put("}t", AccessLogItemTypeEnum.DATETIME_CONFIGURABLE);
-    SUFFIX_PLACEHOLDER_ENUM_MAP.put("}i", AccessLogItemTypeEnum.REQUEST_HEADER);
-    SUFFIX_PLACEHOLDER_ENUM_MAP.put("}o", AccessLogItemTypeEnum.RESPONSE_HEADER);
-    SUFFIX_PLACEHOLDER_ENUM_MAP.put("}C", AccessLogItemTypeEnum.COOKIE);
-    SUFFIX_PLACEHOLDER_ENUM_MAP.put("}SCB-ctx", AccessLogItemTypeEnum.SCB_INVOCATION_CONTEXT);
-
-    for (Entry<String, AccessLogItemTypeEnum> entry : SUFFIX_PLACEHOLDER_ENUM_MAP.entrySet()) {
-      ENUM_SUFFIX_MAP.put(entry.getValue(), entry.getKey());
-    }
-  }
-
-  @Override
-  public AccessLogItemLocation match(String rawPattern, int offset) {
-    int begin = rawPattern.indexOf(GENERAL_PREFIX, offset);
-    if (begin < 0) {
-      return null;
-    }
-
-    int end = rawPattern.indexOf(SUFFIX_HEAD, begin);
-    if (end < 0) {
-      return null;
-    }
-
-    for (Entry<String, AccessLogItemTypeEnum> entry : SUFFIX_PLACEHOLDER_ENUM_MAP.entrySet()) {
-      if (rawPattern.startsWith(entry.getKey(), end)) {
-        return new AccessLogItemLocation().setStart(begin).setEnd(end + entry.getKey().length())
-            .setPlaceHolder(entry.getValue());
-      }
-    }
-
-    return null;
-  }
-
-  public static String getSuffix(AccessLogItemTypeEnum accessLogItemTypeEnum) {
-    return ENUM_SUFFIX_MAP.get(accessLogItemTypeEnum);
-  }
-}
diff --git a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/matcher/SimpleItemMatcher.java b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/matcher/SimpleItemMatcher.java
deleted file mode 100644
index a3d6e93..0000000
--- a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/matcher/SimpleItemMatcher.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.servicecomb.transport.rest.vertx.accesslog.parser.matcher;
-
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.AccessLogItemLocation;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.placeholder.AccessLogItemTypeEnum;
-
-/**
- * for those access log items whose placeholder has no changeable part.
- */
-public class SimpleItemMatcher implements AccessLogItemMatcher {
-  private static final Map<String, AccessLogItemTypeEnum> PLACEHOLDER_ENUM_MAP = new LinkedHashMap<>();
-
-  static {
-    PLACEHOLDER_ENUM_MAP.put("%m", AccessLogItemTypeEnum.HTTP_METHOD);
-    PLACEHOLDER_ENUM_MAP.put("cs-method", AccessLogItemTypeEnum.HTTP_METHOD);
-    PLACEHOLDER_ENUM_MAP.put("%s", AccessLogItemTypeEnum.HTTP_STATUS);
-    PLACEHOLDER_ENUM_MAP.put("sc-status", AccessLogItemTypeEnum.HTTP_STATUS);
-    PLACEHOLDER_ENUM_MAP.put("%T", AccessLogItemTypeEnum.DURATION_IN_SECOND);
-    PLACEHOLDER_ENUM_MAP.put("%D", AccessLogItemTypeEnum.DURATION_IN_MILLISECOND);
-    PLACEHOLDER_ENUM_MAP.put("%h", AccessLogItemTypeEnum.REMOTE_HOSTNAME);
-    PLACEHOLDER_ENUM_MAP.put("%v", AccessLogItemTypeEnum.LOCAL_HOSTNAME);
-    PLACEHOLDER_ENUM_MAP.put("%p", AccessLogItemTypeEnum.LOCAL_PORT);
-    PLACEHOLDER_ENUM_MAP.put("%B", AccessLogItemTypeEnum.RESPONSE_SIZE);
-    PLACEHOLDER_ENUM_MAP.put("%b", AccessLogItemTypeEnum.RESPONSE_SIZE_CLF);
-    PLACEHOLDER_ENUM_MAP.put("%r", AccessLogItemTypeEnum.FIRST_LINE_OF_REQUEST);
-    PLACEHOLDER_ENUM_MAP.put("%U", AccessLogItemTypeEnum.URL_PATH);
-    PLACEHOLDER_ENUM_MAP.put("cs-uri-stem", AccessLogItemTypeEnum.URL_PATH);
-    PLACEHOLDER_ENUM_MAP.put("%q", AccessLogItemTypeEnum.QUERY_STRING);
-    PLACEHOLDER_ENUM_MAP.put("cs-uri-query", AccessLogItemTypeEnum.QUERY_STRING);
-    PLACEHOLDER_ENUM_MAP.put("cs-uri", AccessLogItemTypeEnum.URL_PATH_WITH_QUERY);
-    PLACEHOLDER_ENUM_MAP.put("%H", AccessLogItemTypeEnum.REQUEST_PROTOCOL);
-    PLACEHOLDER_ENUM_MAP.put("%t", AccessLogItemTypeEnum.DATETIME_DEFAULT);
-    PLACEHOLDER_ENUM_MAP.put("%SCB-traceId", AccessLogItemTypeEnum.SCB_TRACE_ID);
-  }
-
-  @Override
-  public AccessLogItemLocation match(String rawPattern, int offset) {
-    int start = -1;
-    Entry<String, AccessLogItemTypeEnum> nearestEntry = null;
-    for (Entry<String, AccessLogItemTypeEnum> entry : PLACEHOLDER_ENUM_MAP.entrySet()) {
-      int cursor = rawPattern.indexOf(entry.getKey(), offset);
-      if (cursor < 0) {
-        continue;
-      }
-      if (start < 0 || cursor < start) {
-        start = cursor;
-        nearestEntry = entry;
-      }
-    }
-
-    if (null == nearestEntry) {
-      return null;
-    }
-
-    return new AccessLogItemLocation().setStart(start).setEnd(start + nearestEntry.getKey().length())
-        .setPlaceHolder(nearestEntry.getValue());
-  }
-}
diff --git a/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/AccessLogGeneratorTest.java b/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/AccessLogGeneratorTest.java
index a8a1186..1df6609 100644
--- a/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/AccessLogGeneratorTest.java
+++ b/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/AccessLogGeneratorTest.java
@@ -20,15 +20,12 @@ package org.apache.servicecomb.transport.rest.vertx.accesslog;
 import static org.junit.Assert.assertEquals;
 
 import java.text.SimpleDateFormat;
-import java.util.Arrays;
 import java.util.TimeZone;
 
 import org.apache.servicecomb.transport.rest.vertx.accesslog.element.AccessLogItem;
 import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.DatetimeConfigurableItem;
 import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.HttpMethodItem;
 import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.PlainTextItem;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.AccessLogItemLocation;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.placeholder.AccessLogItemTypeEnum;
 import org.junit.Assert;
 import org.junit.Test;
 import org.mockito.Mockito;
@@ -40,16 +37,7 @@ import mockit.Deencapsulation;
 
 public class AccessLogGeneratorTest {
 
-  private static final AccessLogGenerator ACCESS_LOG_GENERATOR = new AccessLogGenerator("%m - %t",
-      rawPattern -> {
-        assertEquals("%m - %t", rawPattern);
-        return Arrays.asList(
-            new AccessLogItemLocation().setStart(0).setEnd(2).setPlaceHolder(AccessLogItemTypeEnum.HTTP_METHOD),
-            new AccessLogItemLocation().setStart(2).setEnd(5).setPlaceHolder(AccessLogItemTypeEnum.TEXT_PLAIN),
-            new AccessLogItemLocation().setStart(5)
-                .setEnd(7)
-                .setPlaceHolder(AccessLogItemTypeEnum.DATETIME_DEFAULT));
-      });
+  private static final AccessLogGenerator ACCESS_LOG_GENERATOR = new AccessLogGenerator("%m - %t");
 
   @Test
   public void testConstructor() {
diff --git a/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/AccessLogItemFactoryTest.java b/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/AccessLogItemFactoryTest.java
deleted file mode 100644
index 94b16e2..0000000
--- a/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/AccessLogItemFactoryTest.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.servicecomb.transport.rest.vertx.accesslog.element;
-
-import java.util.Arrays;
-import java.util.List;
-
-import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.DatetimeConfigurableItem;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.PlainTextItem;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.QueryStringItem;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.RequestHeaderItem;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.UrlPathWithQueryItem;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.AccessLogItemLocation;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.placeholder.AccessLogItemTypeEnum;
-import org.junit.Assert;
-import org.junit.Test;
-
-import io.vertx.ext.web.RoutingContext;
-
-public class AccessLogItemFactoryTest {
-  private static final String PATTERN = "test %{EEE, dd MMM yyyy HH:mm:ss zzz}t cs-uri-query cs-uri %{VARNAME1}i";
-
-  private static final List<AccessLogItemLocation> locationList = Arrays.asList(
-      new AccessLogItemLocation().setStart(0).setEnd(5).setPlaceHolder(AccessLogItemTypeEnum.TEXT_PLAIN),
-      new AccessLogItemLocation().setStart(5).setEnd(38).setPlaceHolder(AccessLogItemTypeEnum.DATETIME_CONFIGURABLE),
-      new AccessLogItemLocation().setStart(39).setEnd(51).setPlaceHolder(AccessLogItemTypeEnum.QUERY_STRING),
-      new AccessLogItemLocation().setStart(52).setEnd(58).setPlaceHolder(AccessLogItemTypeEnum.URL_PATH_WITH_QUERY),
-      new AccessLogItemLocation().setStart(59).setEnd(71).setPlaceHolder(AccessLogItemTypeEnum.REQUEST_HEADER));
-
-  @Test
-  public void testCreateAccessLogItem() {
-    List<AccessLogItem<RoutingContext>> itemList =
-        new AccessLogItemFactory().createAccessLogItem(PATTERN, locationList);
-    Assert.assertEquals(5, itemList.size());
-    Assert.assertEquals(PlainTextItem.class, itemList.get(0).getClass());
-    Assert.assertEquals(DatetimeConfigurableItem.class, itemList.get(1).getClass());
-    Assert.assertEquals(QueryStringItem.class, itemList.get(2).getClass());
-    Assert.assertEquals(UrlPathWithQueryItem.class, itemList.get(3).getClass());
-    Assert.assertEquals(RequestHeaderItem.class, itemList.get(4).getClass());
-  }
-}
diff --git a/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/creator/PercentagePrefixConfigurableItemCreatorTest.java b/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/creator/PercentagePrefixConfigurableItemCreatorTest.java
deleted file mode 100644
index cf3c343..0000000
--- a/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/creator/PercentagePrefixConfigurableItemCreatorTest.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.servicecomb.transport.rest.vertx.accesslog.element.creator;
-
-import org.apache.servicecomb.transport.rest.vertx.accesslog.element.AccessLogItem;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.CookieItem;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.DatetimeConfigurableItem;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.InvocationContextItem;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.PlainTextItem;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.RequestHeaderItem;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.ResponseHeaderItem;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.AccessLogItemLocation;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.placeholder.AccessLogItemTypeEnum;
-import org.junit.Assert;
-import org.junit.Test;
-
-import io.vertx.ext.web.RoutingContext;
-
-public class PercentagePrefixConfigurableItemCreatorTest {
-  private static final String PATTERN = "test %{EEE, dd MMM yyyy HH:mm:ss zzz}t %{VARNAME1}i %{VARNAME2}o %{VARNAME3}C %{var name4}SCB-ctx";
-
-  private static final PercentagePrefixConfigurableItemCreator CREATOR = new PercentagePrefixConfigurableItemCreator();
-
-  @Test
-  public void testCreateDatetimeConfigurableItem() {
-    AccessLogItemLocation location = new AccessLogItemLocation().setStart(5).setEnd(38).setPlaceHolder(
-        AccessLogItemTypeEnum.DATETIME_CONFIGURABLE);
-
-    AccessLogItem<RoutingContext> item = CREATOR.create(PATTERN, location);
-
-    Assert.assertEquals(DatetimeConfigurableItem.class, item.getClass());
-    Assert.assertEquals("EEE, dd MMM yyyy HH:mm:ss zzz", ((DatetimeConfigurableItem) item).getPattern());
-  }
-
-  @Test
-  public void testCreateRequestHeaderItem() {
-    AccessLogItemLocation location = new AccessLogItemLocation().setStart(39).setEnd(51).setPlaceHolder(
-        AccessLogItemTypeEnum.REQUEST_HEADER);
-
-    AccessLogItem<RoutingContext> item = CREATOR.create(PATTERN, location);
-
-    Assert.assertEquals(RequestHeaderItem.class, item.getClass());
-    Assert.assertEquals("VARNAME1", ((RequestHeaderItem) item).getVarName());
-  }
-
-  @Test
-  public void testCreateResponseHeaderItem() {
-    AccessLogItemLocation location = new AccessLogItemLocation().setStart(52).setEnd(64).setPlaceHolder(
-        AccessLogItemTypeEnum.RESPONSE_HEADER);
-
-    AccessLogItem<RoutingContext> item = CREATOR.create(PATTERN, location);
-
-    Assert.assertEquals(ResponseHeaderItem.class, item.getClass());
-    Assert.assertEquals("VARNAME2", ((ResponseHeaderItem) item).getVarName());
-  }
-
-  @Test
-  public void testCreateCookieItem() {
-    AccessLogItemLocation location = new AccessLogItemLocation().setStart(65).setEnd(77).setPlaceHolder(
-        AccessLogItemTypeEnum.COOKIE);
-
-    AccessLogItem<RoutingContext> item = CREATOR.create(PATTERN, location);
-
-    Assert.assertEquals(CookieItem.class, item.getClass());
-    Assert.assertEquals("VARNAME3", ((CookieItem) item).getVarName());
-  }
-
-  @Test
-  public void testPlainTextItem() {
-    AccessLogItemLocation location = new AccessLogItemLocation().setStart(0)
-        .setEnd(5)
-        .setPlaceHolder(AccessLogItemTypeEnum.TEXT_PLAIN);
-
-    AccessLogItem<RoutingContext> item = CREATOR.create(PATTERN, location);
-
-    Assert.assertEquals(PlainTextItem.class, item.getClass());
-    Assert.assertEquals("test ", item.getFormattedItem(null));
-  }
-
-  @Test
-  public void testCreateInvocationContextItem() {
-    AccessLogItemLocation location = new AccessLogItemLocation().setStart(78)
-        .setEnd(97)
-        .setPlaceHolder(AccessLogItemTypeEnum.SCB_INVOCATION_CONTEXT);
-
-    AccessLogItem<RoutingContext> item = CREATOR.create(PATTERN, location);
-
-    Assert.assertEquals(InvocationContextItem.class, item.getClass());
-    Assert.assertEquals("var name4", ((InvocationContextItem) item).getVarName());
-  }
-}
diff --git a/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/DefaultAccessLogPatternParserTest.java b/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/DefaultAccessLogPatternParserTest.java
deleted file mode 100644
index efd0454..0000000
--- a/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/DefaultAccessLogPatternParserTest.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.servicecomb.transport.rest.vertx.accesslog.parser.impl;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.fail;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
-import java.util.stream.Collectors;
-
-import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.AccessLogItemLocation;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.placeholder.AccessLogItemTypeEnum;
-import org.hamcrest.Matchers;
-import org.junit.Test;
-
-import mockit.Deencapsulation;
-
-public class DefaultAccessLogPatternParserTest {
-  private static final String ROW_PATTERN = "[cs-method] %m %s%T%D%h%v%p%B%b%r%U%q"
-      + "cs-uri-stemcs-uri-querycs-uri%H%t%{yyyy MM dd HH:mm:ss zzz}t"
-      + "%{yyyy MM dd HH:mm:ss|GMT+0|en-US}t"
-      + "%{incoming-header}i"
-      + "%{outgoing-header}o"
-      + "%{cookie}C"
-      + "%SCB-traceId"
-      + "%{invocationContext}SCB-ctx";
-
-  private static DefaultAccessLogPatternParser accessLogPatternParser = new DefaultAccessLogPatternParser();
-
-  @Test
-  public void testParsePattern() {
-    List<AccessLogItemLocation> result = accessLogPatternParser.parsePattern(ROW_PATTERN);
-    assertEquals(28, result.size());
-
-    assertThat(result.stream().map(AccessLogItemLocation::getPlaceHolder)
-            .filter(Objects::nonNull).collect(Collectors.toList()),
-        Matchers.contains(
-            AccessLogItemTypeEnum.TEXT_PLAIN,
-            AccessLogItemTypeEnum.HTTP_METHOD,
-            AccessLogItemTypeEnum.TEXT_PLAIN,
-            AccessLogItemTypeEnum.HTTP_METHOD,
-            AccessLogItemTypeEnum.TEXT_PLAIN,
-            AccessLogItemTypeEnum.HTTP_STATUS,
-            AccessLogItemTypeEnum.DURATION_IN_SECOND,
-            AccessLogItemTypeEnum.DURATION_IN_MILLISECOND,
-            AccessLogItemTypeEnum.REMOTE_HOSTNAME,
-            AccessLogItemTypeEnum.LOCAL_HOSTNAME,
-            AccessLogItemTypeEnum.LOCAL_PORT,
-            AccessLogItemTypeEnum.RESPONSE_SIZE,
-            AccessLogItemTypeEnum.RESPONSE_SIZE_CLF,
-            AccessLogItemTypeEnum.FIRST_LINE_OF_REQUEST,
-            AccessLogItemTypeEnum.URL_PATH,
-            AccessLogItemTypeEnum.QUERY_STRING,
-            AccessLogItemTypeEnum.URL_PATH,
-            AccessLogItemTypeEnum.QUERY_STRING,
-            AccessLogItemTypeEnum.URL_PATH_WITH_QUERY,
-            AccessLogItemTypeEnum.REQUEST_PROTOCOL,
-            AccessLogItemTypeEnum.DATETIME_DEFAULT,
-            AccessLogItemTypeEnum.DATETIME_CONFIGURABLE,
-            AccessLogItemTypeEnum.DATETIME_CONFIGURABLE,
-            AccessLogItemTypeEnum.REQUEST_HEADER,
-            AccessLogItemTypeEnum.RESPONSE_HEADER,
-            AccessLogItemTypeEnum.COOKIE,
-            AccessLogItemTypeEnum.SCB_TRACE_ID,
-            AccessLogItemTypeEnum.SCB_INVOCATION_CONTEXT));
-  }
-
-  @Test
-  public void testCheckLocationList() {
-    List<AccessLogItemLocation> locationList = new ArrayList<>(3);
-    locationList.add(new AccessLogItemLocation().setStart(0).setEnd(3));
-    locationList.add(new AccessLogItemLocation().setStart(3).setEnd(6));
-    locationList.add(new AccessLogItemLocation().setStart(5).setEnd(9));
-
-    try {
-      Deencapsulation.invoke(new DefaultAccessLogPatternParser(), "checkLocationList",
-          "0123456789", locationList);
-      fail("expect an exception");
-    } catch (Exception e) {
-      assertEquals(IllegalArgumentException.class, e.getClass());
-      assertEquals("access log pattern contains illegal placeholder, please check it.", e.getMessage());
-    }
-  }
-
-  @Test
-  public void testCheckLocationListOnLocationEndGreaterThanPatternLength() {
-    List<AccessLogItemLocation> locationList = new ArrayList<>(3);
-    locationList.add(new AccessLogItemLocation().setStart(0).setEnd(3));
-    locationList.add(new AccessLogItemLocation().setStart(3).setEnd(6));
-    locationList.add(new AccessLogItemLocation().setStart(7).setEnd(9));
-
-    try {
-      Deencapsulation.invoke(new DefaultAccessLogPatternParser(), "checkLocationList",
-          "0123456", locationList);
-      fail("expect an exception");
-    } catch (Exception e) {
-      assertEquals(IllegalArgumentException.class, e.getClass());
-      assertEquals("access log pattern contains illegal placeholder, please check it.", e.getMessage());
-    }
-  }
-}
diff --git a/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/matcher/PercentagePrefixConfigurableMatcherTest.java b/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/matcher/PercentagePrefixConfigurableMatcherTest.java
deleted file mode 100644
index d048999..0000000
--- a/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/matcher/PercentagePrefixConfigurableMatcherTest.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.servicecomb.transport.rest.vertx.accesslog.parser.matcher;
-
-import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.AccessLogItemLocation;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.placeholder.AccessLogItemTypeEnum;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class PercentagePrefixConfigurableMatcherTest {
-
-  public static final PercentagePrefixConfigurableMatcher MATCHER = new PercentagePrefixConfigurableMatcher();
-
-  public static final String TEST_RAW_PATTERN = "%{pattern}t %{test pattern}C %{test pattern}t %{test pattern}SCB-ctx";
-
-  @Test
-  public void testMatch() {
-    AccessLogItemLocation location;
-    location = MATCHER.match(TEST_RAW_PATTERN, 0);
-    Assert.assertEquals(
-        location,
-        new AccessLogItemLocation()
-            .setStart(0)
-            .setEnd(11)
-            .setPlaceHolder(AccessLogItemTypeEnum.DATETIME_CONFIGURABLE));
-
-    location = MATCHER.match(TEST_RAW_PATTERN, 10);
-    Assert.assertEquals(
-        location,
-        new AccessLogItemLocation()
-            .setStart(12)
-            .setEnd(28)
-            .setPlaceHolder(AccessLogItemTypeEnum.COOKIE));
-
-    location = MATCHER.match(TEST_RAW_PATTERN, 30);
-    Assert.assertEquals(
-        location,
-        new AccessLogItemLocation()
-            .setStart(46)
-            .setEnd(68)
-            .setPlaceHolder(AccessLogItemTypeEnum.SCB_INVOCATION_CONTEXT));
-
-    location = MATCHER.match(TEST_RAW_PATTERN, 47);
-    Assert.assertNull(location);
-  }
-
-  @Test
-  public void testNotMatch() {
-    AccessLogItemLocation location = MATCHER.match("notmatch", 0);
-    Assert.assertNull(location);
-  }
-
-  @Test
-  public void testNotMatchWithPrefix() {
-    AccessLogItemLocation location = MATCHER.match("%{notmatch}x", 0);
-    Assert.assertNull(location);
-  }
-}
\ No newline at end of file
diff --git a/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/matcher/SimpleItemMatcherTest.java b/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/matcher/SimpleItemMatcherTest.java
deleted file mode 100644
index 3ce57ae..0000000
--- a/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/matcher/SimpleItemMatcherTest.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.servicecomb.transport.rest.vertx.accesslog.parser.matcher;
-
-import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.AccessLogItemLocation;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.placeholder.AccessLogItemTypeEnum;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class SimpleItemMatcherTest {
-
-  private static final SimpleItemMatcher MATCHER = new SimpleItemMatcher();
-
-  public static final String PATTERN = "%h - - %t %r %s %B";
-
-  @Test
-  public void testMatch() {
-    AccessLogItemLocation location = MATCHER.match(PATTERN, 0);
-    Assert.assertEquals(
-        location,
-        new AccessLogItemLocation()
-            .setStart(0)
-            .setEnd(2)
-            .setPlaceHolder(AccessLogItemTypeEnum.REMOTE_HOSTNAME));
-
-    location = MATCHER.match(PATTERN, 3);
-    Assert.assertEquals(
-        location,
-        new AccessLogItemLocation()
-            .setStart(7)
-            .setEnd(9)
-            .setPlaceHolder(AccessLogItemTypeEnum.DATETIME_DEFAULT));
-
-    location = MATCHER.match(PATTERN, 17);
-    Assert.assertNull(location);
-  }
-
-  @Test
-  public void testNotMatch() {
-    AccessLogItemLocation location = MATCHER.match("notmatch", 0);
-    Assert.assertNull(location);
-  }
-}

-- 
To stop receiving notification emails like this one, please contact
wujimin@apache.org.

[incubator-servicecomb-java-chassis] 02/06: [SCB-616] define new AccessLogPatternParser

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

wujimin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-servicecomb-java-chassis.git

commit 789593956bb9a396d838b63fa948894417adcc56
Author: yaohaishi <ya...@huawei.com>
AuthorDate: Sun May 27 01:31:50 2018 +0800

    [SCB-616] define new AccessLogPatternParser
---
 .../vertx/accesslog/parser/AccessLogItemMeta.java  | 57 ++++++++++++++++
 .../accesslog/parser/AccessLogPatternParser.java   | 33 +++++++++
 .../parser/VertxRestAccessLogItemCreator.java      | 45 ++++++++++++
 .../impl/VertxRestAccessLogPatternParser.java      | 79 ++++++++++++++++++++++
 .../impl/VertxRestAccessLogPatternParserTest.java  | 21 ++++++
 5 files changed, 235 insertions(+)

diff --git a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/AccessLogItemMeta.java b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/AccessLogItemMeta.java
new file mode 100644
index 0000000..131743e
--- /dev/null
+++ b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/AccessLogItemMeta.java
@@ -0,0 +1,57 @@
+/*
+ * 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.servicecomb.transport.rest.vertx.accesslog.parser;
+
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.AccessLogItem;
+
+/**
+ * The meta data of {@linkplain AccessLogItem}.
+ */
+public class AccessLogItemMeta {
+  private String prefix;
+
+  private String suffix;
+
+  /**
+   * Used for sorting {@linkplain AccessLogItemMeta}. Default value is 0.
+   * Smaller one has higher priority.
+   */
+  private int order;
+
+  public AccessLogItemMeta(String prefix, String suffix, int order) {
+    this.prefix = prefix;
+    this.suffix = suffix;
+    this.order = order;
+  }
+
+  public AccessLogItemMeta(String prefix, String suffix) {
+    this(prefix, suffix, 0);
+  }
+
+  public String getPrefix() {
+    return prefix;
+  }
+
+  public String getSuffix() {
+    return suffix;
+  }
+
+  public int getOrder() {
+    return order;
+  }
+}
diff --git a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/AccessLogPatternParser.java b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/AccessLogPatternParser.java
new file mode 100644
index 0000000..bc38768
--- /dev/null
+++ b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/AccessLogPatternParser.java
@@ -0,0 +1,33 @@
+/*
+ * 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.servicecomb.transport.rest.vertx.accesslog.parser;
+
+import java.util.List;
+
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.AccessLogItem;
+
+/**
+ * This parser will parse the rawPattern of access log and generate a list of {@link AccessLogItem},
+ * which will be used in {@link org.apache.servicecomb.transport.rest.vertx.accesslog.AccessLogGenerator} to generate
+ * access log content.
+ * @param <T> the type of {@linkplain org.apache.servicecomb.transport.rest.vertx.accesslog.AccessLogParam#contextData
+ * AccessLogParam.contextData}, which usually depends on the transport way.
+ */
+public interface AccessLogPatternParser<T> {
+  List<AccessLogItem<T>> parsePattern(String rawPattern);
+}
diff --git a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/VertxRestAccessLogItemCreator.java b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/VertxRestAccessLogItemCreator.java
new file mode 100644
index 0000000..f1917eb
--- /dev/null
+++ b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/VertxRestAccessLogItemCreator.java
@@ -0,0 +1,45 @@
+/*
+ * 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.servicecomb.transport.rest.vertx.accesslog.parser;
+
+import java.util.List;
+
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.AccessLogItem;
+
+import io.vertx.ext.web.RoutingContext;
+
+/**
+ * The {@linkplain VertxRestAccessLogItemCreator}s are able to instantiate a group of {@linkplain AccessLogItem}.
+ */
+public interface VertxRestAccessLogItemCreator {
+  /**
+   * @return A list of {@linkplain AccessLogItemMeta} to show that what kinds of {@linkplain AccessLogItem}
+   * this creator is able to instantiate.
+   */
+  List<AccessLogItemMeta> getAccessLogItemMeta();
+
+  /**
+   * Create an instance of {@linkplain AccessLogItem} which is specified by {@linkplain AccessLogItemMeta} and config.
+   * @param accessLogItemMeta determine which kind of {@linkplain AccessLogItem} is created.
+   * @param config
+   * e.g. For {@linkplain org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.CookieItem CookieItem},
+   * the pattern may be "%{varName}C", and it's config is "varName". Some {@linkplain AccessLogItem} with no configurable
+   * pattern (like "%m") will receive {@code null} as config.
+   */
+  AccessLogItem<RoutingContext> createItem(AccessLogItemMeta accessLogItemMeta, String config);
+}
diff --git a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/VertxRestAccessLogPatternParser.java b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/VertxRestAccessLogPatternParser.java
new file mode 100644
index 0000000..666d9a9
--- /dev/null
+++ b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/VertxRestAccessLogPatternParser.java
@@ -0,0 +1,79 @@
+/*
+ * 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.servicecomb.transport.rest.vertx.accesslog.parser.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.AccessLogItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.AccessLogItemMeta;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.AccessLogPatternParser;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.VertxRestAccessLogItemCreator;
+
+import io.vertx.ext.web.RoutingContext;
+
+/**
+ * The parser is used for rest-over-vertx transport.
+ */
+public class VertxRestAccessLogPatternParser implements AccessLogPatternParser<RoutingContext> {
+  private List<VertxRestAccessLogItemCreator> creators = new ArrayList<>();
+
+  /**
+   * All of the {@linkplain AccessLogItemMeta} will be wrapped into {@linkplain AccessLogItemMetaWrapper}.
+   */
+  private List<AccessLogItemMetaWrapper> accessLogItemMetaWrappers = new ArrayList<>();
+
+  public VertxRestAccessLogPatternParser() {
+    for (VertxRestAccessLogItemCreator creator : creators) {
+      for (AccessLogItemMeta accessLogItemMeta : creator.getAccessLogItemMeta()) {
+        accessLogItemMetaWrappers.add(new AccessLogItemMetaWrapper(accessLogItemMeta, creator));
+      }
+    }
+  }
+
+  /**
+   * @param rawPattern The access log pattern string specified by users.
+   * @return A list of {@linkplain AccessLogItem} which actually generate the content of access log.
+   */
+  @Override
+  public List<AccessLogItem<RoutingContext>> parsePattern(String rawPattern) {
+    List<AccessLogItem<RoutingContext>> itemList = new ArrayList<>();
+    // the algorithm is unimplemented.
+    return itemList;
+  }
+
+  public static class AccessLogItemMetaWrapper {
+    private AccessLogItemMeta accessLogItemMeta;
+
+    private VertxRestAccessLogItemCreator vertxRestAccessLogItemCreator;
+
+    public AccessLogItemMetaWrapper(AccessLogItemMeta accessLogItemMeta,
+        VertxRestAccessLogItemCreator vertxRestAccessLogItemCreator) {
+      this.accessLogItemMeta = accessLogItemMeta;
+      this.vertxRestAccessLogItemCreator = vertxRestAccessLogItemCreator;
+    }
+
+    public AccessLogItemMeta getAccessLogItemMeta() {
+      return accessLogItemMeta;
+    }
+
+    public VertxRestAccessLogItemCreator getVertxRestAccessLogItemCreator() {
+      return vertxRestAccessLogItemCreator;
+    }
+  }
+}
diff --git a/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/VertxRestAccessLogPatternParserTest.java b/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/VertxRestAccessLogPatternParserTest.java
new file mode 100644
index 0000000..c27503e
--- /dev/null
+++ b/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/VertxRestAccessLogPatternParserTest.java
@@ -0,0 +1,21 @@
+/*
+ * 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.servicecomb.transport.rest.vertx.accesslog.parser.impl;
+
+public class VertxRestAccessLogPatternParserTest {
+}
\ No newline at end of file

-- 
To stop receiving notification emails like this one, please contact
wujimin@apache.org.