You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@servicecomb.apache.org by GitBox <gi...@apache.org> on 2018/01/26 01:24:21 UTC

[GitHub] liubao68 closed pull request #530: [SCB-177] Support trace id in accesslog

liubao68 closed pull request #530: [SCB-177] Support trace id in accesslog
URL: https://github.com/apache/incubator-servicecomb-java-chassis/pull/530
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

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 2efcdd1f8..c787d7209 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 @@ protected void setContext() throws Exception {
     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 658640331..58d6c2eb5 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
@@ -216,6 +216,17 @@ public void setContextNormal() throws Exception {
     Assert.assertThat(invocation.getContext(), Matchers.hasEntry("name", "value"));
   }
 
+  @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("");
diff --git a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/impl/BytesWrittenV1Element.java b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/impl/BytesWrittenElement.java
similarity index 80%
rename from transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/impl/BytesWrittenV1Element.java
rename to transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/impl/BytesWrittenElement.java
index 58ac15ff5..2d88febe0 100644
--- a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/impl/BytesWrittenV1Element.java
+++ b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/impl/BytesWrittenElement.java
@@ -22,22 +22,22 @@
 
 import io.vertx.core.http.HttpServerResponse;
 
-/**
- * Zero bytes written as 0
- */
-public class BytesWrittenV1Element implements AccessLogElement {
+public class BytesWrittenElement implements AccessLogElement {
+  // print zeroBytes when bytes is zero
+  private final String zeroBytes;
 
-  public static final String ZERO_BYTES = "0";
+  public BytesWrittenElement(String zeroBytesPlaceholder) {
+    zeroBytes = zeroBytesPlaceholder;
+  }
 
   @Override
   public String getFormattedElement(AccessLogParam accessLogParam) {
     HttpServerResponse response = accessLogParam.getRoutingContext().response();
     if (null == response) {
-      return ZERO_BYTES;
+      return zeroBytes;
     }
 
     long bytesWritten = response.bytesWritten();
-
-    return String.valueOf(bytesWritten);
+    return 0 == bytesWritten ? zeroBytes : String.valueOf(bytesWritten);
   }
 }
diff --git a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/impl/BytesWrittenV2Element.java b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/impl/TraceIdElement.java
similarity index 60%
rename from transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/impl/BytesWrittenV2Element.java
rename to transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/impl/TraceIdElement.java
index c2f033841..bfc4b3bf7 100644
--- a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/impl/BytesWrittenV2Element.java
+++ b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/impl/TraceIdElement.java
@@ -17,30 +17,35 @@
 
 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;
 
-import io.vertx.core.http.HttpServerResponse;
-
-/**
- * Zero bytes written as -
- */
-public class BytesWrittenV2Element implements AccessLogElement {
+public class TraceIdElement implements AccessLogElement {
 
-  public static final String ZERO_BYTES = "-";
+  private static final String TRACE_ID_NOT_FOUND = "-";
 
   @Override
   public String getFormattedElement(AccessLogParam accessLogParam) {
-    HttpServerResponse response = accessLogParam.getRoutingContext().response();
-    if (null == response) {
-      return ZERO_BYTES;
+    Map<String, Object> data = accessLogParam.getRoutingContext().data();
+    if (null == data) {
+      return TRACE_ID_NOT_FOUND;
     }
 
-    long bytesWritten = response.bytesWritten();
-    if (0 == bytesWritten) {
-      return ZERO_BYTES;
+    RestProducerInvocation restProducerInvocation = (RestProducerInvocation) data
+        .get("servicecomb-rest-producer-invocation");
+    if (null == restProducerInvocation) {
+      return TRACE_ID_NOT_FOUND;
     }
 
-    return String.valueOf(bytesWritten);
+    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 713d3513d..5bf5b6572 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.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 @@
       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 @@ private void checkExtractionList(List<AccessLogElementExtraction> extractionList
 
   /**
    * 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/BytesWrittenV1Matcher.java b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/matcher/impl/BytesWrittenV1Matcher.java
index 406a60a8f..258d5b1ac 100644
--- a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/matcher/impl/BytesWrittenV1Matcher.java
+++ b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/matcher/impl/BytesWrittenV1Matcher.java
@@ -18,11 +18,11 @@
 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.BytesWrittenV1Element;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.BytesWrittenElement;
 
 public class BytesWrittenV1Matcher extends SinglePatternImmutableElementMatcher {
 
-  public static final BytesWrittenV1Element ELEMENT = new BytesWrittenV1Element();
+  public static final BytesWrittenElement ELEMENT = new BytesWrittenElement("0");
 
   @Override
   protected String getPlaceholderPattern() {
diff --git a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/matcher/impl/BytesWrittenV2Matcher.java b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/matcher/impl/BytesWrittenV2Matcher.java
index 2bba5778e..8b3307adc 100644
--- a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/matcher/impl/BytesWrittenV2Matcher.java
+++ b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/matcher/impl/BytesWrittenV2Matcher.java
@@ -18,11 +18,11 @@
 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.BytesWrittenV2Element;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.BytesWrittenElement;
 
 public class BytesWrittenV2Matcher extends SinglePatternImmutableElementMatcher {
 
-  public static final BytesWrittenV2Element ELEMENT = new BytesWrittenV2Element();
+  public static final BytesWrittenElement ELEMENT = new BytesWrittenElement("-");
 
   @Override
   protected String getPlaceholderPattern() {
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 000000000..d39249494
--- /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/BytesWrittenV1ElementTest.java b/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/impl/BytesWrittenElementTest.java
similarity index 93%
rename from transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/impl/BytesWrittenV1ElementTest.java
rename to transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/impl/BytesWrittenElementTest.java
index 91880a1cb..a85e08017 100644
--- a/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/impl/BytesWrittenV1ElementTest.java
+++ b/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/impl/BytesWrittenElementTest.java
@@ -26,16 +26,16 @@
 import io.vertx.core.http.HttpServerResponse;
 import io.vertx.ext.web.RoutingContext;
 
-public class BytesWrittenV1ElementTest {
+public class BytesWrittenElementTest {
 
-  private static final BytesWrittenV1Element ELEMENT = new BytesWrittenV1Element();
+  private static final BytesWrittenElement ELEMENT = new BytesWrittenElement("0");
 
   @Test
   public void getFormattedElement() {
     AccessLogParam param = new AccessLogParam();
     RoutingContext mockContext = Mockito.mock(RoutingContext.class);
     HttpServerResponse mockResponse = Mockito.mock(HttpServerResponse.class);
-    long bytesWritten = 16l;
+    long bytesWritten = 16L;
 
     param.setRoutingContext(mockContext);
     Mockito.when(mockContext.response()).thenReturn(mockResponse);
@@ -46,7 +46,6 @@ public void getFormattedElement() {
     assertEquals(String.valueOf(bytesWritten), result);
   }
 
-
   @Test
   public void getFormattedElementOnResponseIsNull() {
     AccessLogParam param = new AccessLogParam();
@@ -66,7 +65,7 @@ public void getFormattedElementOnBytesWrittenIsZero() {
     AccessLogParam param = new AccessLogParam();
     RoutingContext mockContext = Mockito.mock(RoutingContext.class);
     HttpServerResponse mockResponse = Mockito.mock(HttpServerResponse.class);
-    long bytesWritten = 0l;
+    long bytesWritten = 0L;
 
     param.setRoutingContext(mockContext);
     Mockito.when(mockContext.response()).thenReturn(mockResponse);
diff --git a/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/impl/BytesWrittenV2ElementTest.java b/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/impl/BytesWrittenV2ElementTest.java
deleted file mode 100644
index 691ee5c93..000000000
--- a/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/impl/BytesWrittenV2ElementTest.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.element.impl;
-
-import static org.junit.Assert.assertEquals;
-
-import org.apache.servicecomb.transport.rest.vertx.accesslog.AccessLogParam;
-import org.junit.Test;
-import org.mockito.Mockito;
-
-import io.vertx.core.http.HttpServerResponse;
-import io.vertx.ext.web.RoutingContext;
-
-public class BytesWrittenV2ElementTest {
-
-  public static final BytesWrittenV2Element ELEMENT = new BytesWrittenV2Element();
-
-  @Test
-  public void getFormattedElement() {
-    AccessLogParam param = new AccessLogParam();
-    RoutingContext mockContext = Mockito.mock(RoutingContext.class);
-    HttpServerResponse mockResponse = Mockito.mock(HttpServerResponse.class);
-    long bytesWritten = 16L;
-
-    param.setRoutingContext(mockContext);
-    Mockito.when(mockContext.response()).thenReturn(mockResponse);
-    Mockito.when(mockResponse.bytesWritten()).thenReturn(bytesWritten);
-
-    String result = ELEMENT.getFormattedElement(param);
-
-    assertEquals(String.valueOf(bytesWritten), result);
-  }
-
-
-  @Test
-  public void getFormattedElementOnResponseIsNull() {
-    AccessLogParam param = new AccessLogParam();
-    RoutingContext mockContext = Mockito.mock(RoutingContext.class);
-
-    param.setRoutingContext(mockContext);
-    Mockito.when(mockContext.response()).thenReturn(null);
-
-    String result = ELEMENT.getFormattedElement(param);
-
-    assertEquals("-", result);
-  }
-
-
-  @Test
-  public void getFormattedElementOnBytesWrittenIsZero() {
-    AccessLogParam param = new AccessLogParam();
-    RoutingContext mockContext = Mockito.mock(RoutingContext.class);
-    HttpServerResponse mockResponse = Mockito.mock(HttpServerResponse.class);
-    long bytesWritten = 0l;
-
-    param.setRoutingContext(mockContext);
-    Mockito.when(mockContext.response()).thenReturn(mockResponse);
-    Mockito.when(mockResponse.bytesWritten()).thenReturn(bytesWritten);
-
-    String result = ELEMENT.getFormattedElement(param);
-    assertEquals("-", result);
-  }
-}
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 000000000..86ededff5
--- /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 0566f0ca5..86f99420e 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,13 +18,16 @@
 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.impl.BytesWrittenV1Element;
-import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.BytesWrittenV2Element;
+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;
 import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.DurationMillisecondElement;
@@ -39,10 +42,12 @@
 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;
@@ -53,40 +58,48 @@
       + "%{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(BytesWrittenV1Element.class, result.get(11).getAccessLogElement().getClass());
-    assertEquals(BytesWrittenV2Element.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/BytesWrittenV1MatcherTest.java b/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/matcher/impl/BytesWrittenV1MatcherTest.java
index 4ae668190..3a52defb2 100644
--- a/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/matcher/impl/BytesWrittenV1MatcherTest.java
+++ b/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/matcher/impl/BytesWrittenV1MatcherTest.java
@@ -22,7 +22,7 @@
 
 import java.util.List;
 
-import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.BytesWrittenV1Element;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.BytesWrittenElement;
 import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.AccessLogElementExtraction;
 import org.junit.Test;
 
@@ -57,6 +57,6 @@ public void testGetPlaceholderPattern() {
 
   @Test
   public void getAccessLogElement() {
-    assertTrue(BytesWrittenV1Element.class.equals(MATCHER.getAccessLogElement().getClass()));
+    assertTrue(BytesWrittenElement.class.equals(MATCHER.getAccessLogElement().getClass()));
   }
 }
diff --git a/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/matcher/impl/BytesWrittenV2MatcherTest.java b/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/matcher/impl/BytesWrittenV2MatcherTest.java
index d8418f102..01f87897d 100644
--- a/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/matcher/impl/BytesWrittenV2MatcherTest.java
+++ b/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/matcher/impl/BytesWrittenV2MatcherTest.java
@@ -22,7 +22,7 @@
 
 import java.util.List;
 
-import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.BytesWrittenV2Element;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.BytesWrittenElement;
 import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.AccessLogElementExtraction;
 import org.junit.Test;
 
@@ -57,6 +57,6 @@ public void testGetPlaceholderPattern() {
 
   @Test
   public void getAccessLogElement() {
-    assertTrue(BytesWrittenV2Element.class.equals(MATCHER.getAccessLogElement().getClass()));
+    assertTrue(BytesWrittenElement.class.equals(MATCHER.getAccessLogElement().getClass()));
   }
 }
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 000000000..6b45cbf07
--- /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


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services