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;
}
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();
}
}
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);
}
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);
}
}
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();
}
}
}
Aggregations