You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by li...@apache.org on 2018/01/26 01:24:20 UTC

[incubator-servicecomb-java-chassis] 02/02: [SCB-177] add traceId element in access log

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

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

commit 86ab2ec7af8f5b6b40f47c54d922b7e094f377cb
Author: yaohaishi <ya...@huawei.com>
AuthorDate: Thu Jan 25 00:47:07 2018 +0800

    [SCB-177] add traceId element in access log
---
 .../common/rest/AbstractRestInvocation.java        |   8 ++
 .../common/rest/TestAbstractRestInvocation.java    |  11 +++
 .../accesslog/element/impl/TraceIdElement.java     |  51 ++++++++++
 .../parser/impl/DefaultAccessLogPatternParser.java |  12 ++-
 .../parser/matcher/impl/TraceIdMatcher.java        |  35 +++++++
 .../accesslog/element/impl/TraceIdElementTest.java | 106 +++++++++++++++++++++
 .../impl/DefaultAccessLogPatternParserTest.java    |  70 ++++++++------
 .../parser/matcher/impl/TraceIdMatcherTest.java    |  65 +++++++++++++
 8 files changed, 327 insertions(+), 31 deletions(-)

diff --git a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/AbstractRestInvocation.java b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/AbstractRestInvocation.java
index 36c1739..c8ce3ca 100644
--- a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/AbstractRestInvocation.java
+++ b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/AbstractRestInvocation.java
@@ -106,6 +106,14 @@ public abstract class AbstractRestInvocation {
     invocation.setContext(cseContext);
   }
 
+  public String getContext(String key) {
+    if (null == invocation || null == invocation.getContext()) {
+      return null;
+    }
+
+    return invocation.getContext(key);
+  }
+
   protected void scheduleInvocation() {
     OperationMeta operationMeta = restOperationMeta.getOperationMeta();
 
diff --git a/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/TestAbstractRestInvocation.java b/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/TestAbstractRestInvocation.java
index 6586403..58d6c2e 100644
--- a/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/TestAbstractRestInvocation.java
+++ b/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/TestAbstractRestInvocation.java
@@ -217,6 +217,17 @@ public class TestAbstractRestInvocation {
   }
 
   @Test
+  public void getContext() {
+    invocation.addContext("key", "test");
+    Assert.assertEquals("test", restInvocation.getContext("key"));
+  }
+
+  @Test
+  public void getContextNull() {
+    Assert.assertEquals(null, restInvocation.getContext("key"));
+  }
+
+  @Test
   public void invokeFilterHaveResponse(@Mocked HttpServerFilter filter) {
     Response response = Response.ok("");
     new Expectations() {
diff --git a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/impl/TraceIdElement.java b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/impl/TraceIdElement.java
new file mode 100644
index 0000000..bfc4b3b
--- /dev/null
+++ b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/impl/TraceIdElement.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl;
+
+import java.util.Map;
+
+import org.apache.servicecomb.common.rest.RestProducerInvocation;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.AccessLogParam;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.AccessLogElement;
+import org.springframework.util.StringUtils;
+
+public class TraceIdElement implements AccessLogElement {
+
+  private static final String TRACE_ID_NOT_FOUND = "-";
+
+  @Override
+  public String getFormattedElement(AccessLogParam accessLogParam) {
+    Map<String, Object> data = accessLogParam.getRoutingContext().data();
+    if (null == data) {
+      return TRACE_ID_NOT_FOUND;
+    }
+
+    RestProducerInvocation restProducerInvocation = (RestProducerInvocation) data
+        .get("servicecomb-rest-producer-invocation");
+    if (null == restProducerInvocation) {
+      return TRACE_ID_NOT_FOUND;
+    }
+
+    String traceId = restProducerInvocation.getContext("X-B3-TraceId");
+
+    if (StringUtils.isEmpty(traceId)) {
+      return TRACE_ID_NOT_FOUND;
+    }
+    return traceId;
+  }
+}
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
index 713d351..5bf5b65 100644
--- 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
@@ -42,10 +42,15 @@ import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.matcher.impl
 import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.matcher.impl.RequestHeaderElementMatcher;
 import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.matcher.impl.ResponseHeaderElementMatcher;
 import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.matcher.impl.StatusMatcher;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.matcher.impl.TraceIdMatcher;
 import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.matcher.impl.UriPathIncludeQueryMatcher;
 import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.matcher.impl.UriPathOnlyMatcher;
 import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.matcher.impl.VersionOrProtocolMatcher;
 
+/**
+ * contains all kinds of {@link AccessLogElementMatcher},
+ * generate a chain of {@link AccessLogElementExtraction} according to the raw access log pattern.
+ */
 public class DefaultAccessLogPatternParser implements AccessLogPatternParser {
   private static final List<AccessLogElementMatcher> MATCHER_LIST = Arrays.asList(
       new RequestHeaderElementMatcher(),
@@ -66,7 +71,8 @@ public class DefaultAccessLogPatternParser implements AccessLogPatternParser {
       new MethodMatcher(),
       new QueryOnlyMatcher(),
       new UriPathOnlyMatcher(),
-      new StatusMatcher());
+      new StatusMatcher(),
+      new TraceIdMatcher());
 
   public static final Comparator<AccessLogElementExtraction> ACCESS_LOG_ELEMENT_EXTRACTION_COMPARATOR = Comparator
       .comparingInt(AccessLogElementExtraction::getStart);
@@ -101,8 +107,8 @@ public class DefaultAccessLogPatternParser implements AccessLogPatternParser {
 
   /**
    * The content not matched in rawPattern will be printed as it is, so should be converted to {@link PlainTextElement}
-   * @param rawPattern
-   * @param extractionList
+   * @param rawPattern access log string pattern
+   * @param extractionList {@link AccessLogElementExtraction} list indicating the position of each access log element
    */
   private void fillInPlainTextElement(String rawPattern, List<AccessLogElementExtraction> extractionList) {
     int cursor = 0;
diff --git a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/matcher/impl/TraceIdMatcher.java b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/matcher/impl/TraceIdMatcher.java
new file mode 100644
index 0000000..d392494
--- /dev/null
+++ b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/matcher/impl/TraceIdMatcher.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.transport.rest.vertx.accesslog.parser.matcher.impl;
+
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.AccessLogElement;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.TraceIdElement;
+
+public class TraceIdMatcher extends SinglePatternImmutableElementMatcher {
+  public static final TraceIdElement ELEMENT = new TraceIdElement();
+
+  @Override
+  protected String getPlaceholderPattern() {
+    return "%SCB-traceId";
+  }
+
+  @Override
+  protected AccessLogElement getAccessLogElement() {
+    return ELEMENT;
+  }
+}
diff --git a/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/impl/TraceIdElementTest.java b/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/impl/TraceIdElementTest.java
new file mode 100644
index 0000000..86ededf
--- /dev/null
+++ b/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/impl/TraceIdElementTest.java
@@ -0,0 +1,106 @@
+/*
+ * 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.impl;
+
+import static org.hamcrest.core.Is.is;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.servicecomb.common.rest.RestProducerInvocation;
+import org.apache.servicecomb.core.Const;
+import org.apache.servicecomb.core.Invocation;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.AccessLogParam;
+import org.junit.Assert;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import io.vertx.ext.web.RoutingContext;
+import mockit.Deencapsulation;
+
+public class TraceIdElementTest {
+  private static final TraceIdElement ELEMENT = new TraceIdElement();
+
+  @Test
+  public void testGetFormattedElement() {
+    AccessLogParam param = new AccessLogParam();
+    RoutingContext routingContext = Mockito.mock(RoutingContext.class);
+    Map<String, Object> data = new HashMap<>();
+    RestProducerInvocation restProducerInvocation = new RestProducerInvocation();
+    Invocation invocation = Mockito.mock(Invocation.class);
+    String traceIdTest = "traceIdTest";
+
+    Mockito.when(invocation.getContext(Const.TRACE_ID_NAME)).thenReturn(traceIdTest);
+    Deencapsulation.setField(restProducerInvocation, "invocation", invocation);
+    Mockito.when(routingContext.data()).thenReturn(data);
+    data.put("servicecomb-rest-producer-invocation", restProducerInvocation);
+
+    param.setRoutingContext(routingContext);
+
+    String result = ELEMENT.getFormattedElement(param);
+    Assert.assertThat(result, is(traceIdTest));
+  }
+
+  @Test
+  public void testGetFormattedElementOnTraceIdNotFound() {
+    AccessLogParam param = new AccessLogParam();
+    RoutingContext routingContext = Mockito.mock(RoutingContext.class);
+    Map<String, Object> data = new HashMap<>();
+    RestProducerInvocation restProducerInvocation = new RestProducerInvocation();
+    Invocation invocation = Mockito.mock(Invocation.class);
+
+    Mockito.when(invocation.getContext(Const.TRACE_ID_NAME)).thenReturn("");
+    Deencapsulation.setField(restProducerInvocation, "invocation", invocation);
+    Mockito.when(routingContext.data()).thenReturn(data);
+    data.put("servicecomb-rest-producer-invocation", restProducerInvocation);
+
+    param.setRoutingContext(routingContext);
+
+    String result = ELEMENT.getFormattedElement(param);
+    Assert.assertThat(result, is("-"));
+
+    Mockito.when(invocation.getContext(Const.TRACE_ID_NAME)).thenReturn(null);
+    result = ELEMENT.getFormattedElement(param);
+    Assert.assertThat(result, is("-"));
+  }
+
+  @Test
+  public void testGetFormattedElementOnInvocationContextIsNull() {
+    AccessLogParam param = new AccessLogParam();
+    RoutingContext routingContext = Mockito.mock(RoutingContext.class);
+    Map<String, Object> data = new HashMap<>();
+
+    Mockito.when(routingContext.data()).thenReturn(data);
+    param.setRoutingContext(routingContext);
+
+    String result = ELEMENT.getFormattedElement(param);
+    Assert.assertThat(result, is("-"));
+  }
+
+  @Test
+  public void testGetFormattedElementOnDataIsNull() {
+    AccessLogParam param = new AccessLogParam();
+    RoutingContext routingContext = Mockito.mock(RoutingContext.class);
+
+    param.setRoutingContext(routingContext);
+    Mockito.when(routingContext.data()).thenReturn(null);
+
+    String result = ELEMENT.getFormattedElement(param);
+    Assert.assertThat(result, is("-"));
+  }
+}
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
index dd2f625..86f9942 100644
--- 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
@@ -18,11 +18,15 @@
 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.element.AccessLogElement;
 import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.BytesWrittenElement;
 import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.CookieElement;
 import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.DatetimeConfigurableElement;
@@ -38,10 +42,12 @@ import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.Remote
 import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.RequestHeaderElement;
 import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.ResponseHeaderElement;
 import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.StatusElement;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.TraceIdElement;
 import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.UriPathIncludeQueryElement;
 import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.UriPathOnlyElement;
 import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.VersionOrProtocolElement;
 import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.AccessLogElementExtraction;
+import org.hamcrest.Matchers;
 import org.junit.Test;
 
 import mockit.Deencapsulation;
@@ -52,40 +58,48 @@ public class DefaultAccessLogPatternParserTest {
       + "%{yyyy MM dd HH:mm:ss|GMT+0|en-US}t"
       + "%{incoming-header}i"
       + "%{outgoing-header}o"
-      + "%{cookie}c";
+      + "%{cookie}c"
+      + "%SCB-traceId";
 
   private static DefaultAccessLogPatternParser accessLogPatternParser = new DefaultAccessLogPatternParser();
 
   @Test
+  @SuppressWarnings(value = "unchecked")
   public void testParsePattern() {
     List<AccessLogElementExtraction> result = accessLogPatternParser.parsePattern(ROW_PATTERN);
-    assertEquals(26, result.size());
-    assertEquals(PlainTextElement.class, result.get(0).getAccessLogElement().getClass());
-    assertEquals(MethodElement.class, result.get(1).getAccessLogElement().getClass());
-    assertEquals(PlainTextElement.class, result.get(2).getAccessLogElement().getClass());
-    assertEquals(MethodElement.class, result.get(3).getAccessLogElement().getClass());
-    assertEquals(PlainTextElement.class, result.get(4).getAccessLogElement().getClass());
-    assertEquals(StatusElement.class, result.get(5).getAccessLogElement().getClass());
-    assertEquals(DurationSecondElement.class, result.get(6).getAccessLogElement().getClass());
-    assertEquals(DurationMillisecondElement.class, result.get(7).getAccessLogElement().getClass());
-    assertEquals(RemoteHostElement.class, result.get(8).getAccessLogElement().getClass());
-    assertEquals(LocalHostElement.class, result.get(9).getAccessLogElement().getClass());
-    assertEquals(LocalPortElement.class, result.get(10).getAccessLogElement().getClass());
-    assertEquals(BytesWrittenElement.class, result.get(11).getAccessLogElement().getClass());
-    assertEquals(BytesWrittenElement.class, result.get(12).getAccessLogElement().getClass());
-    assertEquals(FirstLineOfRequestElement.class, result.get(13).getAccessLogElement().getClass());
-    assertEquals(UriPathOnlyElement.class, result.get(14).getAccessLogElement().getClass());
-    assertEquals(QueryOnlyElement.class, result.get(15).getAccessLogElement().getClass());
-    assertEquals(UriPathOnlyElement.class, result.get(16).getAccessLogElement().getClass());
-    assertEquals(QueryOnlyElement.class, result.get(17).getAccessLogElement().getClass());
-    assertEquals(UriPathIncludeQueryElement.class, result.get(18).getAccessLogElement().getClass());
-    assertEquals(VersionOrProtocolElement.class, result.get(19).getAccessLogElement().getClass());
-    assertEquals(DatetimeConfigurableElement.class, result.get(20).getAccessLogElement().getClass());
-    assertEquals(DatetimeConfigurableElement.class, result.get(21).getAccessLogElement().getClass());
-    assertEquals(DatetimeConfigurableElement.class, result.get(22).getAccessLogElement().getClass());
-    assertEquals(RequestHeaderElement.class, result.get(23).getAccessLogElement().getClass());
-    assertEquals(ResponseHeaderElement.class, result.get(24).getAccessLogElement().getClass());
-    assertEquals(CookieElement.class, result.get(25).getAccessLogElement().getClass());
+    assertEquals(27, result.size());
+
+    assertThat(result.stream().map(AccessLogElementExtraction::getAccessLogElement)
+            .filter(Objects::nonNull).map(AccessLogElement::getClass)
+            .collect(Collectors.toList()),
+        Matchers.contains(
+            PlainTextElement.class,
+            MethodElement.class,
+            PlainTextElement.class,
+            MethodElement.class,
+            PlainTextElement.class,
+            StatusElement.class,
+            DurationSecondElement.class,
+            DurationMillisecondElement.class,
+            RemoteHostElement.class,
+            LocalHostElement.class,
+            LocalPortElement.class,
+            BytesWrittenElement.class,
+            BytesWrittenElement.class,
+            FirstLineOfRequestElement.class,
+            UriPathOnlyElement.class,
+            QueryOnlyElement.class,
+            UriPathOnlyElement.class,
+            QueryOnlyElement.class,
+            UriPathIncludeQueryElement.class,
+            VersionOrProtocolElement.class,
+            DatetimeConfigurableElement.class,
+            DatetimeConfigurableElement.class,
+            DatetimeConfigurableElement.class,
+            RequestHeaderElement.class,
+            ResponseHeaderElement.class,
+            CookieElement.class,
+            TraceIdElement.class));
   }
 
   @Test
diff --git a/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/matcher/impl/TraceIdMatcherTest.java b/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/matcher/impl/TraceIdMatcherTest.java
new file mode 100644
index 0000000..6b45cbf
--- /dev/null
+++ b/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/matcher/impl/TraceIdMatcherTest.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.transport.rest.vertx.accesslog.parser.matcher.impl;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
+
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.TraceIdElement;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.AccessLogElementExtraction;
+import org.junit.Test;
+
+public class TraceIdMatcherTest {
+  private static final TraceIdMatcher MATCHER = new TraceIdMatcher();
+
+  private static final String RAW_PATTERN = "%SCB-traceId %h %SCB-traceId %{PATTERN}t %SCB-traceId%SCB-traceId %H %SCB-traceId";
+
+  @Test
+  public void testExtractElementPlaceHolder() {
+    List<AccessLogElementExtraction> extractionList = MATCHER.extractElementPlaceholder(RAW_PATTERN);
+
+    assertEquals(5, extractionList.size());
+    assertEquals(0, extractionList.get(0).getStart());
+    assertEquals(12, extractionList.get(0).getEnd());
+    assertEquals(MATCHER.getAccessLogElement(), extractionList.get(0).getAccessLogElement());
+    assertEquals(16, extractionList.get(1).getStart());
+    assertEquals(28, extractionList.get(1).getEnd());
+    assertEquals(MATCHER.getAccessLogElement(), extractionList.get(1).getAccessLogElement());
+    assertEquals(41, extractionList.get(2).getStart());
+    assertEquals(53, extractionList.get(2).getEnd());
+    assertEquals(MATCHER.getAccessLogElement(), extractionList.get(2).getAccessLogElement());
+    assertEquals(53, extractionList.get(3).getStart());
+    assertEquals(65, extractionList.get(3).getEnd());
+    assertEquals(MATCHER.getAccessLogElement(), extractionList.get(3).getAccessLogElement());
+    assertEquals(69, extractionList.get(4).getStart());
+    assertEquals(81, extractionList.get(4).getEnd());
+    assertEquals(MATCHER.getAccessLogElement(), extractionList.get(4).getAccessLogElement());
+  }
+
+  @Test
+  public void testGetPlaceholderPattern() {
+    assertEquals("%SCB-traceId", MATCHER.getPlaceholderPattern());
+  }
+
+  @Test
+  public void getAccessLogElement() {
+    assertTrue(TraceIdElement.class.equals(MATCHER.getAccessLogElement().getClass()));
+  }
+}
\ No newline at end of file

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