diff --git a/.travis.yml b/.travis.yml index 8ef0342a..d3f1f3a4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,7 @@ language: java sudo: false jdk: -- openjdk7 +- openjdk8 install: diff --git a/pom.xml b/pom.xml index 86288140..053c9770 100644 --- a/pom.xml +++ b/pom.xml @@ -23,6 +23,7 @@ sofa-tracer-plugins/sofa-tracer-datasource-plugin sofa-tracer-plugins/sofa-tracer-resttmplate-plugin sofa-tracer-plugins/sofa-tracer-zipkin-plugin + sofa-tracer-plugins/sofa-tracer-dubbo-plugin tracer-all tracer-sofa-boot-starter tracer-samples @@ -35,8 +36,8 @@ 0.22.0 2.4.0 - 1.6 - 1.6 + 1.8 + 1.8 1.9.3 UTF-8 ${user.dir} @@ -123,6 +124,11 @@ sofa-tracer-zipkin-plugin ${sofa.tracer.version} + + com.alipay.sofa + sofa-tracer-dubbo-plugin + ${sofa.tracer.version} + com.alipay.sofa tracer-all @@ -216,9 +222,13 @@ ${jmh.version} test + + com.alibaba + fastjson + 1.2.51 + - diff --git a/sofa-tracer-plugins/sofa-tracer-dubbo-plugin/pom.xml b/sofa-tracer-plugins/sofa-tracer-dubbo-plugin/pom.xml new file mode 100644 index 00000000..b59133ea --- /dev/null +++ b/sofa-tracer-plugins/sofa-tracer-dubbo-plugin/pom.xml @@ -0,0 +1,41 @@ + + + + tracer-all-parent + com.alipay.sofa + 2.4.0 + ../../pom.xml + + 4.0.0 + sofa-tracer-dubbo-plugin + + + + org.apache.dubbo + dubbo + 2.7.0 + provided + + + com.alipay.sofa + tracer-core + + + junit + junit + test + + + commons-io + commons-io + test + + + com.alibaba + fastjson + + + + \ No newline at end of file diff --git a/sofa-tracer-plugins/sofa-tracer-dubbo-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo/DubboSofaTracerFilter.java b/sofa-tracer-plugins/sofa-tracer-dubbo-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo/DubboSofaTracerFilter.java new file mode 100644 index 00000000..a71f64a7 --- /dev/null +++ b/sofa-tracer-plugins/sofa-tracer-dubbo-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo/DubboSofaTracerFilter.java @@ -0,0 +1,408 @@ +/* + * 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 com.alipay.sofa.tracer.plugins.dubbo; + +import com.alipay.common.tracer.core.appender.self.SelfLog; +import com.alipay.common.tracer.core.configuration.SofaTracerConfiguration; +import com.alipay.common.tracer.core.context.span.SofaTracerSpanContext; +import com.alipay.common.tracer.core.context.trace.SofaTraceContext; +import com.alipay.common.tracer.core.holder.SofaTraceContextHolder; +import com.alipay.common.tracer.core.samplers.Sampler; +import com.alipay.common.tracer.core.span.CommonSpanTags; +import com.alipay.common.tracer.core.span.LogData; +import com.alipay.common.tracer.core.span.SofaTracerSpan; +import com.alipay.common.tracer.core.utils.StringUtils; +import com.alipay.sofa.tracer.plugins.dubbo.tracer.DubboConsumerSofaTracer; +import com.alipay.sofa.tracer.plugins.dubbo.tracer.DubboProviderSofaTracer; +import io.opentracing.tag.Tags; +import org.apache.dubbo.common.Constants; +import org.apache.dubbo.common.extension.Activate; +import org.apache.dubbo.remoting.TimeoutException; +import org.apache.dubbo.rpc.*; +import org.apache.dubbo.rpc.support.RpcUtils; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ConcurrentHashMap; + +/** + * @author: guolei.sgl (guolei.sgl@antfin.com) 2019/2/26 2:02 PM + * @since: 2.3.4 + **/ +@Activate(group = { Constants.PROVIDER, Constants.CONSUMER }, value = "dubboSofaTracerFilter", order = 1) +public class DubboSofaTracerFilter implements Filter { + + private String appName = StringUtils.EMPTY_STRING; + + private static final String BLANK = StringUtils.EMPTY_STRING; + + private static final String SUCCESS_CODE = "00"; + + private static final String FAILED_CODE = "99"; + + private static final String SPAN_INVOKE_KEY = "sofa.current.span.key"; + + private DubboConsumerSofaTracer dubboConsumerSofaTracer; + + private DubboProviderSofaTracer dubboProviderSofaTracer; + + private static Map TracerSpanMap = new ConcurrentHashMap(); + + @Override + public Result invoke(Invoker invoker, Invocation invocation) throws RpcException { + // do not record + if ("$echo".equals(invocation.getMethodName())) { + return invoker.invoke(invocation); + } + + RpcContext rpcContext = RpcContext.getContext(); + // get appName + if (StringUtils.isBlank(this.appName)) { + this.appName = SofaTracerConfiguration + .getProperty(SofaTracerConfiguration.TRACER_APPNAME_KEY); + } + // get span kind by rpc request type + String spanKind = spanKind(rpcContext); + Result result; + if (spanKind.equals(Tags.SPAN_KIND_SERVER)) { + result = doServerFilter(rpcContext, invoker, invocation); + } else { + result = doClientFilter(rpcContext, invoker, invocation); + } + return result; + } + + @Override + public Result onResponse(Result result, Invoker invoker, Invocation invocation) { + String spanKey = getTracerSpanMapKey(invoker); + try { + // 只有异步才进行回调打印 + boolean isAsync = RpcUtils.isAsync(invoker.getUrl(), invocation); + if (!isAsync) { + return result; + } + if (TracerSpanMap.containsKey(spanKey)) { + SofaTracerSpan sofaTracerSpan = TracerSpanMap.get(spanKey); + // to build tracer instance + if (dubboConsumerSofaTracer == null) { + this.dubboConsumerSofaTracer = DubboConsumerSofaTracer + .getDubboConsumerSofaTracerSingleton(); + } + String resultCode = SUCCESS_CODE; + if (result.hasException()) { + if (result.getException() instanceof RpcException) { + resultCode = Integer.toString(((RpcException) result.getException()) + .getCode()); + sofaTracerSpan.setTag(CommonSpanTags.RESULT_CODE, resultCode); + } else { + resultCode = FAILED_CODE; + } + } + // add elapsed time + appendElapsedTimeTags(invocation, sofaTracerSpan, result, true); + dubboConsumerSofaTracer.clientReceiveTagFinish(sofaTracerSpan, resultCode); + } + } finally { + if (TracerSpanMap.containsKey(spanKey)) { + TracerSpanMap.remove(spanKey); + } + } + return result; + } + + /** + * rpc client handler + * @param rpcContext + * @param invoker + * @param invocation + * @return + */ + private Result doClientFilter(RpcContext rpcContext, Invoker invoker, Invocation invocation) { + // to build tracer instance + if (dubboConsumerSofaTracer == null) { + this.dubboConsumerSofaTracer = DubboConsumerSofaTracer + .getDubboConsumerSofaTracerSingleton(); + } + // get methodName + String methodName = rpcContext.getMethodName(); + // get service interface + String service = invoker.getInterface().getSimpleName(); + // build a dubbo rpc span + SofaTracerSpan sofaTracerSpan = dubboConsumerSofaTracer.clientSend(service + "#" + + methodName); + // set tags to span + appendRpcClientSpanTags(invoker, sofaTracerSpan); + // do serialized and then transparent transmission to the rpc server + String serializedSpanContext = sofaTracerSpan.getSofaTracerSpanContext() + .serializeSpanContext(); + //put into attachments + invocation.getAttachments().put(CommonSpanTags.RPC_TRACE_NAME, serializedSpanContext); + // check invoke type + boolean isAsync = RpcUtils.isAsync(invoker.getUrl(), invocation); + boolean isOneWay = false; + if (isAsync) { + sofaTracerSpan.setTag(CommonSpanTags.INVOKE_TYPE, "future"); + } else { + isOneWay = RpcUtils.isOneway(invoker.getUrl(), invocation); + if (isOneWay) { + sofaTracerSpan.setTag(CommonSpanTags.INVOKE_TYPE, "oneway"); + } else { + sofaTracerSpan.setTag(CommonSpanTags.INVOKE_TYPE, "sync"); + } + } + Result result; + Throwable exception = null; + String resultCode = SUCCESS_CODE; + try { + // do invoke + result = invoker.invoke(invocation); + // check result + if (result == null) { + // isOneWay, we think that the current request is successful + if (isOneWay) { + sofaTracerSpan.setTag(CommonSpanTags.RESP_SIZE, 0); + } + } else { + // add elapsed time + appendElapsedTimeTags(invocation, sofaTracerSpan, result,true); + } + } catch (RpcException e) { + exception = e; + throw e; + } catch (Throwable t) { + exception = t; + throw new RpcException(t); + } finally { + if (exception != null) { + if (exception instanceof RpcException) { + sofaTracerSpan.setTag(Tags.ERROR.getKey(),exception.getMessage()); + RpcException rpcException = (RpcException) exception; + resultCode = String.valueOf(rpcException.getCode()); + } else { + resultCode = FAILED_CODE; + } + } + + if (!isAsync) { + dubboConsumerSofaTracer.clientReceive(resultCode); + } else { + SofaTraceContext sofaTraceContext = SofaTraceContextHolder.getSofaTraceContext(); + SofaTracerSpan clientSpan = sofaTraceContext.pop(); + if (clientSpan != null) { + // Record client send event + sofaTracerSpan.log(LogData.CLIENT_SEND_EVENT_VALUE); + } + // 将当前 span 缓存 + TracerSpanMap.put(getTracerSpanMapKey(invoker), sofaTracerSpan); + if (clientSpan != null && clientSpan.getParentSofaTracerSpan() != null) { + //restore parent + sofaTraceContext.push(clientSpan.getParentSofaTracerSpan()); + } + CompletableFuture future = (CompletableFuture) RpcContext.getContext().getFuture(); + future.whenComplete((object, throwable)-> { + if (throwable != null && throwable instanceof TimeoutException) { + sofaTracerSpan.setTag(Tags.ERROR.getKey(),throwable.getMessage()); + dubboConsumerSofaTracer.clientReceiveTagFinish(sofaTracerSpan, "03"); + } + }); + } + } + return result; + } + + /** + * rpc client handler + * @param rpcContext + * @param invoker + * @param invocation + * @return + */ + private Result doServerFilter(RpcContext rpcContext, Invoker invoker, Invocation invocation) { + if (dubboProviderSofaTracer == null) { + this.dubboProviderSofaTracer = DubboProviderSofaTracer + .getDubboProviderSofaTracerSingleton(); + } + SofaTracerSpan sofaTracerSpan = serverReceived(invocation); + appendRpcServerSpanTags(invoker, sofaTracerSpan); + Result result; + Throwable exception = null; + try { + result = invoker.invoke(invocation); + // 处理返回结果 + if (result == null) { + return null; + } else { + appendElapsedTimeTags(invocation, sofaTracerSpan, result, false); + } + if (result.hasException()) { + exception = result.getException(); + } + return result; + } catch (RpcException e) { + exception = e; + throw e; + } catch (Throwable t) { + exception = t; + throw new RpcException(t); + } finally { + String resultCode = SUCCESS_CODE; + if (exception != null) { + if (exception instanceof RpcException) { + sofaTracerSpan.setTag(Tags.ERROR.getKey(), exception.getMessage()); + RpcException rpcException = (RpcException) exception; + if (rpcException.isBiz()) { + resultCode = String.valueOf(rpcException.getCode()); + } + } else { + resultCode = FAILED_CODE; + } + } + dubboProviderSofaTracer.serverSend(resultCode); + } + } + + private SofaTracerSpan serverReceived(Invocation invocation) { + Map tags = new HashMap(); + //server tags 必须设置 + tags.put(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_SERVER); + String serializeSpanContext = invocation.getAttachments() + .get(CommonSpanTags.RPC_TRACE_NAME); + SofaTracerSpanContext sofaTracerSpanContext = SofaTracerSpanContext + .deserializeFromString(serializeSpanContext); + boolean isCalculateSampler = false; + boolean isSampled = true; + if (sofaTracerSpanContext == null) { + SelfLog + .error("SpanContext created error when server received and root SpanContext created."); + sofaTracerSpanContext = SofaTracerSpanContext.rootStart(); + isCalculateSampler = true; + } + String simpleName = invocation.getInvoker().getInterface().getSimpleName(); + SofaTracerSpan serverSpan = new SofaTracerSpan(dubboProviderSofaTracer.getSofaTracer(), + System.currentTimeMillis(), simpleName, sofaTracerSpanContext, tags); + // calculate sampler + if (isCalculateSampler) { + Sampler sampler = dubboProviderSofaTracer.getSofaTracer().getSampler(); + if (sampler != null) { + isSampled = sampler.sample(serverSpan).isSampled(); + } + sofaTracerSpanContext.setSampled(isSampled); + } + SofaTraceContext sofaTraceContext = SofaTraceContextHolder.getSofaTraceContext(); + // Record server receive event + serverSpan.log(LogData.SERVER_RECV_EVENT_VALUE); + // 放到线程上下文 + sofaTraceContext.push(serverSpan); + return serverSpan; + } + + private void appendElapsedTimeTags(Invocation invocation, SofaTracerSpan sofaTracerSpan, + Result result, boolean isClient) { + if (sofaTracerSpan == null) { + return; + } + String reqSize = invocation.getAttachment(Constants.INPUT_KEY); + String respSize = result.getAttachment(Constants.OUTPUT_KEY); + String elapsed; + String deElapsed; + if (isClient) { + elapsed = invocation.getAttachment(CommonSpanTags.CLIENT_SERIALIZE_TIME); + deElapsed = invocation.getAttachment(CommonSpanTags.CLIENT_DESERIALIZE_TIME); + //客户端请求序列化耗时 + sofaTracerSpan + .setTag(CommonSpanTags.CLIENT_SERIALIZE_TIME, parseAttachment(elapsed, 0)); + //客户端接受响应反序列化耗时 + sofaTracerSpan.setTag(CommonSpanTags.CLIENT_DESERIALIZE_TIME, + parseAttachment(deElapsed, 0)); + } else { + elapsed = invocation.getAttachment(CommonSpanTags.SERVER_SERIALIZE_TIME); + deElapsed = invocation.getAttachment(CommonSpanTags.SERVER_DESERIALIZE_TIME); + sofaTracerSpan + .setTag(CommonSpanTags.SERVER_SERIALIZE_TIME, parseAttachment(elapsed, 0)); + sofaTracerSpan.setTag(CommonSpanTags.SERVER_DESERIALIZE_TIME, + parseAttachment(deElapsed, 0)); + } + sofaTracerSpan.setTag(CommonSpanTags.REQ_SIZE, parseAttachment(reqSize, 0)); + sofaTracerSpan.setTag(CommonSpanTags.RESP_SIZE, parseAttachment(respSize, 0)); + } + + private int parseAttachment(String value, int defaultVal) { + try { + if (StringUtils.isNotBlank(value)) { + defaultVal = Integer.parseInt(value); + } + } catch (Exception e) { + SelfLog.error("Failed to parse Dubbo plugin params.", e); + } + return defaultVal; + } + + /** + * set rpc server span tags + * @param invoker + * @param sofaTracerSpan + */ + private void appendRpcServerSpanTags(Invoker invoker, SofaTracerSpan sofaTracerSpan) { + if (sofaTracerSpan == null) { + return; + } + RpcContext rpcContext = RpcContext.getContext(); + Map tagsStr = sofaTracerSpan.getTagsWithStr(); + tagsStr.put(Tags.SPAN_KIND.getKey(), spanKind(rpcContext)); + String service = invoker.getInterface().getName(); + tagsStr.put(CommonSpanTags.SERVICE, service == null ? BLANK : service); + String methodName = rpcContext.getMethodName(); + tagsStr.put(CommonSpanTags.METHOD, methodName == null ? BLANK : methodName); + String app = rpcContext.getUrl().getParameter(Constants.APPLICATION_KEY); + tagsStr.put(CommonSpanTags.REMOTE_HOST, rpcContext.getRemoteHost()); + tagsStr.put(CommonSpanTags.LOCAL_APP, app == null ? BLANK : app); + tagsStr.put(CommonSpanTags.CURRENT_THREAD_NAME, Thread.currentThread().getName()); + String protocol = rpcContext.getUrl().getProtocol(); + tagsStr.put(CommonSpanTags.PROTOCOL, protocol == null ? BLANK : protocol); + tagsStr.put(CommonSpanTags.LOCAL_HOST, rpcContext.getRemoteHost()); + tagsStr.put(CommonSpanTags.LOCAL_PORT, String.valueOf(rpcContext.getRemotePort())); + } + + private void appendRpcClientSpanTags(Invoker invoker, SofaTracerSpan sofaTracerSpan) { + if (sofaTracerSpan == null) { + return; + } + RpcContext rpcContext = RpcContext.getContext(); + Map tagsStr = sofaTracerSpan.getTagsWithStr(); + tagsStr.put(Tags.SPAN_KIND.getKey(), spanKind(rpcContext)); + String protocol = rpcContext.getUrl().getProtocol(); + tagsStr.put(CommonSpanTags.PROTOCOL, protocol == null ? BLANK : protocol); + String service = invoker.getInterface().getName(); + tagsStr.put(CommonSpanTags.SERVICE, service == null ? BLANK : service); + String methodName = rpcContext.getMethodName(); + tagsStr.put(CommonSpanTags.METHOD, methodName == null ? BLANK : methodName); + tagsStr.put(CommonSpanTags.CURRENT_THREAD_NAME, Thread.currentThread().getName()); + String app = rpcContext.getUrl().getParameter(Constants.APPLICATION_KEY); + tagsStr.put(CommonSpanTags.LOCAL_APP, app == null ? BLANK : app); + tagsStr.put(CommonSpanTags.REMOTE_HOST, rpcContext.getRemoteHost()); + tagsStr.put(CommonSpanTags.REMOTE_PORT, String.valueOf(rpcContext.getRemotePort())); + tagsStr.put(CommonSpanTags.LOCAL_HOST, rpcContext.getLocalHost()); + } + + private String spanKind(RpcContext rpcContext) { + return rpcContext.isConsumerSide() ? Tags.SPAN_KIND_CLIENT : Tags.SPAN_KIND_SERVER; + } + + private String getTracerSpanMapKey(Invoker invoker) { + return SPAN_INVOKE_KEY + "." + invoker.hashCode(); + } +} diff --git a/sofa-tracer-plugins/sofa-tracer-dubbo-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo/encoder/DubboClientDigestJsonEncoder.java b/sofa-tracer-plugins/sofa-tracer-dubbo-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo/encoder/DubboClientDigestJsonEncoder.java new file mode 100644 index 00000000..73d8c9e5 --- /dev/null +++ b/sofa-tracer-plugins/sofa-tracer-dubbo-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo/encoder/DubboClientDigestJsonEncoder.java @@ -0,0 +1,104 @@ +/* + * 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 com.alipay.sofa.tracer.plugins.dubbo.encoder; + +import com.alipay.common.tracer.core.appender.builder.JsonStringBuilder; +import com.alipay.common.tracer.core.appender.self.Timestamp; +import com.alipay.common.tracer.core.context.span.SofaTracerSpanContext; +import com.alipay.common.tracer.core.middleware.parent.AbstractDigestSpanEncoder; +import com.alipay.common.tracer.core.span.CommonSpanTags; +import com.alipay.common.tracer.core.span.SofaTracerSpan; +import com.alipay.common.tracer.core.utils.StringUtils; +import io.opentracing.tag.Tags; + +import java.io.IOException; +import java.util.Map; + +/** + * @author: guolei.sgl (guolei.sgl@antfin.com) 2019/2/26 3:56 PM + * @since: + **/ +public class DubboClientDigestJsonEncoder extends AbstractDigestSpanEncoder { + + @Override + public String encode(SofaTracerSpan sofaTracerSpan) throws IOException { + + JsonStringBuilder data = new JsonStringBuilder(); + //span end time + data.appendBegin("time", Timestamp.format(sofaTracerSpan.getEndTime())); + + Map tagStr = sofaTracerSpan.getTagsWithStr(); + Map tagNum = sofaTracerSpan.getTagsWithNumber(); + SofaTracerSpanContext context = sofaTracerSpan.getSofaTracerSpanContext(); + + // TraceId + data.append("traceId", context.getTraceId()); + // SpanId + data.append("spanId", context.getSpanId()); + // Span Type + data.append(Tags.SPAN_KIND.getKey(), tagStr.get(Tags.SPAN_KIND.getKey())); + // app name + data.append(CommonSpanTags.LOCAL_APP, tagStr.get(CommonSpanTags.LOCAL_APP)); + // protocol + data.append(CommonSpanTags.PROTOCOL, tagStr.get(CommonSpanTags.PROTOCOL)); + // serviceName + data.append(CommonSpanTags.SERVICE, tagStr.get(CommonSpanTags.SERVICE)); + // method + data.append(CommonSpanTags.METHOD, tagStr.get(CommonSpanTags.METHOD)); + //invoke type + data.append(CommonSpanTags.INVOKE_TYPE, tagStr.get(CommonSpanTags.INVOKE_TYPE)); + //target ip + data.append(CommonSpanTags.REMOTE_HOST, tagStr.get(CommonSpanTags.REMOTE_HOST)); + //target port + data.append(CommonSpanTags.REMOTE_PORT, tagStr.get(CommonSpanTags.REMOTE_PORT)); + //local ip + data.append(CommonSpanTags.LOCAL_HOST, tagStr.get(CommonSpanTags.LOCAL_HOST)); + //request serialize time + data.append(CommonSpanTags.CLIENT_SERIALIZE_TIME, + tagNum.get(CommonSpanTags.CLIENT_SERIALIZE_TIME)); + //response deserialize time + data.append(CommonSpanTags.CLIENT_DESERIALIZE_TIME, + tagNum.get(CommonSpanTags.CLIENT_DESERIALIZE_TIME)); + //Request Body bytes length + Number reqSizeNum = tagNum.get(CommonSpanTags.REQ_SIZE); + data.append(CommonSpanTags.REQ_SIZE, reqSizeNum == null ? 0 : reqSizeNum.longValue()); + //Response Body bytes length + Number respSizeNum = tagNum.get(CommonSpanTags.REQ_SIZE); + data.append(CommonSpanTags.RESP_SIZE, respSizeNum == null ? 0 : respSizeNum.longValue()); + //Http status code + data.append(CommonSpanTags.RESULT_CODE, tagStr.get(CommonSpanTags.RESULT_CODE)); + //error message + if (StringUtils.isNotBlank(tagStr.get(Tags.ERROR.getKey()))) { + data.append(Tags.ERROR.getKey(), tagStr.get(Tags.ERROR.getKey())); + } + //thread name + data.append(CommonSpanTags.CURRENT_THREAD_NAME, + tagStr.get(CommonSpanTags.CURRENT_THREAD_NAME)); + //time-consuming ms + data.append("time.cost.milliseconds", + (sofaTracerSpan.getEndTime() - sofaTracerSpan.getStartTime())); + this.appendBaggage(data, context); + return data.toString(); + } + + private void appendBaggage(JsonStringBuilder jsonStringBuilder, + SofaTracerSpanContext sofaTracerSpanContext) { + //baggage + jsonStringBuilder.appendEnd("baggage", baggageSerialized(sofaTracerSpanContext)); + } + +} diff --git a/sofa-tracer-plugins/sofa-tracer-dubbo-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo/encoder/DubboServerDigestJsonEncoder.java b/sofa-tracer-plugins/sofa-tracer-dubbo-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo/encoder/DubboServerDigestJsonEncoder.java new file mode 100644 index 00000000..67138081 --- /dev/null +++ b/sofa-tracer-plugins/sofa-tracer-dubbo-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo/encoder/DubboServerDigestJsonEncoder.java @@ -0,0 +1,95 @@ +/* + * 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 com.alipay.sofa.tracer.plugins.dubbo.encoder; + +import com.alipay.common.tracer.core.appender.builder.JsonStringBuilder; +import com.alipay.common.tracer.core.appender.self.Timestamp; +import com.alipay.common.tracer.core.context.span.SofaTracerSpanContext; +import com.alipay.common.tracer.core.middleware.parent.AbstractDigestSpanEncoder; +import com.alipay.common.tracer.core.span.CommonSpanTags; +import com.alipay.common.tracer.core.span.SofaTracerSpan; +import com.alipay.common.tracer.core.utils.StringUtils; +import io.opentracing.tag.Tags; + +import java.io.IOException; +import java.util.Map; + +/** + * @author: guolei.sgl (guolei.sgl@antfin.com) 2019/2/26 4:19 PM + * @since: + **/ +public class DubboServerDigestJsonEncoder extends AbstractDigestSpanEncoder { + + @Override + public String encode(SofaTracerSpan sofaTracerSpan) throws IOException { + JsonStringBuilder data = new JsonStringBuilder(); + //span end time + data.appendBegin("time", Timestamp.format(sofaTracerSpan.getEndTime())); + Map tagStr = sofaTracerSpan.getTagsWithStr(); + Map tagNum = sofaTracerSpan.getTagsWithNumber(); + SofaTracerSpanContext context = sofaTracerSpan.getSofaTracerSpanContext(); + //TraceId + data.append("traceId", context.getTraceId()); + //SpanId + data.append("spanId", context.getSpanId()); + //Span Type + data.append(Tags.SPAN_KIND.getKey(), tagStr.get(Tags.SPAN_KIND.getKey())); + //local appName + data.append(CommonSpanTags.LOCAL_APP, tagStr.get(CommonSpanTags.LOCAL_APP)); + //serviceName + data.append(CommonSpanTags.SERVICE, tagStr.get(CommonSpanTags.SERVICE)); + //method + data.append(CommonSpanTags.METHOD, tagStr.get(CommonSpanTags.METHOD)); + //local ip + data.append(CommonSpanTags.LOCAL_HOST, tagStr.get(CommonSpanTags.LOCAL_HOST)); + //local port + data.append(CommonSpanTags.LOCAL_PORT, tagStr.get(CommonSpanTags.LOCAL_PORT)); + //protocol + data.append(CommonSpanTags.PROTOCOL, tagStr.get(CommonSpanTags.PROTOCOL)); + long serializeTime = getTime(tagNum.get(CommonSpanTags.SERVER_SERIALIZE_TIME)); + data.append(CommonSpanTags.SERVER_SERIALIZE_TIME, serializeTime); + long deserializeTime = getTime(tagNum.get(CommonSpanTags.SERVER_DESERIALIZE_TIME)); + data.append(CommonSpanTags.SERVER_DESERIALIZE_TIME, deserializeTime); + //Http status code + data.append(CommonSpanTags.RESULT_CODE, tagStr.get(CommonSpanTags.RESULT_CODE)); + //error message + if (StringUtils.isNotBlank(tagStr.get(Tags.ERROR.getKey()))) { + data.append(Tags.ERROR.getKey(), tagStr.get(Tags.ERROR.getKey())); + } + //thread name + data.append(CommonSpanTags.CURRENT_THREAD_NAME, + tagStr.get(CommonSpanTags.CURRENT_THREAD_NAME)); + //time-consuming ms + data.append("time.cost.milliseconds", + (sofaTracerSpan.getEndTime() - sofaTracerSpan.getStartTime())); + this.appendBaggage(data, context); + return data.toString(); + } + + private long getTime(Number number) { + if (number != null) { + return number.longValue(); + } + return 0; + } + + private void appendBaggage(JsonStringBuilder jsonStringBuilder, + SofaTracerSpanContext sofaTracerSpanContext) { + //baggage + jsonStringBuilder.appendEnd("baggage", baggageSerialized(sofaTracerSpanContext)); + } +} diff --git a/sofa-tracer-plugins/sofa-tracer-dubbo-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo/enums/DubboLogEnum.java b/sofa-tracer-plugins/sofa-tracer-dubbo-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo/enums/DubboLogEnum.java new file mode 100644 index 00000000..48829250 --- /dev/null +++ b/sofa-tracer-plugins/sofa-tracer-dubbo-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo/enums/DubboLogEnum.java @@ -0,0 +1,60 @@ +/* + * 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 com.alipay.sofa.tracer.plugins.dubbo.enums; + +/** + * @author: guolei.sgl (guolei.sgl@antfin.com) 2019/2/26 3:43 PM + * @since: + **/ +public enum DubboLogEnum { + + DUBBO_SERVER_DIGEST("dubbo_server_digest_log_name", "dubbo-server-digest.log", + "dubbo_server_digest_rolling"), + + DUBBO_SERVER_STAT("dubbo_server_stat_log_name", "dubbo-server-stat.log", + "dubbo_server_stat_rolling"), + + DUBBO_CLIENT_DIGEST("dubbo_client_digest_log_name", "dubbo-client-digest.log", + "dubbo_client_digest_rolling"), + + DUBBO_CLIENT_STAT("dubbo_client_stat_log_name", "dubbo-client-stat.log", + "dubbot_client_stat_rolling"); + + private String logNameKey; + private String defaultLogName; + private String rollingKey; + + DubboLogEnum(String logNameKey, String defaultLogName, String rollingKey) { + this.logNameKey = logNameKey; + this.defaultLogName = defaultLogName; + this.rollingKey = rollingKey; + } + + public String getLogNameKey() { + //log reserve config key + return logNameKey; + } + + public String getDefaultLogName() { + return defaultLogName; + } + + public String getRollingKey() { + return rollingKey; + } + +} diff --git a/sofa-tracer-plugins/sofa-tracer-dubbo-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo/stat/DubboClientStatJsonReporter.java b/sofa-tracer-plugins/sofa-tracer-dubbo-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo/stat/DubboClientStatJsonReporter.java new file mode 100644 index 00000000..bbd439f0 --- /dev/null +++ b/sofa-tracer-plugins/sofa-tracer-dubbo-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo/stat/DubboClientStatJsonReporter.java @@ -0,0 +1,122 @@ +/* + * 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 com.alipay.sofa.tracer.plugins.dubbo.stat; + +import com.alipay.common.tracer.core.appender.builder.JsonStringBuilder; +import com.alipay.common.tracer.core.appender.file.LoadTestAwareAppender; +import com.alipay.common.tracer.core.appender.self.SelfLog; +import com.alipay.common.tracer.core.appender.self.Timestamp; +import com.alipay.common.tracer.core.reporter.stat.AbstractSofaTracerStatisticReporter; +import com.alipay.common.tracer.core.reporter.stat.model.StatKey; +import com.alipay.common.tracer.core.reporter.stat.model.StatMapKey; +import com.alipay.common.tracer.core.span.CommonSpanTags; +import com.alipay.common.tracer.core.span.SofaTracerSpan; +import com.alipay.common.tracer.core.utils.TracerUtils; + +import java.util.Map; + +/** + * @author: guolei.sgl (guolei.sgl@antfin.com) 2019/2/26 4:23 PM + * @since: + **/ +public class DubboClientStatJsonReporter extends AbstractSofaTracerStatisticReporter { + + /*** + * print builder + */ + private static JsonStringBuilder jsonBuffer = new JsonStringBuilder(); + + public DubboClientStatJsonReporter(String statTracerName, String rollingPolicy, + String logReserveConfig) { + super(statTracerName, rollingPolicy, logReserveConfig); + } + + @Override + public void doReportStat(SofaTracerSpan sofaTracerSpan) { + //tags + Map tagsWithStr = sofaTracerSpan.getTagsWithStr(); + StatMapKey statKey = new StatMapKey(); + String fromApp = tagsWithStr.get(CommonSpanTags.LOCAL_APP); + String toApp = tagsWithStr.get(CommonSpanTags.REMOTE_APP); + //service name + String serviceName = tagsWithStr.get(CommonSpanTags.SERVICE); + //method name + String methodName = tagsWithStr.get(CommonSpanTags.METHOD); + statKey.setKey(buildString(new String[] { fromApp, toApp, serviceName, methodName })); + String resultCode = tagsWithStr.get(CommonSpanTags.RESULT_CODE); + statKey.setResult(resultCode.equals("00") ? "Y" : "N"); + statKey.setEnd(buildString(new String[] { getLoadTestMark(sofaTracerSpan) })); + statKey.setLoadTest(TracerUtils.isLoadTest(sofaTracerSpan)); + statKey.addKey(CommonSpanTags.LOCAL_APP, fromApp); + statKey.addKey(CommonSpanTags.REMOTE_APP, toApp); + statKey.addKey(CommonSpanTags.SERVICE, serviceName); + statKey.addKey(CommonSpanTags.METHOD, methodName); + //次数和耗时,最后一个耗时是单独打印的字段 + long duration = sofaTracerSpan.getEndTime() - sofaTracerSpan.getStartTime(); + long[] values = new long[] { 1, duration }; + this.addStat(statKey, values); + } + + protected String getLoadTestMark(SofaTracerSpan span) { + if (TracerUtils.isLoadTest(span)) { + return "T"; + } else { + return "F"; + } + } + + @Override + public void print(StatKey statKey, long[] values) { + if (this.isClosePrint.get()) { + //关闭统计日志输出 + return; + } + + StatMapKey statMapKey = (StatMapKey) statKey; + + jsonBuffer.reset(); + jsonBuffer.appendBegin("time", Timestamp.currentTime()); + jsonBuffer.append("stat.key", this.statKeySplit(statMapKey)); + jsonBuffer.append("count", values[0]); + jsonBuffer.append("total.cost.milliseconds", values[1]); + jsonBuffer.append("success", statMapKey.getResult()); + jsonBuffer.appendEnd(); + try { + if (appender instanceof LoadTestAwareAppender) { + ((LoadTestAwareAppender) appender).append(jsonBuffer.toString(), + statKey.isLoadTest()); + } else { + appender.append(jsonBuffer.toString()); + } + // 这里强制刷一次 + appender.flush(); + } catch (Throwable t) { + SelfLog.error("stat log<" + statTracerName + "> error!", t); + } + } + + private String statKeySplit(StatMapKey statKey) { + JsonStringBuilder jsonBufferKey = new JsonStringBuilder(); + Map keyMap = statKey.getKeyMap(); + jsonBufferKey.appendBegin(); + for (Map.Entry entry : keyMap.entrySet()) { + jsonBufferKey.append(entry.getKey(), entry.getValue()); + } + jsonBufferKey.appendEnd(false); + return jsonBufferKey.toString(); + } +} diff --git a/sofa-tracer-plugins/sofa-tracer-dubbo-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo/stat/DubboServerStatJsonReporter.java b/sofa-tracer-plugins/sofa-tracer-dubbo-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo/stat/DubboServerStatJsonReporter.java new file mode 100644 index 00000000..12acdfba --- /dev/null +++ b/sofa-tracer-plugins/sofa-tracer-dubbo-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo/stat/DubboServerStatJsonReporter.java @@ -0,0 +1,122 @@ +/* + * 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 com.alipay.sofa.tracer.plugins.dubbo.stat; + +import com.alipay.common.tracer.core.appender.builder.JsonStringBuilder; +import com.alipay.common.tracer.core.appender.file.LoadTestAwareAppender; +import com.alipay.common.tracer.core.appender.self.SelfLog; +import com.alipay.common.tracer.core.appender.self.Timestamp; +import com.alipay.common.tracer.core.reporter.stat.AbstractSofaTracerStatisticReporter; +import com.alipay.common.tracer.core.reporter.stat.model.StatKey; +import com.alipay.common.tracer.core.reporter.stat.model.StatMapKey; +import com.alipay.common.tracer.core.span.CommonSpanTags; +import com.alipay.common.tracer.core.span.SofaTracerSpan; +import com.alipay.common.tracer.core.utils.TracerUtils; + +import java.util.Map; + +/** + * @author: guolei.sgl (guolei.sgl@antfin.com) 2019/2/26 4:23 PM + * @since: + **/ +public class DubboServerStatJsonReporter extends AbstractSofaTracerStatisticReporter { + + /*** + * print builder + */ + private static JsonStringBuilder jsonBuffer = new JsonStringBuilder(); + + public DubboServerStatJsonReporter(String statTracerName, String rollingPolicy, + String logReserveConfig) { + super(statTracerName, rollingPolicy, logReserveConfig); + } + + @Override + public void doReportStat(SofaTracerSpan sofaTracerSpan) { + //tags + Map tagsWithStr = sofaTracerSpan.getTagsWithStr(); + StatMapKey statKey = new StatMapKey(); + String fromApp = tagsWithStr.get(CommonSpanTags.REMOTE_APP); + String toApp = tagsWithStr.get(CommonSpanTags.LOCAL_APP); + //service name + String serviceName = tagsWithStr.get(CommonSpanTags.SERVICE); + //method name + String methodName = tagsWithStr.get(CommonSpanTags.METHOD); + statKey.setKey(buildString(new String[] { fromApp, toApp, serviceName, methodName })); + String resultCode = tagsWithStr.get(CommonSpanTags.RESULT_CODE); + statKey.setResult(resultCode.equals("00") ? "Y" : "N"); + statKey.setEnd(buildString(new String[] { getLoadTestMark(sofaTracerSpan) })); + statKey.setLoadTest(TracerUtils.isLoadTest(sofaTracerSpan)); + statKey.addKey(CommonSpanTags.LOCAL_APP, fromApp); + statKey.addKey(CommonSpanTags.REMOTE_APP, toApp); + statKey.addKey(CommonSpanTags.SERVICE, serviceName); + statKey.addKey(CommonSpanTags.METHOD, methodName); + //次数和耗时,最后一个耗时是单独打印的字段 + long duration = sofaTracerSpan.getEndTime() - sofaTracerSpan.getStartTime(); + long[] values = new long[] { 1, duration }; + this.addStat(statKey, values); + } + + protected String getLoadTestMark(SofaTracerSpan span) { + if (TracerUtils.isLoadTest(span)) { + return "T"; + } else { + return "F"; + } + } + + @Override + public void print(StatKey statKey, long[] values) { + if (this.isClosePrint.get()) { + //关闭统计日志输出 + return; + } + + StatMapKey statMapKey = (StatMapKey) statKey; + + jsonBuffer.reset(); + jsonBuffer.appendBegin("time", Timestamp.currentTime()); + jsonBuffer.append("stat.key", this.statKeySplit(statMapKey)); + jsonBuffer.append("count", values[0]); + jsonBuffer.append("total.cost.milliseconds", values[1]); + jsonBuffer.append("success", statMapKey.getResult()); + jsonBuffer.appendEnd(); + try { + if (appender instanceof LoadTestAwareAppender) { + ((LoadTestAwareAppender) appender).append(jsonBuffer.toString(), + statKey.isLoadTest()); + } else { + appender.append(jsonBuffer.toString()); + } + // 这里强制刷一次 + appender.flush(); + } catch (Throwable t) { + SelfLog.error("stat log <" + statTracerName + "> error!", t); + } + } + + private String statKeySplit(StatMapKey statKey) { + JsonStringBuilder jsonBufferKey = new JsonStringBuilder(); + Map keyMap = statKey.getKeyMap(); + jsonBufferKey.appendBegin(); + for (Map.Entry entry : keyMap.entrySet()) { + jsonBufferKey.append(entry.getKey(), entry.getValue()); + } + jsonBufferKey.appendEnd(false); + return jsonBufferKey.toString(); + } +} diff --git a/sofa-tracer-plugins/sofa-tracer-dubbo-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo/tracer/DubboConsumerSofaTracer.java b/sofa-tracer-plugins/sofa-tracer-dubbo-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo/tracer/DubboConsumerSofaTracer.java new file mode 100644 index 00000000..f4d5798f --- /dev/null +++ b/sofa-tracer-plugins/sofa-tracer-dubbo-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo/tracer/DubboConsumerSofaTracer.java @@ -0,0 +1,81 @@ +/* + * 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 com.alipay.sofa.tracer.plugins.dubbo.tracer; + +import com.alipay.common.tracer.core.appender.encoder.SpanEncoder; +import com.alipay.common.tracer.core.configuration.SofaTracerConfiguration; +import com.alipay.common.tracer.core.reporter.stat.AbstractSofaTracerStatisticReporter; +import com.alipay.common.tracer.core.span.SofaTracerSpan; +import com.alipay.common.tracer.core.tracer.AbstractClientTracer; +import com.alipay.sofa.tracer.plugins.dubbo.encoder.DubboClientDigestJsonEncoder; +import com.alipay.sofa.tracer.plugins.dubbo.enums.DubboLogEnum; +import com.alipay.sofa.tracer.plugins.dubbo.stat.DubboClientStatJsonReporter; + +/** + * @author: guolei.sgl (guolei.sgl@antfin.com) 2019/2/26 3:33 PM + * @since: + **/ +public class DubboConsumerSofaTracer extends AbstractClientTracer { + + private volatile static DubboConsumerSofaTracer dubboConsumerSofaTracer = null; + + public static DubboConsumerSofaTracer getDubboConsumerSofaTracerSingleton() { + if (dubboConsumerSofaTracer == null) { + synchronized (DubboConsumerSofaTracer.class) { + if (dubboConsumerSofaTracer == null) { + dubboConsumerSofaTracer = new DubboConsumerSofaTracer("dubbo-client"); + } + } + } + return dubboConsumerSofaTracer; + } + + public DubboConsumerSofaTracer(String tracerType) { + super(tracerType); + } + + @Override + protected String getClientDigestReporterLogName() { + return DubboLogEnum.DUBBO_CLIENT_DIGEST.getDefaultLogName(); + } + + @Override + protected String getClientDigestReporterRollingKey() { + return DubboLogEnum.DUBBO_CLIENT_DIGEST.getRollingKey(); + } + + @Override + protected String getClientDigestReporterLogNameKey() { + return DubboLogEnum.DUBBO_CLIENT_DIGEST.getLogNameKey(); + } + + @Override + protected SpanEncoder getClientDigestEncoder() { + return new DubboClientDigestJsonEncoder(); + } + + @Override + protected AbstractSofaTracerStatisticReporter generateClientStatReporter() { + DubboLogEnum dubboClientStat = DubboLogEnum.DUBBO_CLIENT_STAT; + String statLog = dubboClientStat.getDefaultLogName(); + String statRollingPolicy = SofaTracerConfiguration.getRollingPolicy(dubboClientStat + .getRollingKey()); + String statLogReserveConfig = SofaTracerConfiguration.getLogReserveConfig(dubboClientStat + .getLogNameKey()); + return new DubboClientStatJsonReporter(statLog, statRollingPolicy, statLogReserveConfig); + } +} diff --git a/sofa-tracer-plugins/sofa-tracer-dubbo-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo/tracer/DubboProviderSofaTracer.java b/sofa-tracer-plugins/sofa-tracer-dubbo-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo/tracer/DubboProviderSofaTracer.java new file mode 100644 index 00000000..b02dd871 --- /dev/null +++ b/sofa-tracer-plugins/sofa-tracer-dubbo-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo/tracer/DubboProviderSofaTracer.java @@ -0,0 +1,81 @@ +/* + * 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 com.alipay.sofa.tracer.plugins.dubbo.tracer; + +import com.alipay.common.tracer.core.appender.encoder.SpanEncoder; +import com.alipay.common.tracer.core.configuration.SofaTracerConfiguration; +import com.alipay.common.tracer.core.reporter.stat.AbstractSofaTracerStatisticReporter; +import com.alipay.common.tracer.core.span.SofaTracerSpan; +import com.alipay.common.tracer.core.tracer.AbstractServerTracer; +import com.alipay.sofa.tracer.plugins.dubbo.encoder.DubboServerDigestJsonEncoder; +import com.alipay.sofa.tracer.plugins.dubbo.enums.DubboLogEnum; +import com.alipay.sofa.tracer.plugins.dubbo.stat.DubboServerStatJsonReporter; + +/** + * @author: guolei.sgl (guolei.sgl@antfin.com) 2019/2/26 3:47 PM + * @since: + **/ +public class DubboProviderSofaTracer extends AbstractServerTracer { + + private volatile static DubboProviderSofaTracer dubboProviderSofaTracer = null; + + public static DubboProviderSofaTracer getDubboProviderSofaTracerSingleton() { + if (dubboProviderSofaTracer == null) { + synchronized (DubboProviderSofaTracer.class) { + if (dubboProviderSofaTracer == null) { + dubboProviderSofaTracer = new DubboProviderSofaTracer("dubbo-server"); + } + } + } + return dubboProviderSofaTracer; + } + + public DubboProviderSofaTracer(String tracerType) { + super(tracerType); + } + + @Override + protected String getServerDigestReporterLogName() { + return DubboLogEnum.DUBBO_SERVER_DIGEST.getDefaultLogName(); + } + + @Override + protected String getServerDigestReporterRollingKey() { + return DubboLogEnum.DUBBO_SERVER_DIGEST.getRollingKey(); + } + + @Override + protected String getServerDigestReporterLogNameKey() { + return DubboLogEnum.DUBBO_SERVER_DIGEST.getLogNameKey(); + } + + @Override + protected SpanEncoder getServerDigestEncoder() { + return new DubboServerDigestJsonEncoder(); + } + + @Override + protected AbstractSofaTracerStatisticReporter generateServerStatReporter() { + DubboLogEnum dubboClientStat = DubboLogEnum.DUBBO_SERVER_STAT; + String statLog = dubboClientStat.getDefaultLogName(); + String statRollingPolicy = SofaTracerConfiguration.getRollingPolicy(dubboClientStat + .getRollingKey()); + String statLogReserveConfig = SofaTracerConfiguration.getLogReserveConfig(dubboClientStat + .getLogNameKey()); + return new DubboServerStatJsonReporter(statLog, statRollingPolicy, statLogReserveConfig); + } +} diff --git a/sofa-tracer-plugins/sofa-tracer-dubbo-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo/wrapper/DataSizeCodecWrapper.java b/sofa-tracer-plugins/sofa-tracer-dubbo-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo/wrapper/DataSizeCodecWrapper.java new file mode 100644 index 00000000..de1c88d8 --- /dev/null +++ b/sofa-tracer-plugins/sofa-tracer-dubbo-plugin/src/main/java/com/alipay/sofa/tracer/plugins/dubbo/wrapper/DataSizeCodecWrapper.java @@ -0,0 +1,139 @@ +/* + * 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 com.alipay.sofa.tracer.plugins.dubbo.wrapper; + +import com.alipay.common.tracer.core.span.CommonSpanTags; +import org.apache.dubbo.common.Constants; +import org.apache.dubbo.remoting.Channel; +import org.apache.dubbo.remoting.Codec2; +import org.apache.dubbo.remoting.buffer.ChannelBuffer; +import org.apache.dubbo.remoting.exchange.Request; +import org.apache.dubbo.remoting.exchange.Response; +import org.apache.dubbo.rpc.RpcInvocation; +import org.apache.dubbo.rpc.RpcResult; +import java.io.IOException; + +/** + * @author: guolei.sgl (guolei.sgl@antfin.com) 2019/2/26 7:46 PM + * @since: + **/ +public class DataSizeCodecWrapper implements Codec2 { + /** + * origin codec + */ + protected Codec2 codec; + + public DataSizeCodecWrapper(Codec2 codec) { + this.codec = codec; + } + + @Override + public void encode(Channel channel, ChannelBuffer buffer, Object message) throws IOException { + if (message instanceof Request) { + Object data = ((Request) message).getData(); + if (data instanceof RpcInvocation) { + RpcInvocation invocation = (RpcInvocation) data; + encodeRequestWithTracer(channel, buffer, message, invocation); + return; + } + } else if (message instanceof Response) { + Object result = ((Response) message).getResult(); + if (result instanceof RpcResult) { + RpcResult rpcResult = (RpcResult) result; + encodeResultWithTracer(channel, buffer, message, rpcResult); + return; + } + } + // 其它走原来 + codec.encode(channel, buffer, message); + } + + /** + * @param channel 长连接 + * @param buffer UnsafeByteArrayOutputStream + * @param message 原生Request对象 + * @param invocation Request里的Invocation + * @throws IOException 序列化出现异常 + */ + protected void encodeRequestWithTracer(Channel channel, ChannelBuffer buffer, Object message, + RpcInvocation invocation) throws IOException { + long startTime = System.currentTimeMillis(); + int index = buffer.writerIndex(); + // 序列化 + codec.encode(channel, buffer, message); + int reqSize = buffer.writerIndex() - index; + long elapsed = System.currentTimeMillis() - startTime; + invocation.setAttachment(Constants.INPUT_KEY, String.valueOf(reqSize)); + invocation.setAttachment(CommonSpanTags.CLIENT_SERIALIZE_TIME, String.valueOf(elapsed)); + } + + /** + * @param channel 长连接 + * @param buffer UnsafeByteArrayOutputStream + * @param result 原生Resopnse对象 + * @param rpcResult Resopnse对象的结果 + * @throws IOException 序列化出现异常 + */ + protected void encodeResultWithTracer(Channel channel, ChannelBuffer buffer, Object result, + RpcResult rpcResult) throws IOException { + + long startTime = System.currentTimeMillis(); + int index = buffer.writerIndex(); + codec.encode(channel, buffer, result); + int respSize = buffer.writerIndex() - index; + long elapsed = System.currentTimeMillis() - startTime; + rpcResult.setAttachment(Constants.OUTPUT_KEY, String.valueOf(respSize)); + rpcResult.setAttachment(CommonSpanTags.SERVER_SERIALIZE_TIME, String.valueOf(elapsed)); + } + + /** + * 反序列化操作 + * @param channel + * @param input + * @return + * @throws IOException + */ + @Override + public Object decode(Channel channel, ChannelBuffer input) throws IOException { + long startTime = System.currentTimeMillis(); + int index = input.readerIndex(); + Object ret = codec.decode(channel, input); + int size = input.readerIndex() - index; + long elapsed = System.currentTimeMillis() - startTime; + if (ret instanceof Request) { + // 服务端反序列化Request + Object data = ((Request) ret).getData(); + if (data instanceof RpcInvocation) { + RpcInvocation invocation = (RpcInvocation) data; + invocation.setAttachment(Constants.INPUT_KEY, String.valueOf(size)); + invocation.setAttachment(CommonSpanTags.SERVER_DESERIALIZE_TIME, + String.valueOf(elapsed)); + } + + } else if (ret instanceof Response) { + // 客户端反序列化Response + Object result = ((Response) ret).getResult(); + if (result instanceof RpcResult) { + RpcResult rpcResult = (RpcResult) result; + rpcResult.setAttachment(Constants.OUTPUT_KEY, String.valueOf(size)); + rpcResult.setAttachment(CommonSpanTags.CLIENT_DESERIALIZE_TIME, + String.valueOf(elapsed)); + } + } + return ret; + } +} diff --git a/sofa-tracer-plugins/sofa-tracer-dubbo-plugin/src/main/resources/META-INF/dubbo/com.alibaba.dubbo.remoting.Codec2 b/sofa-tracer-plugins/sofa-tracer-dubbo-plugin/src/main/resources/META-INF/dubbo/com.alibaba.dubbo.remoting.Codec2 new file mode 100644 index 00000000..b41d89ce --- /dev/null +++ b/sofa-tracer-plugins/sofa-tracer-dubbo-plugin/src/main/resources/META-INF/dubbo/com.alibaba.dubbo.remoting.Codec2 @@ -0,0 +1 @@ +tracerCodec=com.alipay.sofa.tracer.plugins.dubbo.wrapper.DataSizeCodecWrapper \ No newline at end of file diff --git a/sofa-tracer-plugins/sofa-tracer-dubbo-plugin/src/main/resources/META-INF/dubbo/com.alibaba.dubbo.rpc.Filter b/sofa-tracer-plugins/sofa-tracer-dubbo-plugin/src/main/resources/META-INF/dubbo/com.alibaba.dubbo.rpc.Filter new file mode 100644 index 00000000..2d55d257 --- /dev/null +++ b/sofa-tracer-plugins/sofa-tracer-dubbo-plugin/src/main/resources/META-INF/dubbo/com.alibaba.dubbo.rpc.Filter @@ -0,0 +1 @@ +dubboSofaTracerFilter=com.alipay.sofa.tracer.plugins.dubbo.DubboSofaTracerFilter diff --git a/sofa-tracer-plugins/sofa-tracer-dubbo-plugin/src/test/java/com/alipay/sofa/tracer/plugins/dubbo/DubboSofaTracerTest.java b/sofa-tracer-plugins/sofa-tracer-dubbo-plugin/src/test/java/com/alipay/sofa/tracer/plugins/dubbo/DubboSofaTracerTest.java new file mode 100644 index 00000000..9811670c --- /dev/null +++ b/sofa-tracer-plugins/sofa-tracer-dubbo-plugin/src/test/java/com/alipay/sofa/tracer/plugins/dubbo/DubboSofaTracerTest.java @@ -0,0 +1,155 @@ +/* + * 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 com.alipay.sofa.tracer.plugins.dubbo; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.alipay.common.tracer.core.span.CommonSpanTags; +import com.alipay.sofa.tracer.plugins.dubbo.enums.DubboLogEnum; +import com.alipay.sofa.tracer.plugins.dubbo.impl.DubboServiceImpl; +import com.alipay.sofa.tracer.plugins.dubbo.service.DubboService; +import org.apache.commons.io.FileUtils; +import org.apache.dubbo.common.URL; +import org.apache.dubbo.config.*; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import java.io.File; +import java.util.List; + +/** + * @author: guolei.sgl (guolei.sgl@antfin.com) 2019/2/27 8:36 PM + * @since: + **/ +public class DubboSofaTracerTest { + + protected static String logDirectoryPath = System.getProperty("user.home") + File.separator + + "logs" + File.separator + "tracelog"; + + private static String address = ""; + + @Before + public void testBefore() throws Exception { + cleanFile(); + // application + ApplicationConfig application = new ApplicationConfig(); + application.setName("test-server"); + // registry + RegistryConfig registryConfig = new RegistryConfig(); + registryConfig.setAddress("N/A"); + // 服务提供者协议配置 + ProtocolConfig protocol = new ProtocolConfig(); + protocol.setName("dubbo"); + protocol.setThreadpool("fixed"); + protocol.setPort(12280); + protocol.setSerialization("hessian2"); + // 服务提供者连接注册中心,设置属性 + DubboServiceImpl dubboServiceImpl = new DubboServiceImpl(); + ServiceConfig service = new ServiceConfig(); + service.setApplication(application); + service.setProtocol(protocol); // 多个协议可以用setProtocols() + service.setInterface(DubboService.class.getName()); + service.setRef(dubboServiceImpl); + service.setGroup("tracer"); + service.setVersion("1.0"); + service.setFilter("dubboSofaTracerFilter"); + service.setRegistry(registryConfig); + //services.setRegister(false); + // 暴露及注册服务 + service.export(); + List exportedUrls = service.getExportedUrls(); + Assert.assertTrue(exportedUrls.size() == 1); + address = exportedUrls.get(0).toString(); + } + + @Test + public void testTracer() throws Exception { + RegistryConfig registryConfig = new RegistryConfig(); + registryConfig.setAddress("N/A"); + // 服务调用者连接注册中心,设置属性 + ReferenceConfig reference = new ReferenceConfig(); // 此实例很重,封装了与注册中心的连接以及与提供者的连接,请自行缓存,否则可能造成内存和连接泄漏 + reference.setInterface(DubboService.class); + reference.setRegistry(registryConfig); + reference.setUrl(address); + reference.setVersion("1.0"); + reference.setGroup("tracer"); + reference.setFilter("dubboSofaTracerFilter"); + DubboService service = reference.get(); + Assert.assertEquals(service.echoStr("sofa-tarcer"), "sofa-tarcer"); + + Thread.sleep(500); + //wait for async output + List serverContent = FileUtils.readLines(new File( + logDirectoryPath + File.separator + + DubboLogEnum.DUBBO_SERVER_DIGEST.getDefaultLogName())); + Assert.assertTrue(serverContent.size() == 1); + String jsonData = serverContent.get(0); + JSONObject json = JSON.parseObject(jsonData); + Assert.assertEquals(json.getString(CommonSpanTags.SERVICE), + "com.alipay.sofa.tracer.plugins.dubbo.service.DubboService"); + Assert.assertEquals(json.getString(CommonSpanTags.LOCAL_APP), "test-server"); + Assert.assertEquals(json.getString("spanId"), "0"); + Assert.assertEquals(json.getString(CommonSpanTags.METHOD), "echoStr"); + Assert.assertEquals(json.getString(CommonSpanTags.PROTOCOL), "dubbo"); + Assert.assertEquals(json.getString("span.kind"), "server"); + + //wait for async output + List clientContents = FileUtils.readLines(new File( + logDirectoryPath + File.separator + + DubboLogEnum.DUBBO_CLIENT_DIGEST.getDefaultLogName())); + + Assert.assertTrue(clientContents.size() == 1); + String clientData = clientContents.get(0); + JSONObject clientJson = JSON.parseObject(clientData); + + Assert.assertEquals(clientJson.getString(CommonSpanTags.SERVICE), + "com.alipay.sofa.tracer.plugins.dubbo.service.DubboService"); + Assert.assertEquals(clientJson.getString(CommonSpanTags.LOCAL_APP), "test-server"); + Assert.assertEquals(clientJson.getString("spanId"), "0"); + Assert.assertEquals(clientJson.getString(CommonSpanTags.METHOD), "echoStr"); + Assert.assertEquals(clientJson.getString(CommonSpanTags.PROTOCOL), "dubbo"); + Assert.assertEquals(clientJson.getString("span.kind"), "client"); + + Thread.sleep(60 * 1000); + + //wait for async output + List clientStatContents = FileUtils + .readLines(new File(logDirectoryPath + File.separator + + DubboLogEnum.DUBBO_CLIENT_STAT.getDefaultLogName())); + + Assert.assertTrue(clientStatContents.size() == 1); + + //wait for async output + List serverStatContents = FileUtils + .readLines(new File(logDirectoryPath + File.separator + + DubboLogEnum.DUBBO_SERVER_STAT.getDefaultLogName())); + + Assert.assertTrue(serverStatContents.size() == 1); + + } + + private void cleanFile() { + DubboLogEnum[] dubboLogEnums = DubboLogEnum.values(); + for (DubboLogEnum dubboLogEnum : dubboLogEnums) { + String logName = dubboLogEnum.getDefaultLogName(); + File logFile = new File(logDirectoryPath + File.separator + logName); + if (logFile.exists()) { + logFile.delete(); + } + } + } +} diff --git a/sofa-tracer-plugins/sofa-tracer-dubbo-plugin/src/test/java/com/alipay/sofa/tracer/plugins/dubbo/impl/DubboServiceImpl.java b/sofa-tracer-plugins/sofa-tracer-dubbo-plugin/src/test/java/com/alipay/sofa/tracer/plugins/dubbo/impl/DubboServiceImpl.java new file mode 100644 index 00000000..933ba2e4 --- /dev/null +++ b/sofa-tracer-plugins/sofa-tracer-dubbo-plugin/src/test/java/com/alipay/sofa/tracer/plugins/dubbo/impl/DubboServiceImpl.java @@ -0,0 +1,30 @@ +/* + * 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 com.alipay.sofa.tracer.plugins.dubbo.impl; + +import com.alipay.sofa.tracer.plugins.dubbo.service.DubboService; + +/** + * @author: guolei.sgl (guolei.sgl@antfin.com) 2019/2/27 8:39 PM + * @since: + **/ +public class DubboServiceImpl implements DubboService { + @Override + public String echoStr(String name) { + return name; + } +} diff --git a/sofa-tracer-plugins/sofa-tracer-dubbo-plugin/src/test/java/com/alipay/sofa/tracer/plugins/dubbo/service/DubboService.java b/sofa-tracer-plugins/sofa-tracer-dubbo-plugin/src/test/java/com/alipay/sofa/tracer/plugins/dubbo/service/DubboService.java new file mode 100644 index 00000000..499cb32c --- /dev/null +++ b/sofa-tracer-plugins/sofa-tracer-dubbo-plugin/src/test/java/com/alipay/sofa/tracer/plugins/dubbo/service/DubboService.java @@ -0,0 +1,26 @@ +/* + * 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 com.alipay.sofa.tracer.plugins.dubbo.service; + +/** + * @author: guolei.sgl (guolei.sgl@antfin.com) 2019/2/27 8:38 PM + * @since: + **/ +public interface DubboService { + + String echoStr(String name); +} diff --git a/tracer-core/src/main/java/com/alipay/common/tracer/core/span/CommonSpanTags.java b/tracer-core/src/main/java/com/alipay/common/tracer/core/span/CommonSpanTags.java index 6b6c483c..8151dd6d 100644 --- a/tracer-core/src/main/java/com/alipay/common/tracer/core/span/CommonSpanTags.java +++ b/tracer-core/src/main/java/com/alipay/common/tracer/core/span/CommonSpanTags.java @@ -17,52 +17,109 @@ package com.alipay.common.tracer.core.span; /** - * 一些通用的 SpanTags + * some common SpanTags * @author luoguimu123 - * @version $Id: CommonSpanTags.java, v 0.1 2018年01月29日 下午12:10 luoguimu123 Exp $ + * @author guolei.sgl + * @version : v 0.1 */ public class CommonSpanTags { - //************** String 类型 ************** - /*** - * 当前应用名称,注意和 RPC 保持一致 com.alipay.sofa.rpc.tracer.log.tags.RpcSpanTags#LOCAL_APP + /** + * LOCAL_APP records the currnt app name + */ + public static final String LOCAL_APP = "local.app"; + + /** + * REMOTE_APP records the target app name + */ + public static final String REMOTE_APP = "remote.app"; + + /** + * CURRENT_THREAD_NAME records handler result + */ + public static final String RESULT_CODE = "result.code"; + + /** + * CURRENT_THREAD_NAME records current thread name + */ + public static final String CURRENT_THREAD_NAME = "current.thread.name"; + + /** + * REQUEST_URL records the url of the incoming request. + */ + public static final String REQUEST_URL = "request.url"; + + /** + * METHOD records the request method name,(rpc method or http method). + */ + public static final String METHOD = "method"; + + /** + * REQ_SIZE records the request body size. + */ + public static final String REQ_SIZE = "req.size.bytes"; + + /** + * RESP_SIZE records the response body size. + */ + public static final String RESP_SIZE = "resp.size.bytes"; + + /** + * PROTOCOL records the request protocol type. + */ + public static final String PROTOCOL = "protocol"; + + /** + * SERVICE records the rpc service interface. + */ + public static final String SERVICE = "service"; + + /** + * REMOTE_HOST records the rpc target host. + */ + public static final String REMOTE_HOST = "remote.host"; + /** + * REMOTE_PORT records the rpc target port. */ - public static final String LOCAL_APP = "local.app"; + public static final String REMOTE_PORT = "remote.port"; /** - * opposite end appName such as source or target appName + * LOCAL_HOST records the local host. */ - public static final String REMOTE_APP = "remote.app"; + public static final String LOCAL_HOST = "local.host"; /** - * 结果码, 具体含义根据实际每个中间件的约定不同而不同 + * LOCAL_PORT records the local port. */ - public static final String RESULT_CODE = "result.code"; + public static final String LOCAL_PORT = "local.port"; - /*** - * 当前线程名字 + /** + * INVOKE_TYPE records the invoke type(oneway/sync/async). */ - public static final String CURRENT_THREAD_NAME = "current.thread.name"; + public static final String INVOKE_TYPE = "invoke.type"; - /*** - * 请求 url + /** + * RPC_TRACE_NAME constants key for dubbo rpc transfer. */ - public static final String REQUEST_URL = "request.url"; + public static final String RPC_TRACE_NAME = "dubbo.rpc.sofa.tracer"; - /*** - * 方法名称 + /** + * CLIENT_SERIALIZE_TIME records the rpc client serializes the request body time */ - public static final String METHOD = "method"; + public static final String CLIENT_SERIALIZE_TIME = "client.serialize.time"; - //************** Number 类型 ************** + /** + * SERVER_SERIALIZE_TIME records the rpc server serializes the response body time + */ + public static final String SERVER_SERIALIZE_TIME = "server.serialize.time"; - /*** - * 请求大小 + /** + * CLIENT_DESERIALIZE_TIME records the rpc client deserialize the response body time */ - public static final String REQ_SIZE = "req.size.bytes"; + public static final String CLIENT_DESERIALIZE_TIME = "client.deserialize.time"; - /*** - * 响应大小 + /** + * SERVER_DESERIALIZE_TIME records the rpc server deserialize the request body time */ - public static final String RESP_SIZE = "resp.size.bytes"; + public static final String SERVER_DESERIALIZE_TIME = "server.deserialize.time"; } \ No newline at end of file diff --git a/tracer-samples/pom.xml b/tracer-samples/pom.xml index 3fa8f154..1706061a 100644 --- a/tracer-samples/pom.xml +++ b/tracer-samples/pom.xml @@ -21,6 +21,7 @@ tracer-sample-with-h2 tracer-sample-with-resttemplate tracer-sample-with-sampler + tracer-sample-with-dubbo diff --git a/tracer-samples/tracer-sample-with-dubbo/README.md b/tracer-samples/tracer-sample-with-dubbo/README.md new file mode 100644 index 00000000..e8c164bb --- /dev/null +++ b/tracer-samples/tracer-sample-with-dubbo/README.md @@ -0,0 +1,142 @@ +## 使用 SOFATracer 集成 Dubbo 埋点 + +本案例使用的各框架组件的版本如下: + +* SOFABoot 3.1.1/SpringBoot 2.1.0.RELEASE +* SOFATracer 2.4.0/3.0.4 +* JDK 8 + +本案例包括三个子模块: + +* tracer-sample-with-dubbo-consumer 服务调用方 +* tracer-sample-with-dubbo-provider 服务提供方 +* tracer-sample-with-dubbo-facade 接口 + +## 新建 SOFABoot 工程作为父工程 + +在创建好一个 Spring Boot 的工程之后,接下来就需要引入 SOFABoot 的依赖,首先,需要将上文中生成的 Spring Boot 工程的 `zip` 包解压后,修改 Maven 项目的配置文件 `pom.xml`,将 + +```xml + + org.springframework.boot + spring-boot-starter-parent + ${spring.boot.version} + + +``` + +替换为: + +```xml + + com.alipay.sofa + sofaboot-dependencies + ${sofa.boot.version} + +``` +这里的 ${sofa.boot.version} 指定具体的 SOFABoot 版本,参考[发布历史](https://github.com/alipay/sofa-build/releases)。 + +## 新建 tracer-sample-with-dubbo-facade + +提供一个接口 + +```java +public interface HelloService { + String SayHello(String name); +} +``` +## 新建 tracer-sample-with-dubbo-provider + +* 在工程模块的 pom 文件中添加 SOFATracer 依赖 + + ```xml + + com.alipay.sofa + tracer-sofa-boot-starter + + ``` + > SOFATracer 版本受 SOFABoot 版本管控,如果使用的 SOFABoot 版本不匹配,则需要手动指定 tracer 版本,且版本需高于 2.4.0. + +* 在工程的 `application.properties` 文件下添加相关参数 + + ```properties + # Spring boot application + spring.application.name=dubbo-provider + # Base packages to scan Dubbo Component: @org.apache.dubbo.config.annotation.Service + dubbo.scan.base-packages=com.alipay.sofa.tracer.examples.dubbo.impl + ## Filter + dubbo.provider.filter=dubboSofaTracerFilter + # Dubbo Protocol + dubbo.protocol.name=dubbo + ## Dubbo Registry + dubbo.registry.address=zookeeper://localhost:2181 + logging.path=./logs + ``` +* 使用注解方式发布 Dubbo 服务 + + ```java + @Service + public class HelloServiceImpl implements HelloService { + @Override + public String SayHello(String name) { + return "Hello , "+name; + } + } + ``` + +## 新建 tracer-sample-with-dubbo-consumer + +* 在工程模块的 pom 文件中添加 SOFATracer 依赖 + + ```xml + + com.alipay.sofa + tracer-sofa-boot-starter + + ``` + +* 在工程的 `application.properties` 文件下添加相关参数 + + ```properties + spring.application.name=dubbo-consumer + dubbo.registry.address=zookeeper://localhost:2181 + dubbo.consumer.filter=dubboSofaTracerFilter + logging.path=./logs + ``` +* 服务引用 + + ```java + @Reference(async = false) + public HelloService helloService; + + @Bean + public ApplicationRunner runner() { + return args -> { + logger.info(helloService.SayHello("sofa")); + }; + } + ``` + +## 测试 + +先后启动 tracer-sample-with-dubbo-provider 和 tracer-sample-with-dubbo-consumer 两个工程; 然后查看日志: + +* dubbo-client-digest.log +```json +{"time":"2019-04-03 11:36:01.909","traceId":"0a0fe8451554262561656100126684","spanId":"0","span.kind":"client","local.app":"dubbo-consumer","protocol":"dubbo","service":"com.alipay.sofa.tracer.examples.dubbo.facade.HelloService","method":"SayHello","invoke.type":"sync","remote.host":"10.15.232.69","remote.port":"20880","local.host":"10.15.232.69","client.serialize.time":35,"client.deserialize.time":0,"req.size.bytes":323,"resp.size.bytes":323,"result.code":"00","current.thread.name":"main","time.cost.milliseconds":252,"baggage":""} +``` + +* dubbo-server-digest.log +```json +{"time":"2019-04-03 11:36:01.880","traceId":"0a0fe8451554262561656100126684","spanId":"0","span.kind":"server","local.app":"dubbo-provider","service":"com.alipay.sofa.tracer.examples.dubbo.facade.HelloService","method":"SayHello","local.host":"10.15.232.69","local.port":"54178","protocol":"dubbo","server.serialize.time":0,"server.deserialize.time":27,"result.code":"00","current.thread.name":"DubboServerHandler-10.15.232.69:20880-thread-2","time.cost.milliseconds":3,"baggage":""} +``` + +* dubbo-client-stat.log +```json +{"time":"2019-04-03 11:37:01.650","stat.key":{"method":"SayHello","local.app":"dubbo-consumer","service":"com.alipay.sofa.tracer.examples.dubbo.facade.HelloService"},"count":1,"total.cost.milliseconds":252,"success":"Y"} +``` + +* dubbo-server-stat.log +```json +{"time":"2019-04-03 11:37:01.872","stat.key":{"method":"SayHello","remote.app":"dubbo-provider","service":"com.alipay.sofa.tracer.examples.dubbo.facade.HelloService"},"count":1,"total.cost.milliseconds":3,"success":"Y"} +``` \ No newline at end of file diff --git a/tracer-samples/tracer-sample-with-dubbo/pom.xml b/tracer-samples/tracer-sample-with-dubbo/pom.xml new file mode 100644 index 00000000..8d547655 --- /dev/null +++ b/tracer-samples/tracer-sample-with-dubbo/pom.xml @@ -0,0 +1,23 @@ + + + + tracer-all-parent + com.alipay.sofa + 2.4.0 + ../../pom.xml + + 4.0.0 + + tracer-sample-with-dubbo + pom + + tracer-sample-with-dubbo-facade + tracer-sample-with-dubbo-consumer + tracer-sample-with-dubbo-provider + + + ${project.basedir}/../.. + + \ No newline at end of file diff --git a/tracer-samples/tracer-sample-with-dubbo/tracer-sample-with-dubbo-consumer/pom.xml b/tracer-samples/tracer-sample-with-dubbo/tracer-sample-with-dubbo-consumer/pom.xml new file mode 100644 index 00000000..1ffb5fcc --- /dev/null +++ b/tracer-samples/tracer-sample-with-dubbo/tracer-sample-with-dubbo-consumer/pom.xml @@ -0,0 +1,76 @@ + + + + tracer-sample-with-dubbo + com.alipay.sofa + 2.4.0 + + 4.0.0 + + + ${project.basedir}/../../.. + + + tracer-sample-with-dubbo-consumer + + + org.springframework.boot + spring-boot-starter + + + log4j-over-slf4j + org.slf4j + + + + + + org.apache.dubbo + dubbo-spring-boot-starter + 2.7.0 + + + + org.apache.dubbo + dubbo + 2.7.0 + + + + com.alipay.sofa + tracer-sample-with-dubbo-facade + 2.4.0 + + + + org.apache.curator + curator-framework + 2.9.1 + + + + org.apache.curator + curator-recipes + 2.9.1 + + + + org.apache.zookeeper + zookeeper + 3.4.13 + + + + com.alipay.sofa + sofa-tracer-dubbo-plugin + + + + org.springframework.boot + spring-boot-starter-web + + + + \ No newline at end of file diff --git a/tracer-samples/tracer-sample-with-dubbo/tracer-sample-with-dubbo-consumer/src/main/java/com/alipay/sofa/tracer/examples/dubbo/DubboConsumerApplication.java b/tracer-samples/tracer-sample-with-dubbo/tracer-sample-with-dubbo-consumer/src/main/java/com/alipay/sofa/tracer/examples/dubbo/DubboConsumerApplication.java new file mode 100644 index 00000000..b6ada910 --- /dev/null +++ b/tracer-samples/tracer-sample-with-dubbo/tracer-sample-with-dubbo-consumer/src/main/java/com/alipay/sofa/tracer/examples/dubbo/DubboConsumerApplication.java @@ -0,0 +1,50 @@ +/* + * 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 com.alipay.sofa.tracer.examples.dubbo; + +import com.alipay.sofa.tracer.examples.dubbo.facade.HelloService; +import org.apache.dubbo.config.annotation.Reference; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.boot.ApplicationRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; + +/** + * @author: guolei.sgl (glmapper_2018@163.com) 2019/2/26 2:16 PM + * @since: + **/ +@SpringBootApplication +public class DubboConsumerApplication { + + private final Logger logger = LoggerFactory.getLogger(getClass()); + + @Reference(async = false) + public HelloService helloService; + + public static void main(String[] args) { + SpringApplication.run(DubboConsumerApplication.class); + } + + @Bean + public ApplicationRunner runner() { + return args -> { + logger.info(helloService.SayHello("sofa")); + }; + } +} diff --git a/tracer-samples/tracer-sample-with-dubbo/tracer-sample-with-dubbo-consumer/src/main/resources/application.properties b/tracer-samples/tracer-sample-with-dubbo/tracer-sample-with-dubbo-consumer/src/main/resources/application.properties new file mode 100644 index 00000000..e192b967 --- /dev/null +++ b/tracer-samples/tracer-sample-with-dubbo/tracer-sample-with-dubbo-consumer/src/main/resources/application.properties @@ -0,0 +1,4 @@ +spring.application.name=dubbo-consumer +dubbo.registry.address=zookeeper://localhost:2181 +dubbo.consumer.filter=dubboSofaTracerFilter +logging.path=./logs \ No newline at end of file diff --git a/tracer-samples/tracer-sample-with-dubbo/tracer-sample-with-dubbo-facade/pom.xml b/tracer-samples/tracer-sample-with-dubbo/tracer-sample-with-dubbo-facade/pom.xml new file mode 100644 index 00000000..e92e4771 --- /dev/null +++ b/tracer-samples/tracer-sample-with-dubbo/tracer-sample-with-dubbo-facade/pom.xml @@ -0,0 +1,17 @@ + + + + tracer-sample-with-dubbo + com.alipay.sofa + 2.4.0 + + 4.0.0 + + tracer-sample-with-dubbo-facade + + ${project.basedir}/../../.. + + + \ No newline at end of file diff --git a/tracer-samples/tracer-sample-with-dubbo/tracer-sample-with-dubbo-facade/src/main/java/com/alipay/sofa/tracer/examples/dubbo/facade/HelloService.java b/tracer-samples/tracer-sample-with-dubbo/tracer-sample-with-dubbo-facade/src/main/java/com/alipay/sofa/tracer/examples/dubbo/facade/HelloService.java new file mode 100644 index 00000000..62899ea3 --- /dev/null +++ b/tracer-samples/tracer-sample-with-dubbo/tracer-sample-with-dubbo-facade/src/main/java/com/alipay/sofa/tracer/examples/dubbo/facade/HelloService.java @@ -0,0 +1,25 @@ +/* + * 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 com.alipay.sofa.tracer.examples.dubbo.facade; + +/** + * @author: guolei.sgl (guolei.sgl@antfin.com) 2019/4/4 10:12 AM + * @since: + **/ +public interface HelloService { + String SayHello(String name); +} diff --git a/tracer-samples/tracer-sample-with-dubbo/tracer-sample-with-dubbo-provider/pom.xml b/tracer-samples/tracer-sample-with-dubbo/tracer-sample-with-dubbo-provider/pom.xml new file mode 100644 index 00000000..531854c9 --- /dev/null +++ b/tracer-samples/tracer-sample-with-dubbo/tracer-sample-with-dubbo-provider/pom.xml @@ -0,0 +1,69 @@ + + + + tracer-sample-with-dubbo + com.alipay.sofa + 2.4.0 + + 4.0.0 + + tracer-sample-with-dubbo-provider + + ${project.basedir}/../../.. + + + + + + org.springframework.boot + spring-boot-starter + + + + + org.apache.dubbo + dubbo-spring-boot-starter + 2.7.0 + + + + org.apache.dubbo + dubbo + 2.7.0 + + + + com.alipay.sofa + tracer-sample-with-dubbo-facade + 2.4.0 + + + + com.alipay.sofa + sofa-tracer-dubbo-plugin + + + + + org.apache.zookeeper + zookeeper + 3.4.13 + + + + org.apache.curator + curator-framework + 2.9.1 + + + + org.apache.curator + curator-recipes + 2.9.1 + + + + + \ No newline at end of file diff --git a/tracer-samples/tracer-sample-with-dubbo/tracer-sample-with-dubbo-provider/src/main/java/com/alipay/sofa/tracer/examples/dubbo/DubboRegistryZooKeeperProviderBootstrap.java b/tracer-samples/tracer-sample-with-dubbo/tracer-sample-with-dubbo-provider/src/main/java/com/alipay/sofa/tracer/examples/dubbo/DubboRegistryZooKeeperProviderBootstrap.java new file mode 100644 index 00000000..1ce6584e --- /dev/null +++ b/tracer-samples/tracer-sample-with-dubbo/tracer-sample-with-dubbo-provider/src/main/java/com/alipay/sofa/tracer/examples/dubbo/DubboRegistryZooKeeperProviderBootstrap.java @@ -0,0 +1,39 @@ +/* + * 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 com.alipay.sofa.tracer.examples.dubbo; + +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent; +import org.springframework.context.ApplicationListener; + +/** + * Dubbo Registry ZooKeeper Provider Bootstrap + * + * @since 2.7.0 + */ +@EnableAutoConfiguration +public class DubboRegistryZooKeeperProviderBootstrap { + + public static void main(String[] args) { + new SpringApplicationBuilder(DubboRegistryZooKeeperProviderBootstrap.class) + .listeners((ApplicationListener) event -> { + new EmbeddedZooKeeper(2181, false).start(); + }) + .run(args); + } +} diff --git a/tracer-samples/tracer-sample-with-dubbo/tracer-sample-with-dubbo-provider/src/main/java/com/alipay/sofa/tracer/examples/dubbo/EmbeddedZooKeeper.java b/tracer-samples/tracer-sample-with-dubbo/tracer-sample-with-dubbo-provider/src/main/java/com/alipay/sofa/tracer/examples/dubbo/EmbeddedZooKeeper.java new file mode 100644 index 00000000..2d43a637 --- /dev/null +++ b/tracer-samples/tracer-sample-with-dubbo/tracer-sample-with-dubbo-provider/src/main/java/com/alipay/sofa/tracer/examples/dubbo/EmbeddedZooKeeper.java @@ -0,0 +1,252 @@ +/* + * 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 com.alipay.sofa.tracer.examples.dubbo; + +import org.apache.zookeeper.server.ServerConfig; +import org.apache.zookeeper.server.ZooKeeperServerMain; +import org.apache.zookeeper.server.quorum.QuorumPeerConfig; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.SmartLifecycle; +import org.springframework.util.ErrorHandler; +import org.springframework.util.SocketUtils; + +import java.io.File; +import java.lang.reflect.Method; +import java.util.Properties; +import java.util.UUID; + +/** + * from: https://github.com/spring-projects/spring-xd/blob/v1.3.1.RELEASE/spring-xd-dirt/src/main/java/org/springframework/xd/dirt/zookeeper/ZooKeeperUtils.java + *

+ * Helper class to start an embedded instance of standalone (non clustered) ZooKeeper. + *

+ * NOTE: at least an external standalone server (if not an ensemble) are recommended, even for + * org.springframework.xd.dirt.server.singlenode.SingleNodeApplication + * + * @author Patrick Peralta + * @author Mark Fisher + * @author David Turanski + */ +public class EmbeddedZooKeeper implements SmartLifecycle { + + /** + * Logger. + */ + private static final Logger logger = LoggerFactory + .getLogger(EmbeddedZooKeeper.class); + + /** + * ZooKeeper client port. This will be determined dynamically upon startup. + */ + private final int clientPort; + + /** + * Whether to auto-start. Default is true. + */ + private boolean autoStartup = true; + + /** + * Lifecycle phase. Default is 0. + */ + private int phase = 0; + + /** + * Thread for running the ZooKeeper server. + */ + private volatile Thread zkServerThread; + + /** + * ZooKeeper server. + */ + private volatile ZooKeeperServerMain zkServer; + + /** + * {@link ErrorHandler} to be invoked if an Exception is thrown from the ZooKeeper server thread. + */ + private ErrorHandler errorHandler; + + private boolean daemon = true; + + /** + * Construct an EmbeddedZooKeeper with a random port. + */ + public EmbeddedZooKeeper() { + clientPort = SocketUtils.findAvailableTcpPort(); + } + + /** + * Construct an EmbeddedZooKeeper with the provided port. + * + * @param clientPort port for ZooKeeper server to bind to + */ + public EmbeddedZooKeeper(int clientPort, boolean daemon) { + this.clientPort = clientPort; + this.daemon = daemon; + } + + /** + * Returns the port that clients should use to connect to this embedded server. + * + * @return dynamically determined client port + */ + public int getClientPort() { + return this.clientPort; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean isAutoStartup() { + return this.autoStartup; + } + + /** + * Specify whether to start automatically. Default is true. + * + * @param autoStartup whether to start automatically + */ + public void setAutoStartup(boolean autoStartup) { + this.autoStartup = autoStartup; + } + + /** + * {@inheritDoc} + */ + @Override + public int getPhase() { + return this.phase; + } + + /** + * Specify the lifecycle phase for the embedded server. + * + * @param phase the lifecycle phase + */ + public void setPhase(int phase) { + this.phase = phase; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean isRunning() { + return (zkServerThread != null); + } + + /** + * Start the ZooKeeper server in a background thread. + *

+ * Register an error handler via {@link #setErrorHandler} in order to handle + * any exceptions thrown during startup or execution. + */ + @Override + public synchronized void start() { + if (zkServerThread == null) { + zkServerThread = new Thread(new ServerRunnable(), "ZooKeeper Server Starter"); + zkServerThread.setDaemon(daemon); + zkServerThread.start(); + } + } + + /** + * Shutdown the ZooKeeper server. + */ + @Override + public synchronized void stop() { + if (zkServerThread != null) { + // The shutdown method is protected...thus this hack to invoke it. + // This will log an exception on shutdown; see + // https://issues.apache.org/jira/browse/ZOOKEEPER-1873 for details. + try { + Method shutdown = ZooKeeperServerMain.class.getDeclaredMethod("shutdown"); + shutdown.setAccessible(true); + shutdown.invoke(zkServer); + } catch (Exception e) { + throw new RuntimeException(e); + } + + // It is expected that the thread will exit after + // the server is shutdown; this will block until + // the shutdown is complete. + try { + zkServerThread.join(5000); + zkServerThread = null; + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + logger.warn("Interrupted while waiting for embedded ZooKeeper to exit"); + // abandoning zk thread + zkServerThread = null; + } + } + } + + /** + * Stop the server if running and invoke the callback when complete. + */ + @Override + public void stop(Runnable callback) { + stop(); + callback.run(); + } + + /** + * Provide an {@link ErrorHandler} to be invoked if an Exception is thrown from the ZooKeeper server thread. If none + * is provided, only error-level logging will occur. + * + * @param errorHandler the {@link ErrorHandler} to be invoked + */ + public void setErrorHandler(ErrorHandler errorHandler) { + this.errorHandler = errorHandler; + } + + /** + * Runnable implementation that starts the ZooKeeper server. + */ + private class ServerRunnable implements Runnable { + + @Override + public void run() { + try { + Properties properties = new Properties(); + File file = new File(System.getProperty("java.io.tmpdir") + File.separator + + UUID.randomUUID()); + file.deleteOnExit(); + properties.setProperty("dataDir", file.getAbsolutePath()); + properties.setProperty("clientPort", String.valueOf(clientPort)); + + QuorumPeerConfig quorumPeerConfig = new QuorumPeerConfig(); + quorumPeerConfig.parseProperties(properties); + + zkServer = new ZooKeeperServerMain(); + ServerConfig configuration = new ServerConfig(); + configuration.readFrom(quorumPeerConfig); + + zkServer.runFromConfig(configuration); + } catch (Exception e) { + if (errorHandler != null) { + errorHandler.handleError(e); + } else { + logger.error("Exception running embedded ZooKeeper", e); + } + } + } + } + +} diff --git a/tracer-samples/tracer-sample-with-dubbo/tracer-sample-with-dubbo-provider/src/main/java/com/alipay/sofa/tracer/examples/dubbo/impl/HelloServiceImpl.java b/tracer-samples/tracer-sample-with-dubbo/tracer-sample-with-dubbo-provider/src/main/java/com/alipay/sofa/tracer/examples/dubbo/impl/HelloServiceImpl.java new file mode 100644 index 00000000..3782bd6c --- /dev/null +++ b/tracer-samples/tracer-sample-with-dubbo/tracer-sample-with-dubbo-provider/src/main/java/com/alipay/sofa/tracer/examples/dubbo/impl/HelloServiceImpl.java @@ -0,0 +1,32 @@ +/* + * 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 com.alipay.sofa.tracer.examples.dubbo.impl; + +import com.alipay.sofa.tracer.examples.dubbo.facade.HelloService; +import org.apache.dubbo.config.annotation.Service; + +/** + * @author: guolei.sgl (glmapper_2018@163.com) 2019/2/26 2:10 PM + * @since: + **/ +@Service +public class HelloServiceImpl implements HelloService { + @Override + public String SayHello(String name) { + return "Hello , " + name; + } +} diff --git a/tracer-samples/tracer-sample-with-dubbo/tracer-sample-with-dubbo-provider/src/main/resources/application.properties b/tracer-samples/tracer-sample-with-dubbo/tracer-sample-with-dubbo-provider/src/main/resources/application.properties new file mode 100644 index 00000000..8f2df850 --- /dev/null +++ b/tracer-samples/tracer-sample-with-dubbo/tracer-sample-with-dubbo-provider/src/main/resources/application.properties @@ -0,0 +1,11 @@ +# Spring boot application +spring.application.name=dubbo-provider +# Base packages to scan Dubbo Component: @org.apache.dubbo.config.annotation.Service +dubbo.scan.base-packages=com.alipay.sofa.tracer.examples.dubbo.impl +## Dubbo Registry +dubbo.provider.filter=dubboSofaTracerFilter +# Dubbo Protocol +dubbo.protocol.name=dubbo +## Dubbo Registry +dubbo.registry.address=zookeeper://localhost:2181 +logging.path=./logs diff --git a/tracer-samples/tracer-sample-with-sofarpc/pom.xml b/tracer-samples/tracer-sample-with-sofarpc/pom.xml index 5d262026..f53b1134 100644 --- a/tracer-samples/tracer-sample-with-sofarpc/pom.xml +++ b/tracer-samples/tracer-sample-with-sofarpc/pom.xml @@ -24,6 +24,17 @@ com.alipay.sofa rpc-sofa-boot-starter + + + dubbo + com.alibaba + + + + + com.alibaba + dubbo + 2.6.0 com.alipay.sofa diff --git a/tracer-sofa-boot-starter/pom.xml b/tracer-sofa-boot-starter/pom.xml index 8454acee..26167d81 100644 --- a/tracer-sofa-boot-starter/pom.xml +++ b/tracer-sofa-boot-starter/pom.xml @@ -53,6 +53,12 @@ com.alipay.sofa sofa-tracer-zipkin-plugin + + + com.alipay.sofa + sofa-tracer-dubbo-plugin + + org.springframework.boot spring-boot diff --git a/tracer-sofa-boot-starter/src/test/java/com/alipay/sofa/tracer/boot/springmvc/SpringMvcFilterJsonOutputTest.java b/tracer-sofa-boot-starter/src/test/java/com/alipay/sofa/tracer/boot/springmvc/SpringMvcFilterJsonOutputTest.java index 2ebac8dc..a5585233 100644 --- a/tracer-sofa-boot-starter/src/test/java/com/alipay/sofa/tracer/boot/springmvc/SpringMvcFilterJsonOutputTest.java +++ b/tracer-sofa-boot-starter/src/test/java/com/alipay/sofa/tracer/boot/springmvc/SpringMvcFilterJsonOutputTest.java @@ -80,8 +80,9 @@ public void testSofaRestGet() throws Exception { } SofaTracerStatisticReporterManager s = SofaTracerStatisticReporterCycleTimesManager .getSofaTracerStatisticReporterManager(1L); - Assert.notNull(s.getStatReporters().get( - SpringMvcLogEnum.SPRING_MVC_STAT.getDefaultLogName())); + Assert.notNull( + s.getStatReporters().get(SpringMvcLogEnum.SPRING_MVC_STAT.getDefaultLogName()), + "mvc reporter cannot be null"); //stat log : 设置了周期 1s 输出一次 Thread.sleep(2000);