ShenFeng312 commented on issue #11650:
URL: https://github.com/apache/dubbo/issues/11650#issuecomment-1446313706

   ```java
   
   
   /*
    * Copyright 2013-2020 The OpenZipkin Authors
    *
    * Licensed 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 brave.dubbo;
   
   import brave.Span;
   import brave.Span.Kind;
   import brave.SpanCustomizer;
   import brave.Tag;
   import brave.Tracing;
   import brave.internal.Nullable;
   import brave.propagation.CurrentTraceContext;
   import brave.propagation.CurrentTraceContext.Scope;
   import brave.propagation.TraceContext;
   import brave.rpc.RpcClientHandler;
   import brave.rpc.RpcClientRequest;
   import brave.rpc.RpcResponse;
   import brave.rpc.RpcResponseParser;
   import brave.rpc.RpcServerHandler;
   import brave.rpc.RpcTracing;
   import java.util.Map;
   import java.util.concurrent.CompletableFuture;
   import org.apache.dubbo.common.constants.CommonConstants;
   import org.apache.dubbo.common.extension.Activate;
   import org.apache.dubbo.common.extension.ExtensionLoader;
   import org.apache.dubbo.rpc.Filter;
   import org.apache.dubbo.rpc.Invocation;
   import org.apache.dubbo.rpc.Invoker;
   import org.apache.dubbo.rpc.Result;
   import org.apache.dubbo.rpc.RpcContext;
   import org.apache.dubbo.rpc.RpcException;
   
   import static brave.internal.Throwables.propagateIfFatal;
   
   @Activate(group = {CommonConstants.PROVIDER, CommonConstants.CONSUMER}, 
value = "tracing")
   // http://dubbo.apache.org/en-us/docs/dev/impls/filter.html
   // public constructor permitted to allow dubbo to instantiate this
   public final class Tracing3Filter implements Filter {
       static final Tag<Throwable> DUBBO_ERROR_CODE = new 
Tag<Throwable>("dubbo.error_code") {
           @Override protected String parseValue(Throwable input, TraceContext 
context) {
               if (!(input instanceof RpcException)) return null;
               return String.valueOf(((RpcException) input).getCode());
           }
       };
       static final RpcResponseParser LEGACY_RESPONSE_PARSER = new 
RpcResponseParser() {
           @Override public void parse(RpcResponse response, TraceContext 
context, SpanCustomizer span) {
               DUBBO_ERROR_CODE.tag(response.error(), span);
           }
       };
   
       CurrentTraceContext currentTraceContext;
       RpcClientHandler clientHandler;
       RpcServerHandler serverHandler;
       volatile boolean isInit = false;
   
       /**
        * {@link ExtensionLoader} supplies the tracing implementation which 
must be named "tracing". For
        * example, if using the {@link SpringExtensionFactory}, only a bean 
named "tracing" will be
        * injected.
        *
        * @deprecated Since 5.12 only use {@link #setRpcTracing(RpcTracing)}
        */
       @Deprecated public void setTracing(Tracing tracing) {
           if (tracing == null) throw new NullPointerException("rpcTracing == 
null");
           setRpcTracing(RpcTracing.newBuilder(tracing)
               .clientResponseParser(LEGACY_RESPONSE_PARSER)
               .serverResponseParser(LEGACY_RESPONSE_PARSER)
               .build());
       }
   
       /**
        * {@link ExtensionLoader} supplies the tracing implementation which 
must be named "rpcTracing".
        * For example, if using the {@link SpringExtensionFactory}, only a bean 
named "rpcTracing" will
        * be injected.
        *
        * <h3>Custom parsing</h3>
        * Custom parsers, such as {@link RpcTracing#clientRequestParser()}, can 
use Dubbo-specific types
        * {@link DubboRequest} and {@link DubboResponse} to get access such as 
the Java invocation or
        * result.
        */
       public void setRpcTracing(RpcTracing rpcTracing) {
           if (rpcTracing == null) throw new NullPointerException("rpcTracing 
== null");
           // we don't guard on init because we intentionally want to overwrite 
any call to setTracing
           currentTraceContext = rpcTracing.tracing().currentTraceContext();
           clientHandler = RpcClientHandler.create(rpcTracing);
           serverHandler = RpcServerHandler.create(rpcTracing);
           isInit = true;
       }
   
       @Override
       public Result invoke(Invoker<?> invoker, Invocation invocation) throws 
RpcException {
           if (!isInit) return invoker.invoke(invocation);
           TraceContext invocationContext = currentTraceContext.get();
   
           RpcContext rpcContext = RpcContext.getContext();
           Kind kind = rpcContext.isProviderSide() ? Kind.SERVER : Kind.CLIENT;
           Span span;
           DubboRequest request;
           if (kind.equals(Kind.CLIENT)) {
               // When A service invoke B service, then B service then invoke C 
service, the parentId of the
               // C service span is A when read from 
invocation.getAttachments(). This is because
               // AbstractInvoker adds attachments via RpcContext.getContext(), 
not the invocation.
               // See org.apache.dubbo.rpc.protocol.AbstractInvoker(line 141) 
from v2.7.3
               Map<String, String> attachments = invocation.getAttachments();
               DubboClientRequest clientRequest = new 
DubboClientRequest(invoker, invocation, attachments);
               request = clientRequest;
               span = clientHandler.handleSendWithParent(clientRequest, 
invocationContext);
           } else {
               DubboServerRequest serverRequest = new 
DubboServerRequest(invoker, invocation);
               request = serverRequest;
               span = serverHandler.handleReceive(serverRequest);
           }
   
           boolean isSynchronous = true;
           Scope scope = currentTraceContext.newScope(span.context());
           Result result = null;
           Throwable error = null;
           try {
               result = invoker.invoke(invocation);
               error = result.getException();
               CompletableFuture<Object> future = 
rpcContext.getCompletableFuture();
               if (future != null) {
                   isSynchronous = false;
                   // NOTE: We don't currently instrument CompletableFuture, so 
callbacks will not see the
                   // invocation context unless they use an executor 
instrumented by CurrentTraceContext
                   // If we later instrument this, take care to use the correct 
context depending on RPC kind!
                   future.whenComplete(create(this,request,result,span));
               }
               return result;
           } catch (Throwable e) {
               propagateIfFatal(e);
               error = e;
               throw e;
           } finally {
               if (isSynchronous) finish(this, request, result, error, span);
               scope.close();
           }
       }
   
       static FinishSpan create(Tracing3Filter filter, DubboRequest request, 
Result result, Span span) {
           if (request instanceof DubboClientRequest) {
               return new FinishSpan.FinishClientSpan(
                   span, result, filter.clientHandler, (DubboClientRequest) 
request);
           }
           return new FinishSpan.FinishServerSpan(span, result, 
filter.serverHandler, (DubboServerRequest) request);
       }
   
       static void finish(Tracing3Filter filter,
                          DubboRequest request, @Nullable Result result, 
@Nullable Throwable error, Span span) {
           if (request instanceof RpcClientRequest) {
               filter.clientHandler.handleReceive(
                   new DubboClientResponse((DubboClientRequest) request, 
result, error), span);
           } else {
               filter.serverHandler.handleSend(
                   new DubboServerResponse((DubboServerRequest) request, 
result, error), span);
           }
       }
   }
   
   ```
   @liunancun 你可以先使用这个Filter,后续我会在brave 社区提PR 修改


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to