Search in sources :

Example 16 with SofaTraceContext

use of com.alipay.common.tracer.core.context.trace.SofaTraceContext in project sofa-rpc by sofastack.

the class ServerReqHeaderInterceptor method interceptCall.

@Override
public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(final ServerCall<ReqT, RespT> call, final Metadata requestHeaders, ServerCallHandler<ReqT, RespT> next) {
    final ServerServiceDefinition serverServiceDefinition = this.getServerServiceDefinition();
    SofaResponse sofaResponse = new SofaResponse();
    final Throwable[] throwable = { null };
    SofaRequest sofaRequest = new SofaRequest();
    TripleTracerAdapter.serverReceived(sofaRequest, serverServiceDefinition, call, requestHeaders);
    SofaTraceContext sofaTraceContext = SofaTraceContextHolder.getSofaTraceContext();
    SofaTracerSpan serverSpan = sofaTraceContext.getCurrentSpan();
    Context ctxWithSpan = Context.current().withValue(TracingContextKey.getKey(), serverSpan).withValue(TracingContextKey.getSpanContextKey(), serverSpan.context()).withValue(TracingContextKey.getKeySofaRequest(), sofaRequest);
    // 这里和下面不在一个线程
    if (RpcRunningState.isDebugMode()) {
        LOGGER.info("[1]header received from client:" + requestHeaders);
    }
    ServerCall<ReqT, RespT> realCall = new ForwardingServerCall.SimpleForwardingServerCall<ReqT, RespT>(call) {

        @Override
        public void sendHeaders(Metadata responseHeaders) {
            if (RpcRunningState.isDebugMode()) {
                LOGGER.info("[4]send response header:{}", responseHeaders);
            }
            super.sendHeaders(responseHeaders);
        }

        // 服务端发完了
        @Override
        public void sendMessage(RespT message) {
            if (RpcRunningState.isDebugMode()) {
                LOGGER.info("[5]send response message:{}", message);
            }
            super.sendMessage(message);
            sofaResponse.setAppResponse(message);
        }

        @Override
        public void close(Status status, Metadata trailers) {
            if (RpcRunningState.isDebugMode()) {
                LOGGER.info("[6]send response message:{},trailers:{}", status, trailers);
            }
            super.close(status, trailers);
        }
    };
    ServerCall.Listener<ReqT> listenerWithContext = Contexts.interceptCall(ctxWithSpan, realCall, requestHeaders, next);
    ForwardingServerCallListener.SimpleForwardingServerCallListener<ReqT> result = new ForwardingServerCallListener.SimpleForwardingServerCallListener<ReqT>(listenerWithContext) {

        // 完成的时候走到这里
        @Override
        public void onComplete() {
            // 和代码执行不一定在一个线程池
            super.onComplete();
            if (RpcRunningState.isDebugMode()) {
                LOGGER.info("[7]server processed done received from client:" + requestHeaders);
            }
            TripleTracerAdapter.serverReceived(sofaRequest, serverServiceDefinition, call, requestHeaders);
            // 进行一下补偿
            SofaTraceContext sofaTraceContext = SofaTraceContextHolder.getSofaTraceContext();
            SofaTracerSpan serverSpan = sofaTraceContext.getCurrentSpan();
            SofaTracerSpan originalSpan = (SofaTracerSpan) TracingContextKey.getKey().get(ctxWithSpan);
            serverSpan.setStartTime(originalSpan.getStartTime());
            serverSpan.setTag("remote.ip", originalSpan.getTagsWithStr().get("remote.ip"));
            long endTime = RpcRuntimeContext.now();
            serverSpan.setTag("biz.impl.time", endTime - originalSpan.getStartTime());
            TripleTracerAdapter.serverSend(sofaRequest, requestHeaders, sofaResponse, throwable[0]);
        }

        // 客户端发完了
        @Override
        public void onHalfClose() {
            try {
                doOnHalfClose();
            } finally {
                RpcInvokeContext.removeContext();
            }
        }

        private void doOnHalfClose() {
            if (RpcRunningState.isDebugMode()) {
                LOGGER.info("[2]body received done from client:" + requestHeaders);
            }
            // 服务端收到所有信息
            TripleTracerAdapter.serverReceived(sofaRequest, serverServiceDefinition, call, requestHeaders);
            try {
                super.onHalfClose();
            } catch (Throwable t) {
                // 统一处理异常
                StatusRuntimeException exception = fromThrowable(t);
                // 调用 call.close() 发送 Status 和 metadata
                // 这个方式和 onError()本质是一样的
                call.close(exception.getStatus(), exception.getTrailers());
                throwable[0] = t;
            }
        }

        private StatusRuntimeException fromThrowable(Throwable t) {
            final Metadata trailers = new Metadata();
            return new StatusRuntimeException(Status.UNKNOWN, trailers);
        }
    };
    return result;
}
Also used : RpcRuntimeContext(com.alipay.sofa.rpc.context.RpcRuntimeContext) SofaTraceContext(com.alipay.common.tracer.core.context.trace.SofaTraceContext) Context(io.grpc.Context) RpcInvokeContext(com.alipay.sofa.rpc.context.RpcInvokeContext) Status(io.grpc.Status) SofaRequest(com.alipay.sofa.rpc.core.request.SofaRequest) SofaTraceContext(com.alipay.common.tracer.core.context.trace.SofaTraceContext) Metadata(io.grpc.Metadata) SofaTracerSpan(com.alipay.common.tracer.core.span.SofaTracerSpan) ForwardingServerCallListener(io.grpc.ForwardingServerCallListener) ForwardingServerCall(io.grpc.ForwardingServerCall) ServerCall(io.grpc.ServerCall) ServerServiceDefinition(io.grpc.ServerServiceDefinition) StatusRuntimeException(io.grpc.StatusRuntimeException) SofaResponse(com.alipay.sofa.rpc.core.response.SofaResponse)

Example 17 with SofaTraceContext

use of com.alipay.common.tracer.core.context.trace.SofaTraceContext in project sofa-rpc by sofastack.

the class TripleTracerAdapter method beforeSend.

/**
 * 存入tracer信息
 *
 * @param sofaRequest   SofaRequest
 * @param requestHeader Metadata
 */
public static void beforeSend(SofaRequest sofaRequest, ConsumerConfig consumerConfig, Metadata requestHeader) {
    // 客户端设置请求服务端的Header
    // tracer信息放入request 发到服务端
    Map<String, String> header = new HashMap<String, String>();
    header.put(RemotingConstants.HEAD_METHOD_NAME, sofaRequest.getMethodName());
    header.put(RemotingConstants.HEAD_TARGET_SERVICE, sofaRequest.getTargetServiceUniqueName());
    header.put(RemotingConstants.HEAD_TARGET_APP, sofaRequest.getTargetAppName());
    // 客户端的启动
    SofaTraceContext sofaTraceContext = SofaTraceContextHolder.getSofaTraceContext();
    // 获取并不弹出
    SofaTracerSpan clientSpan = sofaTraceContext.getCurrentSpan();
    if (clientSpan == null) {
        SelfLog.warn("ClientSpan is null.Before call interface=" + sofaRequest.getInterfaceName() + ",method=" + sofaRequest.getMethodName());
    } else {
        SofaTracerSpanContext sofaTracerSpanContext = clientSpan.getSofaTracerSpanContext();
        header.put(TripleHeadKeys.HEAD_KEY_TRACE_ID.name(), sofaTracerSpanContext.getTraceId());
        header.put(TripleHeadKeys.HEAD_KEY_RPC_ID.name(), sofaTracerSpanContext.getSpanId());
        header.put(TripleHeadKeys.HEAD_KEY_OLD_TRACE_ID.name(), sofaTracerSpanContext.getTraceId());
        header.put(TripleHeadKeys.HEAD_KEY_OLD_RPC_ID.name(), sofaTracerSpanContext.getSpanId());
        header.put(TripleHeadKeys.HEAD_KEY_BIZ_BAGGAGE_TYPE.name(), sofaTracerSpanContext.getBizSerializedBaggage());
        header.put(TripleHeadKeys.HEAD_KEY_SYS_BAGGAGE_TYPE.name(), sofaTracerSpanContext.getSysSerializedBaggage());
    }
    // 获取 RPC 上下文
    RpcInvokeContext internalContext = RpcInvokeContext.getContext();
    String route = (String) internalContext.get(USERID_KEY);
    if (StringUtils.isNotBlank(route)) {
        Map<String, String> map = new HashMap<>();
        map.put(USERID_KEY, route);
        header.put(TripleHeadKeys.HEAD_KEY_UNIT_INFO.name(), JSONUtils.toJSONString(map));
    }
    if (StringUtils.isNotEmpty(consumerConfig.getUniqueId())) {
        header.put(TripleHeadKeys.HEAD_KEY_SERVICE_VERSION.name(), consumerConfig.getUniqueId());
    }
    header.put(TripleHeadKeys.HEAD_KEY_META_TYPE.name(), "rpc");
    header.put(TripleHeadKeys.HEAD_KEY_CURRENT_APP.name(), (String) sofaRequest.getRequestProp(HEAD_APP_NAME));
    header.put(TripleHeadKeys.HEAD_KEY_CONSUMER_APP.name(), (String) sofaRequest.getRequestProp(HEAD_APP_NAME));
    header.put(TripleHeadKeys.HEAD_KEY_PROTOCOL_TYPE.name(), (String) sofaRequest.getRequestProp(RemotingConstants.HEAD_PROTOCOL));
    header.put(TripleHeadKeys.HEAD_KEY_INVOKE_TYPE.name(), (String) sofaRequest.getRequestProp(RemotingConstants.HEAD_INVOKE_TYPE));
    final String source = consumerConfig.getParameter("interworking.source");
    if (StringUtils.isNotBlank(source)) {
        header.put(TripleHeadKeys.HEAD_KEY_SOURCE_TENANTID.name(), source);
    }
    final String target = consumerConfig.getParameter("interworking.target");
    if (StringUtils.isNotBlank(target)) {
        header.put(TripleHeadKeys.HEAD_KEY_TARGET_TENANTID.name(), target);
    }
    for (Map.Entry<String, String> entry : header.entrySet()) {
        if (StringUtils.isNotBlank(entry.getValue())) {
            requestHeader.put(TripleHeadKeys.getKey(entry.getKey()), entry.getValue());
        }
    }
    // set custom headers
    try {
        Set<Map.Entry<String, String>> customHeader = RpcInvokeContext.getContext().getCustomHeader().entrySet();
        for (Map.Entry<String, String> entry : customHeader) {
            if (StringUtils.isNotBlank(entry.getValue())) {
                requestHeader.put(TripleHeadKeys.getKey(entry.getKey()), entry.getValue());
            }
        }
    } finally {
        RpcInvokeContext.getContext().clearCustomHeader();
    }
}
Also used : SofaTracerSpan(com.alipay.common.tracer.core.span.SofaTracerSpan) RpcInvokeContext(com.alipay.sofa.rpc.context.RpcInvokeContext) HashMap(java.util.HashMap) SofaTraceContext(com.alipay.common.tracer.core.context.trace.SofaTraceContext) SofaTracerSpanContext(com.alipay.common.tracer.core.context.span.SofaTracerSpanContext) HashMap(java.util.HashMap) Map(java.util.Map)

Example 18 with SofaTraceContext

use of com.alipay.common.tracer.core.context.trace.SofaTraceContext in project sofa-rpc by sofastack.

the class RpcSofaTracer method startRpc.

@Override
public void startRpc(SofaRequest request) {
    // 客户端的启动
    SofaTraceContext sofaTraceContext = SofaTraceContextHolder.getSofaTraceContext();
    SofaTracerSpan serverSpan = sofaTraceContext.pop();
    SofaTracerSpan clientSpan = (SofaTracerSpan) this.sofaTracer.buildSpan(request.getInterfaceName()).asChildOf(serverSpan).withTag(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_CLIENT).start();
    if (RpcInternalContext.isAttachmentEnable()) {
        RpcInternalContext context = RpcInternalContext.getContext();
        clientSpan.setTag(RpcSpanTags.LOCAL_APP, (String) context.getAttachment(RpcConstants.INTERNAL_KEY_APP_NAME));
        clientSpan.setTag(RpcSpanTags.PROTOCOL, (String) context.getAttachment(RpcConstants.INTERNAL_KEY_PROTOCOL_NAME));
        SofaTracerSpanContext spanContext = clientSpan.getSofaTracerSpanContext();
        if (spanContext != null) {
            context.setAttachment(RpcConstants.INTERNAL_KEY_TRACE_ID, spanContext.getTraceId());
            context.setAttachment(RpcConstants.INTERNAL_KEY_SPAN_ID, spanContext.getSpanId());
        }
    }
    clientSpan.setTag(RpcSpanTags.SERVICE, request.getTargetServiceUniqueName());
    clientSpan.setTag(RpcSpanTags.METHOD, request.getMethodName());
    clientSpan.setTag(RpcSpanTags.CURRENT_THREAD_NAME, Thread.currentThread().getName());
    // 需要主动缓存自己的 serverSpan,原因是:asChildOf 关注的是 spanContext
    clientSpan.setParentSofaTracerSpan(serverSpan);
    // push
    sofaTraceContext.push(clientSpan);
}
Also used : SofaTracerSpan(com.alipay.common.tracer.core.span.SofaTracerSpan) SofaTraceContext(com.alipay.common.tracer.core.context.trace.SofaTraceContext) RpcInternalContext(com.alipay.sofa.rpc.context.RpcInternalContext) SofaTracerSpanContext(com.alipay.common.tracer.core.context.span.SofaTracerSpanContext)

Example 19 with SofaTraceContext

use of com.alipay.common.tracer.core.context.trace.SofaTraceContext in project sofa-rpc by sofastack.

the class RpcSofaTracer method profile.

@Override
public void profile(String profileApp, String code, String message) {
    // 注意 profile 需要打印 traceId 等信息,所以要打开 tracer 才可以
    SofaTraceContext sofaTraceContext = SofaTraceContextHolder.getSofaTraceContext();
    SofaTracerSpan sofaTracerSpan = sofaTraceContext.getCurrentSpan();
    if (sofaTracerSpan != null) {
        sofaTracerSpan.profile(profileApp, code, message);
    }
}
Also used : SofaTracerSpan(com.alipay.common.tracer.core.span.SofaTracerSpan) SofaTraceContext(com.alipay.common.tracer.core.context.trace.SofaTraceContext)

Example 20 with SofaTraceContext

use of com.alipay.common.tracer.core.context.trace.SofaTraceContext in project sofa-rpc by sofastack.

the class RpcSofaTracer method checkState.

@Override
public void checkState() {
    RpcInternalContext rpcInternalContext = RpcInternalContext.getContext();
    // tracer 上下文
    SofaTraceContext sofaTraceContext = SofaTraceContextHolder.getSofaTraceContext();
    if (rpcInternalContext.isConsumerSide()) {
        // 客户端 tracer 堆栈中最多有 1 个(客户端 span 完毕,服务端 span 压栈所以最多一个)
        if (sofaTraceContext.getThreadLocalSpanSize() > 1) {
            SelfLog.error(LogCodes.getLog(LogCodes.ERROR_TRACER_CONSUMER_STACK));
            SelfLog.flush();
        }
    } else if (rpcInternalContext.isProviderSide()) {
        // 服务端 tracer 堆栈中应该为 0 个
        if (sofaTraceContext.getThreadLocalSpanSize() > 0) {
            SelfLog.error(LogCodes.getLog(LogCodes.ERROR_TRACER_PROVIDER_STACK));
            SelfLog.flush();
        }
    }
}
Also used : SofaTraceContext(com.alipay.common.tracer.core.context.trace.SofaTraceContext) RpcInternalContext(com.alipay.sofa.rpc.context.RpcInternalContext)

Aggregations

SofaTraceContext (com.alipay.common.tracer.core.context.trace.SofaTraceContext)26 SofaTracerSpan (com.alipay.common.tracer.core.span.SofaTracerSpan)25 RpcInternalContext (com.alipay.sofa.rpc.context.RpcInternalContext)13 Test (org.junit.Test)7 SofaTracerSpanContext (com.alipay.common.tracer.core.context.span.SofaTracerSpanContext)6 HashMap (java.util.HashMap)6 RpcInvokeContext (com.alipay.sofa.rpc.context.RpcInvokeContext)4 SofaRequest (com.alipay.sofa.rpc.core.request.SofaRequest)3 ProviderInfo (com.alipay.sofa.rpc.client.ProviderInfo)2 SofaRpcException (com.alipay.sofa.rpc.core.exception.SofaRpcException)2 SofaResponse (com.alipay.sofa.rpc.core.response.SofaResponse)2 InetSocketAddress (java.net.InetSocketAddress)2 ProviderConfig (com.alipay.sofa.rpc.config.ProviderConfig)1 RpcRuntimeContext (com.alipay.sofa.rpc.context.RpcRuntimeContext)1 ServerReceiveEvent (com.alipay.sofa.rpc.event.ServerReceiveEvent)1 SofaResourceFactory (com.alipay.sofa.rpc.server.rest.SofaResourceFactory)1 SofaResourceMethodInvoker (com.alipay.sofa.rpc.server.rest.SofaResourceMethodInvoker)1 Context (io.grpc.Context)1 ForwardingServerCall (io.grpc.ForwardingServerCall)1 ForwardingServerCallListener (io.grpc.ForwardingServerCallListener)1