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 2024/05/21 03:59:16 UTC

(servicecomb-java-chassis) branch master updated: [SCB-2880]able to inherit trace in edge service from web (#4339)

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/servicecomb-java-chassis.git


The following commit(s) were added to refs/heads/master by this push:
     new 633e8e2c7 [SCB-2880]able to inherit trace in edge service from web (#4339)
633e8e2c7 is described below

commit 633e8e2c704e792a465d334269885b7c03da28a3
Author: liubao68 <bi...@qq.com>
AuthorDate: Tue May 21 11:59:09 2024 +0800

    [SCB-2880]able to inherit trace in edge service from web (#4339)
---
 .../protobuf/definition/OperationProtobuf.java     |  4 +-
 .../internal/converter/TestSchemaMetaCodec.java    |  8 ++--
 .../converter/TestSchemaMetaCodecRestTemplate.java |  8 ++--
 .../org/apache/servicecomb/core/Invocation.java    | 10 ++---
 .../core/exception/DefaultExceptionProcessor.java  |  2 +-
 .../servicecomb/core/governance/MatchType.java     |  8 ++--
 .../core/provider/consumer/InvokerUtils.java       |  6 +--
 .../servicecomb/core/tracing/TraceIdLogger.java    |  2 +-
 .../core/invocation/TestInvocationStageTrace.java  |  2 +-
 .../demo/pojo/client/CodeFirstPojoClient.java      |  4 +-
 .../edge/core/EdgeInvocationCreator.java           |  2 +-
 .../tracing/zipkin/CustomHttpRequestParser.java    |  5 ++-
 .../tracing/zipkin/CustomHttpResponseParser.java   |  7 +++-
 .../tracing/zipkin/HttpClientRequestWrapper.java   |  2 +-
 .../tracing/zipkin/HttpClientResponseWrapper.java  |  2 +-
 .../tracing/zipkin/HttpServeRequestWrapper.java    | 16 ++++++--
 .../tracing/zipkin/TracingConfiguration.java       |  8 ++--
 .../tracing/zipkin/ZipkinTracingFilter.java        | 45 ++++++++++++++++++++--
 .../metrics/core/InvocationMetersInitializer.java  |  9 ++---
 .../meter/invocation/AbstractInvocationMeters.java |  8 +---
 .../metrics/core/publish/SlowInvocationLogger.java |  2 +-
 .../core/TestInvocationMetersInitializer.java      |  2 +-
 .../core/publish/TestSlowInvocationLogger.java     | 10 ++---
 23 files changed, 107 insertions(+), 65 deletions(-)

diff --git a/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/definition/OperationProtobuf.java b/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/definition/OperationProtobuf.java
index 221820761..5c22ad8c7 100644
--- a/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/definition/OperationProtobuf.java
+++ b/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/definition/OperationProtobuf.java
@@ -117,7 +117,7 @@ public class OperationProtobuf {
     ProtoMapper mapper = scopedProtobufSchemaManager.getOrCreateProtoMapper(invocation.getSchemaMeta());
     Message requestMessage = mapper.getRequestMessage(invocation.getOperationMeta().getOperationId());
 
-    if (!invocation.isConsumer()) {
+    if (invocation.isProducer()) {
       initProducerRequestCodec(invocation, requestMessage, mapper);
     } else {
       initConsumerRequestCodec(invocation, requestMessage, mapper);
@@ -167,7 +167,7 @@ public class OperationProtobuf {
     Message responseMessage = mapper.getResponseMessage(invocation.getOperationMeta().getOperationId());
 
     JavaType responseType = invocation.findResponseType(Status.OK.getStatusCode());
-    if (!invocation.isConsumer()) {
+    if (invocation.isProducer()) {
       initProviderResponseCode(responseMessage, mapper, responseType);
     } else {
       initConsumerResponseCode(responseMessage, mapper, responseType);
diff --git a/common/common-protobuf/src/test/java/org/apache/servicecomb/codec/protobuf/internal/converter/TestSchemaMetaCodec.java b/common/common-protobuf/src/test/java/org/apache/servicecomb/codec/protobuf/internal/converter/TestSchemaMetaCodec.java
index 17efb6eb5..141b7cf4b 100644
--- a/common/common-protobuf/src/test/java/org/apache/servicecomb/codec/protobuf/internal/converter/TestSchemaMetaCodec.java
+++ b/common/common-protobuf/src/test/java/org/apache/servicecomb/codec/protobuf/internal/converter/TestSchemaMetaCodec.java
@@ -118,18 +118,18 @@ public class TestSchemaMetaCodec {
 
   private Invocation mockInvocation(String operation, InvocationType invocationType) {
     OperationMeta operationMeta;
-    boolean isConsumer;
+    boolean isProvider;
     Invocation invocation = Mockito.mock(Invocation.class);
     InvocationRuntimeType invocationRuntimeType;
 
     if (InvocationType.CONSUMER == invocationType) {
       operationMeta = consumerSchemaMeta.getOperations().get(operation);
-      isConsumer = true;
+      isProvider = false;
       Mockito.when(invocation.getSchemaMeta()).thenReturn(consumerSchemaMeta);
       invocationRuntimeType = operationMeta.buildBaseConsumerRuntimeType();
     } else {
       operationMeta = providerSchemaMeta.getOperations().get(operation);
-      isConsumer = false;
+      isProvider = true;
       Mockito.when(invocation.getSchemaMeta()).thenReturn(providerSchemaMeta);
       invocationRuntimeType = operationMeta.buildBaseProviderRuntimeType();
     }
@@ -143,7 +143,7 @@ public class TestSchemaMetaCodec {
     Mockito.when(invocation.getInvocationType()).thenReturn(invocationType);
     Mockito.when(invocation.getMicroserviceMeta()).thenReturn(microserviceMeta);
 
-    Mockito.when(invocation.isConsumer()).thenReturn(isConsumer);
+    Mockito.when(invocation.isProducer()).thenReturn(isProvider);
     return invocation;
   }
 
diff --git a/common/common-protobuf/src/test/java/org/apache/servicecomb/codec/protobuf/internal/converter/TestSchemaMetaCodecRestTemplate.java b/common/common-protobuf/src/test/java/org/apache/servicecomb/codec/protobuf/internal/converter/TestSchemaMetaCodecRestTemplate.java
index 985fcd62c..2a861d202 100644
--- a/common/common-protobuf/src/test/java/org/apache/servicecomb/codec/protobuf/internal/converter/TestSchemaMetaCodecRestTemplate.java
+++ b/common/common-protobuf/src/test/java/org/apache/servicecomb/codec/protobuf/internal/converter/TestSchemaMetaCodecRestTemplate.java
@@ -99,18 +99,18 @@ public class TestSchemaMetaCodecRestTemplate {
 
   private Invocation mockInvocation(String operation, InvocationType invocationType) {
     OperationMeta operationMeta;
-    boolean isConsumer;
+    boolean isProvider;
     Invocation invocation = Mockito.mock(Invocation.class);
     InvocationRuntimeType invocationRuntimeType;
 
     if (InvocationType.CONSUMER == invocationType) {
       operationMeta = consumerSchemaMeta.getOperations().get(operation);
-      isConsumer = true;
+      isProvider = false;
       Mockito.when(invocation.getSchemaMeta()).thenReturn(consumerSchemaMeta);
       invocationRuntimeType = operationMeta.buildBaseConsumerRuntimeType();
     } else {
       operationMeta = providerSchemaMeta.getOperations().get(operation);
-      isConsumer = false;
+      isProvider = true;
       Mockito.when(invocation.getSchemaMeta()).thenReturn(providerSchemaMeta);
       invocationRuntimeType = operationMeta.buildBaseProviderRuntimeType();
     }
@@ -124,7 +124,7 @@ public class TestSchemaMetaCodecRestTemplate {
     Mockito.when(invocation.getInvocationType()).thenReturn(invocationType);
     Mockito.when(invocation.getMicroserviceMeta()).thenReturn(microserviceMeta);
 
-    Mockito.when(invocation.isConsumer()).thenReturn(isConsumer);
+    Mockito.when(invocation.isProducer()).thenReturn(isProvider);
     return invocation;
   }
 
diff --git a/core/src/main/java/org/apache/servicecomb/core/Invocation.java b/core/src/main/java/org/apache/servicecomb/core/Invocation.java
index 11fe585f5..08628a209 100644
--- a/core/src/main/java/org/apache/servicecomb/core/Invocation.java
+++ b/core/src/main/java/org/apache/servicecomb/core/Invocation.java
@@ -92,10 +92,6 @@ public class Invocation extends SwaggerInvocation {
 
   private boolean finished;
 
-  // not extend InvocationType
-  // because isEdge() only affect to apm/metrics output, no need to change so many logic
-  private boolean edge;
-
   private long invocationId;
 
   private TraceIdLogger traceIdLogger;
@@ -399,11 +395,11 @@ public class Invocation extends SwaggerInvocation {
   }
 
   public boolean isEdge() {
-    return edge;
+    return InvocationType.EDGE.equals(invocationType);
   }
 
-  public void setEdge(boolean edge) {
-    this.edge = edge;
+  public void setEdge() {
+    this.invocationType = InvocationType.EDGE;
   }
 
   public long getInvocationId() {
diff --git a/core/src/main/java/org/apache/servicecomb/core/exception/DefaultExceptionProcessor.java b/core/src/main/java/org/apache/servicecomb/core/exception/DefaultExceptionProcessor.java
index f0f101f91..e8817af52 100644
--- a/core/src/main/java/org/apache/servicecomb/core/exception/DefaultExceptionProcessor.java
+++ b/core/src/main/java/org/apache/servicecomb/core/exception/DefaultExceptionProcessor.java
@@ -61,7 +61,7 @@ public class DefaultExceptionProcessor implements ExceptionProcessor {
       .map(converter -> (ExceptionConverter<Throwable>) converter)
       .collect(Collectors.toList());
 
-  @InjectProperty(keys = "print-stack-trace", defaultValue = "false")
+  @InjectProperty(keys = "print-stack-trace", defaultValue = "true")
   protected boolean printStackTrace;
 
   @InjectProperty(keys = "print-rate-limit", defaultValue = "false")
diff --git a/core/src/main/java/org/apache/servicecomb/core/governance/MatchType.java b/core/src/main/java/org/apache/servicecomb/core/governance/MatchType.java
index c6adef1f7..2c1006706 100644
--- a/core/src/main/java/org/apache/servicecomb/core/governance/MatchType.java
+++ b/core/src/main/java/org/apache/servicecomb/core/governance/MatchType.java
@@ -35,7 +35,7 @@ public final class MatchType {
     @Override
     public String apiPath() {
       if (MatchType.REST.equalsIgnoreCase(invocation.getOperationMeta().getConfig().getGovernanceMatchType())) {
-        if (invocation.isConsumer()) {
+        if (!invocation.isProducer()) {
           return concatAbsolutePath(SwaggerUtils.getBasePath(invocation.getSchemaMeta().getSwagger()),
               invocation.getOperationMeta().getOperationPath());
         }
@@ -45,7 +45,7 @@ public final class MatchType {
         }
       }
 
-      if (invocation.isConsumer()) {
+      if (!invocation.isProducer()) {
         return invocation.getOperationMeta().getMicroserviceQualifiedName();
       }
       return invocation.getOperationMeta().getSchemaQualifiedName();
@@ -85,7 +85,7 @@ public final class MatchType {
 
     @Override
     public String instanceId() {
-      if (invocation.isConsumer()) {
+      if (!invocation.isProducer()) {
         if (invocation.getEndpoint() != null && invocation.getEndpoint().getMicroserviceInstance() != null) {
           return invocation.getEndpoint().getMicroserviceInstance().getInstanceId();
         }
@@ -95,7 +95,7 @@ public final class MatchType {
 
     @Override
     public String serviceName() {
-      if (invocation.isConsumer()) {
+      if (!invocation.isProducer()) {
         return invocation.getMicroserviceName();
       }
       return null;
diff --git a/core/src/main/java/org/apache/servicecomb/core/provider/consumer/InvokerUtils.java b/core/src/main/java/org/apache/servicecomb/core/provider/consumer/InvokerUtils.java
index d850cf6b6..152f43a50 100644
--- a/core/src/main/java/org/apache/servicecomb/core/provider/consumer/InvokerUtils.java
+++ b/core/src/main/java/org/apache/servicecomb/core/provider/consumer/InvokerUtils.java
@@ -37,7 +37,6 @@ import org.apache.servicecomb.core.invocation.InvocationFactory;
 import org.apache.servicecomb.foundation.common.utils.AsyncUtils;
 import org.apache.servicecomb.swagger.invocation.AsyncResponse;
 import org.apache.servicecomb.swagger.invocation.Response;
-import org.apache.servicecomb.swagger.invocation.context.ContextUtils;
 import org.apache.servicecomb.swagger.invocation.exception.CommonExceptionData;
 import org.apache.servicecomb.swagger.invocation.exception.ExceptionFactory;
 import org.apache.servicecomb.swagger.invocation.exception.InvocationException;
@@ -187,9 +186,6 @@ public final class InvokerUtils {
     return invocation.getMicroserviceMeta().getConsumerFilterChain()
         .onFilter(invocation)
         .exceptionally(throwable -> toConsumerResponse(invocation, throwable))
-        .whenComplete((response, throwable) -> {
-          ContextUtils.setInvocationContext(invocation.getParentContext());
-          invocation.onFinish(response);
-        });
+        .whenComplete((response, throwable) -> invocation.onFinish(response));
   }
 }
diff --git a/core/src/main/java/org/apache/servicecomb/core/tracing/TraceIdLogger.java b/core/src/main/java/org/apache/servicecomb/core/tracing/TraceIdLogger.java
index 18f0e3664..3819bb902 100644
--- a/core/src/main/java/org/apache/servicecomb/core/tracing/TraceIdLogger.java
+++ b/core/src/main/java/org/apache/servicecomb/core/tracing/TraceIdLogger.java
@@ -23,7 +23,7 @@ import org.slf4j.MDC;
 import org.slf4j.Marker;
 
 public class TraceIdLogger {
-  private static final Logger LOGGER = LoggerFactory.getLogger("scb-trace");
+  private static final Logger LOGGER = LoggerFactory.getLogger("scb-trace-id");
 
   private static final Marker MARKER = new ScbMarker();
 
diff --git a/core/src/test/java/org/apache/servicecomb/core/invocation/TestInvocationStageTrace.java b/core/src/test/java/org/apache/servicecomb/core/invocation/TestInvocationStageTrace.java
index 62f0dc0fa..5b9c7040c 100644
--- a/core/src/test/java/org/apache/servicecomb/core/invocation/TestInvocationStageTrace.java
+++ b/core/src/test/java/org/apache/servicecomb/core/invocation/TestInvocationStageTrace.java
@@ -137,7 +137,7 @@ public class TestInvocationStageTrace {
   public void edge() {
     invocation = new Invocation(referenceConfig, operationMeta, invocationRuntimeType, args);
     stageTrace = new InvocationStageTrace(invocation);
-    invocation.setEdge(true);
+    invocation.setEdge();
 
     stageTrace.startCreateInvocation(1);
     nanoTime = 2;
diff --git a/demo/demo-pojo/pojo-client/src/main/java/org/apache/servicecomb/demo/pojo/client/CodeFirstPojoClient.java b/demo/demo-pojo/pojo-client/src/main/java/org/apache/servicecomb/demo/pojo/client/CodeFirstPojoClient.java
index dbc1bc2eb..7d3386fa3 100644
--- a/demo/demo-pojo/pojo-client/src/main/java/org/apache/servicecomb/demo/pojo/client/CodeFirstPojoClient.java
+++ b/demo/demo-pojo/pojo-client/src/main/java/org/apache/servicecomb/demo/pojo/client/CodeFirstPojoClient.java
@@ -107,7 +107,9 @@ public class CodeFirstPojoClient implements CategorizedTestCase {
           .thenCompose(result -> {
             TestMgr.check("someone sayhi, context k: v", result);
 
-            TestMgr.check(true, context == ContextUtils.getInvocationContext());
+            // new call need set invocation context implicitly or will not
+            // inherit parent context
+            ContextUtils.setInvocationContext(context);
 
             return ((CodeFirstPojoClientIntf) codeFirst).sayHiAsync("someone 1");
           })
diff --git a/edge/edge-core/src/main/java/org/apache/servicecomb/edge/core/EdgeInvocationCreator.java b/edge/edge-core/src/main/java/org/apache/servicecomb/edge/core/EdgeInvocationCreator.java
index 8f3bbedf1..5379515af 100644
--- a/edge/edge-core/src/main/java/org/apache/servicecomb/edge/core/EdgeInvocationCreator.java
+++ b/edge/edge-core/src/main/java/org/apache/servicecomb/edge/core/EdgeInvocationCreator.java
@@ -84,7 +84,7 @@ public class EdgeInvocationCreator extends RestVertxProducerInvocationCreator {
         restOperationMeta.getOperationMeta().buildBaseConsumerRuntimeType(),
         null);
     invocation.setSync(false);
-    invocation.setEdge(true);
+    invocation.setEdge();
     invocation.addLocalContext(EDGE_INVOCATION_CONTEXT, Vertx.currentContext());
 
     return invocation;
diff --git a/handlers/handler-tracing-zipkin/src/main/java/org/apache/servicecomb/tracing/zipkin/CustomHttpRequestParser.java b/handlers/handler-tracing-zipkin/src/main/java/org/apache/servicecomb/tracing/zipkin/CustomHttpRequestParser.java
index 7fc617a87..32fb87520 100644
--- a/handlers/handler-tracing-zipkin/src/main/java/org/apache/servicecomb/tracing/zipkin/CustomHttpRequestParser.java
+++ b/handlers/handler-tracing-zipkin/src/main/java/org/apache/servicecomb/tracing/zipkin/CustomHttpRequestParser.java
@@ -24,12 +24,15 @@ import brave.http.HttpRequestParser;
 import brave.http.HttpTags;
 import brave.propagation.TraceContext;
 
-public record CustomHttpRequestParser(boolean client) implements HttpRequestParser {
+public record CustomHttpRequestParser() implements HttpRequestParser {
   @Override
   public void parse(HttpRequest req, TraceContext context, SpanCustomizer span) {
     Invocation invocation = ((InvocationAware) req).getInvocation();
     span.name(invocation.getInvocationQualifiedName());
     HttpTags.METHOD.tag(req, context, span);
     HttpTags.PATH.tag(req, context, span);
+    if (!invocation.isConsumer()) { // server or edge
+      HttpTags.ROUTE.tag(req, context, span);
+    }
   }
 }
diff --git a/handlers/handler-tracing-zipkin/src/main/java/org/apache/servicecomb/tracing/zipkin/CustomHttpResponseParser.java b/handlers/handler-tracing-zipkin/src/main/java/org/apache/servicecomb/tracing/zipkin/CustomHttpResponseParser.java
index 4edcf0899..bb59f7e93 100644
--- a/handlers/handler-tracing-zipkin/src/main/java/org/apache/servicecomb/tracing/zipkin/CustomHttpResponseParser.java
+++ b/handlers/handler-tracing-zipkin/src/main/java/org/apache/servicecomb/tracing/zipkin/CustomHttpResponseParser.java
@@ -16,6 +16,8 @@
  */
 package org.apache.servicecomb.tracing.zipkin;
 
+import org.apache.servicecomb.core.Invocation;
+
 import brave.SpanCustomizer;
 import brave.Tags;
 import brave.http.HttpResponse;
@@ -23,14 +25,15 @@ import brave.http.HttpResponseParser;
 import brave.http.HttpTags;
 import brave.propagation.TraceContext;
 
-public record CustomHttpResponseParser(boolean client) implements HttpResponseParser {
+public record CustomHttpResponseParser() implements HttpResponseParser {
   @Override
   public void parse(HttpResponse response, TraceContext context, SpanCustomizer span) {
+    Invocation invocation = ((InvocationAware) response).getInvocation();
     HttpTags.STATUS_CODE.tag(response, context, span);
     if (response.error() != null) {
       span.tag(Tags.ERROR.key(), response.error().getMessage());
     }
-    if (client) {
+    if (!invocation.isProducer()) { // client or edge
       span.tag(HttpTags.ROUTE.key(), response.route());
     }
   }
diff --git a/handlers/handler-tracing-zipkin/src/main/java/org/apache/servicecomb/tracing/zipkin/HttpClientRequestWrapper.java b/handlers/handler-tracing-zipkin/src/main/java/org/apache/servicecomb/tracing/zipkin/HttpClientRequestWrapper.java
index e18eeb9a3..cc758d68a 100644
--- a/handlers/handler-tracing-zipkin/src/main/java/org/apache/servicecomb/tracing/zipkin/HttpClientRequestWrapper.java
+++ b/handlers/handler-tracing-zipkin/src/main/java/org/apache/servicecomb/tracing/zipkin/HttpClientRequestWrapper.java
@@ -50,7 +50,7 @@ class HttpClientRequestWrapper extends HttpClientRequest implements InvocationAw
 
   @Override
   public String url() {
-    return invocation.getEndpoint().getEndpoint();
+    return invocation.getInvocationQualifiedName();
   }
 
   @Override
diff --git a/handlers/handler-tracing-zipkin/src/main/java/org/apache/servicecomb/tracing/zipkin/HttpClientResponseWrapper.java b/handlers/handler-tracing-zipkin/src/main/java/org/apache/servicecomb/tracing/zipkin/HttpClientResponseWrapper.java
index 93a833981..b939efaa6 100644
--- a/handlers/handler-tracing-zipkin/src/main/java/org/apache/servicecomb/tracing/zipkin/HttpClientResponseWrapper.java
+++ b/handlers/handler-tracing-zipkin/src/main/java/org/apache/servicecomb/tracing/zipkin/HttpClientResponseWrapper.java
@@ -58,6 +58,6 @@ class HttpClientResponseWrapper extends HttpClientResponse implements Invocation
 
   @Override
   public Invocation getInvocation() {
-    return null;
+    return invocation;
   }
 }
diff --git a/handlers/handler-tracing-zipkin/src/main/java/org/apache/servicecomb/tracing/zipkin/HttpServeRequestWrapper.java b/handlers/handler-tracing-zipkin/src/main/java/org/apache/servicecomb/tracing/zipkin/HttpServeRequestWrapper.java
index e1a71f83f..45725539b 100644
--- a/handlers/handler-tracing-zipkin/src/main/java/org/apache/servicecomb/tracing/zipkin/HttpServeRequestWrapper.java
+++ b/handlers/handler-tracing-zipkin/src/main/java/org/apache/servicecomb/tracing/zipkin/HttpServeRequestWrapper.java
@@ -17,6 +17,7 @@
 
 package org.apache.servicecomb.tracing.zipkin;
 
+import org.apache.commons.lang3.StringUtils;
 import org.apache.servicecomb.core.Invocation;
 
 import brave.http.HttpServerRequest;
@@ -40,12 +41,21 @@ class HttpServeRequestWrapper extends HttpServerRequest implements InvocationAwa
 
   @Override
   public String url() {
-    return invocation.getEndpoint().getEndpoint();
+    return invocation.getInvocationQualifiedName();
   }
 
   @Override
-  public String header(String key) {
-    return invocation.getContext(key);
+  public String route() {
+    return invocation.getRequestEx() != null ? invocation.getRequestEx().getRemoteAddr() : null;
+  }
+
+  @Override
+  public String header(String name) {
+    String result = invocation.getContext(name);
+    if (StringUtils.isEmpty(result) && invocation.getRequestEx() != null) {
+      result = invocation.getRequestEx().getHeader(name);
+    }
+    return result;
   }
 
   @Override
diff --git a/handlers/handler-tracing-zipkin/src/main/java/org/apache/servicecomb/tracing/zipkin/TracingConfiguration.java b/handlers/handler-tracing-zipkin/src/main/java/org/apache/servicecomb/tracing/zipkin/TracingConfiguration.java
index 26059b1ca..dae03aee8 100644
--- a/handlers/handler-tracing-zipkin/src/main/java/org/apache/servicecomb/tracing/zipkin/TracingConfiguration.java
+++ b/handlers/handler-tracing-zipkin/src/main/java/org/apache/servicecomb/tracing/zipkin/TracingConfiguration.java
@@ -125,10 +125,10 @@ public class TracingConfiguration {
   @Bean
   HttpTracing httpTracing(Tracing tracing) {
     return HttpTracing.newBuilder(tracing)
-        .clientRequestParser(new CustomHttpRequestParser(true))
-        .clientResponseParser(new CustomHttpResponseParser(true))
-        .serverRequestParser(new CustomHttpRequestParser(false))
-        .serverResponseParser(new CustomHttpResponseParser(false)).build();
+        .clientRequestParser(new CustomHttpRequestParser())
+        .clientResponseParser(new CustomHttpResponseParser())
+        .serverRequestParser(new CustomHttpRequestParser())
+        .serverResponseParser(new CustomHttpResponseParser()).build();
   }
 
   @Bean
diff --git a/handlers/handler-tracing-zipkin/src/main/java/org/apache/servicecomb/tracing/zipkin/ZipkinTracingFilter.java b/handlers/handler-tracing-zipkin/src/main/java/org/apache/servicecomb/tracing/zipkin/ZipkinTracingFilter.java
index 9a6ae075b..f88532adf 100644
--- a/handlers/handler-tracing-zipkin/src/main/java/org/apache/servicecomb/tracing/zipkin/ZipkinTracingFilter.java
+++ b/handlers/handler-tracing-zipkin/src/main/java/org/apache/servicecomb/tracing/zipkin/ZipkinTracingFilter.java
@@ -41,13 +41,23 @@ public class ZipkinTracingFilter {
 
   public static final String CONTEXT_TRACE_SPAN = "x-trace-span";
 
-  @Autowired
+  public static final String CONTEXT_TRACE_EDGE_REQUEST = "x-trace-edge-request";
+
+  public static final String CONTEXT_TRACE_EDGE_HANDLER = "x-trace-edge-handler";
+
+  public static final String CONTEXT_TRACE_EDGE_SPAN = "x-trace-edge-span";
+
   private HttpTracing httpTracing;
 
   public ZipkinTracingFilter() {
     EventManager.register(this);
   }
 
+  @Autowired
+  public void setHttpTracing(HttpTracing httpTracing) {
+    this.httpTracing = httpTracing;
+  }
+
   @Subscribe
   public void onInvocationStartEvent(InvocationStartEvent event) {
     Invocation invocation = event.getInvocation();
@@ -59,7 +69,7 @@ public class ZipkinTracingFilter {
       invocation.addLocalContext(CONTEXT_TRACE_SPAN, span);
       invocation.addLocalContext(CONTEXT_TRACE_HANDLER, handler);
       invocation.addLocalContext(CONTEXT_TRACE_REQUEST, request);
-    } else {
+    } else if (invocation.isConsumer()) {
       Span parentSpan = invocation.getLocalContext(CONTEXT_TRACE_SPAN);
       HttpClientHandler<HttpClientRequest, HttpClientResponse> handler = HttpClientHandler.create(httpTracing);
       HttpClientRequestWrapper request = new HttpClientRequestWrapper(invocation);
@@ -67,6 +77,22 @@ public class ZipkinTracingFilter {
       invocation.addLocalContext(CONTEXT_TRACE_HANDLER, handler);
       invocation.addLocalContext(CONTEXT_TRACE_REQUEST, request);
       invocation.addLocalContext(CONTEXT_TRACE_SPAN, span);
+    } else {
+      // edge as server
+      HttpServerHandler<HttpServerRequest, HttpServerResponse> serverHandler = HttpServerHandler.create(httpTracing);
+      HttpServeRequestWrapper serverRequest = new HttpServeRequestWrapper(invocation);
+      Span serverSpan = serverHandler.handleReceive(serverRequest);
+      invocation.addLocalContext(CONTEXT_TRACE_EDGE_SPAN, serverSpan);
+      invocation.addLocalContext(CONTEXT_TRACE_EDGE_HANDLER, serverHandler);
+      invocation.addLocalContext(CONTEXT_TRACE_EDGE_REQUEST, serverRequest);
+
+      // edge as client
+      HttpClientHandler<HttpClientRequest, HttpClientResponse> clientHandler = HttpClientHandler.create(httpTracing);
+      HttpClientRequestWrapper clientRequest = new HttpClientRequestWrapper(invocation);
+      Span clientSpan = clientHandler.handleSendWithParent(clientRequest, serverSpan.context());
+      invocation.addLocalContext(CONTEXT_TRACE_HANDLER, clientHandler);
+      invocation.addLocalContext(CONTEXT_TRACE_REQUEST, clientRequest);
+      invocation.addLocalContext(CONTEXT_TRACE_SPAN, clientSpan);
     }
   }
 
@@ -79,12 +105,25 @@ public class ZipkinTracingFilter {
       Span span = invocation.getLocalContext(CONTEXT_TRACE_SPAN);
       handler.handleSend(new HttpServerResponseWrapper(invocation, event.getResponse(),
           invocation.getLocalContext(CONTEXT_TRACE_REQUEST)), span);
-    } else {
+    } else if (invocation.isConsumer()) {
       HttpClientHandler<HttpClientRequest, HttpClientResponse> handler
           = invocation.getLocalContext(CONTEXT_TRACE_HANDLER);
       Span span = invocation.getLocalContext(CONTEXT_TRACE_SPAN);
       handler.handleReceive(new HttpClientResponseWrapper(invocation, event.getResponse(),
           invocation.getLocalContext(CONTEXT_TRACE_REQUEST)), span);
+    } else {
+      // edge as client
+      HttpClientHandler<HttpClientRequest, HttpClientResponse> clientHandler
+          = invocation.getLocalContext(CONTEXT_TRACE_HANDLER);
+      Span clientSpan = invocation.getLocalContext(CONTEXT_TRACE_SPAN);
+      clientHandler.handleReceive(new HttpClientResponseWrapper(invocation, event.getResponse(),
+          invocation.getLocalContext(CONTEXT_TRACE_REQUEST)), clientSpan);
+      // edge as server
+      HttpServerHandler<HttpServerRequest, HttpServerResponse> serverHandler
+          = invocation.getLocalContext(CONTEXT_TRACE_EDGE_HANDLER);
+      Span serverSpan = invocation.getLocalContext(CONTEXT_TRACE_EDGE_SPAN);
+      serverHandler.handleSend(new HttpServerResponseWrapper(invocation, event.getResponse(),
+          invocation.getLocalContext(CONTEXT_TRACE_EDGE_REQUEST)), serverSpan);
     }
   }
 }
diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/InvocationMetersInitializer.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/InvocationMetersInitializer.java
index 4777fa347..25bc9b62e 100644
--- a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/InvocationMetersInitializer.java
+++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/InvocationMetersInitializer.java
@@ -50,11 +50,10 @@ public class InvocationMetersInitializer implements MetricsInitializer {
 
   protected AbstractInvocationMeters findInvocationMeters(Invocation invocation) {
     if (invocation.isConsumer()) {
-      if (invocation.isEdge()) {
-        return edgeMeters.getInvocationMeters();
-      } else {
-        return consumerMeters.getInvocationMeters();
-      }
+      return consumerMeters.getInvocationMeters();
+    }
+    if (invocation.isEdge()) {
+      return edgeMeters.getInvocationMeters();
     }
     return producerMeters.getInvocationMeters();
   }
diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/invocation/AbstractInvocationMeters.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/invocation/AbstractInvocationMeters.java
index 6c696a570..30e8e2987 100644
--- a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/invocation/AbstractInvocationMeters.java
+++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/invocation/AbstractInvocationMeters.java
@@ -46,13 +46,7 @@ public abstract class AbstractInvocationMeters {
   protected AbstractInvocationMeter getOrCreateMeters(Invocation invocation, Response response) {
     // build string key is faster than use Id to locate timer directly
     StringBuilder keyBuilder = new StringBuilder(maxKeyLen);
-    String invocationName;
-    //check edge
-    if (invocation.isConsumer() && invocation.isEdge()) {
-      invocationName = MeterInvocationConst.EDGE_INVOCATION_NAME;
-    } else {
-      invocationName = invocation.getInvocationType().name();
-    }
+    String invocationName = invocation.getInvocationType().name();
 
     keyBuilder
         .append(invocationName)
diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/SlowInvocationLogger.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/SlowInvocationLogger.java
index 8dc61ca8e..797876aaf 100644
--- a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/SlowInvocationLogger.java
+++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/publish/SlowInvocationLogger.java
@@ -66,7 +66,7 @@ public class SlowInvocationLogger {
       return;
     }
 
-    if (!invocation.isConsumer()) {
+    if (invocation.isProducer()) {
       logSlowProvider(invocation, event.getResponse(), operationConfig);
       return;
     }
diff --git a/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/TestInvocationMetersInitializer.java b/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/TestInvocationMetersInitializer.java
index 83f85e78c..316b9bf9b 100644
--- a/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/TestInvocationMetersInitializer.java
+++ b/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/TestInvocationMetersInitializer.java
@@ -182,7 +182,7 @@ public class TestInvocationMetersInitializer {
   @Test
   public void edgeInvocation() {
     InvocationFinishEvent event = Mockito.mock(InvocationFinishEvent.class);
-    Mockito.when(invocation.isConsumer()).thenReturn(true);
+    Mockito.when(invocation.getInvocationType()).thenReturn(InvocationType.EDGE);
     Mockito.when(invocation.isEdge()).thenReturn(true);
     Mockito.when(invocation.getRealTransportName()).thenReturn(CoreConst.RESTFUL);
     Mockito.when(invocation.getMicroserviceQualifiedName()).thenReturn("m.s.o");
diff --git a/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/publish/TestSlowInvocationLogger.java b/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/publish/TestSlowInvocationLogger.java
index 703a245a2..ddfa8adee 100644
--- a/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/publish/TestSlowInvocationLogger.java
+++ b/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/publish/TestSlowInvocationLogger.java
@@ -16,7 +16,6 @@
  */
 package org.apache.servicecomb.metrics.core.publish;
 
-import com.google.common.eventbus.EventBus;
 import org.apache.servicecomb.common.rest.RestConst;
 import org.apache.servicecomb.common.rest.definition.RestOperationMeta;
 import org.apache.servicecomb.core.Endpoint;
@@ -38,6 +37,8 @@ import org.mockito.Mock;
 import org.mockito.Mockito;
 import org.mockito.junit.jupiter.MockitoExtension;
 
+import com.google.common.eventbus.EventBus;
+
 @ExtendWith(MockitoExtension.class)
 public class TestSlowInvocationLogger {
   @Mock
@@ -109,7 +110,7 @@ public class TestSlowInvocationLogger {
     Endpoint endpoint = Mockito.mock(Endpoint.class);
     Mockito.when(invocation.getEndpoint()).thenReturn(endpoint);
     Mockito.when(endpoint.getEndpoint()).thenReturn("rest://1.1.1.1:1234");
-    Mockito.when(invocation.isConsumer()).thenReturn(true);
+    Mockito.when(invocation.isProducer()).thenReturn(false);
     Mockito.when(operationMeta.getExtData(RestConst.SWAGGER_REST_OPERATION)).thenReturn(restOperationMeta);
     Mockito.when(operationConfig.isSlowInvocationEnabled()).thenReturn(true);
     Mockito.when(operationConfig.getNanoSlowInvocation()).thenReturn(1L);
@@ -131,7 +132,7 @@ public class TestSlowInvocationLogger {
                 wait            :      0.0ms
                 consumer-decode :      0.0ms
             """,
-            logCollector.getEvent(0).getMessage().getFormattedMessage());
+        logCollector.getEvent(0).getMessage().getFormattedMessage());
   }
 
   @Test
@@ -139,7 +140,6 @@ public class TestSlowInvocationLogger {
     Endpoint endpoint = Mockito.mock(Endpoint.class);
     Mockito.when(invocation.getEndpoint()).thenReturn(endpoint);
     Mockito.when(endpoint.getEndpoint()).thenReturn("rest://1.1.1.1:1234");
-    Mockito.when(invocation.isConsumer()).thenReturn(true);
     Mockito.when(invocation.isEdge()).thenReturn(true);
     Mockito.when(operationMeta.getExtData(RestConst.SWAGGER_REST_OPERATION)).thenReturn(restOperationMeta);
     Mockito.when(operationConfig.isSlowInvocationEnabled()).thenReturn(true);
@@ -176,7 +176,7 @@ public class TestSlowInvocationLogger {
     Mockito.when(invocation.getRequestEx()).thenReturn(requestEx);
     Mockito.when(requestEx.getRemoteAddr()).thenReturn("1.1.1.1");
     Mockito.when(requestEx.getRemotePort()).thenReturn(1234);
-    Mockito.when(invocation.isConsumer()).thenReturn(false);
+    Mockito.when(invocation.isProducer()).thenReturn(true);
     Mockito.when(operationMeta.getExtData(RestConst.SWAGGER_REST_OPERATION)).thenReturn(restOperationMeta);
     Mockito.when(operationConfig.isSlowInvocationEnabled()).thenReturn(true);
     Mockito.when(operationConfig.getNanoSlowInvocation()).thenReturn(1L);