From 11ad02921787617916bdda97845588fc1553e985 Mon Sep 17 00:00:00 2001 From: Ray Date: Fri, 9 Dec 2016 16:34:16 +0800 Subject: [PATCH 1/4] support opentracing & demo --- .../filter-opentracing/pom.xml | 75 ++++++++ .../opentracing/OpenTracingContext.java | 53 ++++++ .../filter/opentracing/OpenTracingFilter.java | 160 ++++++++++++++++++ .../filter/opentracing/TracerFactory.java | 43 +++++ .../com.weibo.api.motan.filter.Filter | 17 ++ .../filter/opentracing/HelloService.java | 20 +++ .../filter/opentracing/HelloServiceImpl.java | 25 +++ .../opentracing/OpenTracingFilterTest.java | 159 +++++++++++++++++ .../opentracing/zipkin/demo/HelloClient.java | 42 +++++ .../opentracing/zipkin/demo/HelloServer.java | 29 ++++ .../zipkin/demo/MyTracerFactory.java | 33 ++++ .../src/test/resources/motan_client.xml | 25 +++ .../src/test/resources/motan_server.xml | 33 ++++ motan-extension/filter-extension/pom.xml | 26 +++ motan-extension/pom.xml | 8 + 15 files changed, 748 insertions(+) create mode 100644 motan-extension/filter-extension/filter-opentracing/pom.xml create mode 100644 motan-extension/filter-extension/filter-opentracing/src/main/java/com/weibo/api/motan/filter/opentracing/OpenTracingContext.java create mode 100644 motan-extension/filter-extension/filter-opentracing/src/main/java/com/weibo/api/motan/filter/opentracing/OpenTracingFilter.java create mode 100644 motan-extension/filter-extension/filter-opentracing/src/main/java/com/weibo/api/motan/filter/opentracing/TracerFactory.java create mode 100644 motan-extension/filter-extension/filter-opentracing/src/main/resources/META-INF/services/com.weibo.api.motan.filter.Filter create mode 100644 motan-extension/filter-extension/filter-opentracing/src/test/java/com/weibo/api/motan/filter/opentracing/HelloService.java create mode 100644 motan-extension/filter-extension/filter-opentracing/src/test/java/com/weibo/api/motan/filter/opentracing/HelloServiceImpl.java create mode 100644 motan-extension/filter-extension/filter-opentracing/src/test/java/com/weibo/api/motan/filter/opentracing/OpenTracingFilterTest.java create mode 100644 motan-extension/filter-extension/filter-opentracing/src/test/java/com/weibo/api/motan/filter/opentracing/zipkin/demo/HelloClient.java create mode 100644 motan-extension/filter-extension/filter-opentracing/src/test/java/com/weibo/api/motan/filter/opentracing/zipkin/demo/HelloServer.java create mode 100644 motan-extension/filter-extension/filter-opentracing/src/test/java/com/weibo/api/motan/filter/opentracing/zipkin/demo/MyTracerFactory.java create mode 100755 motan-extension/filter-extension/filter-opentracing/src/test/resources/motan_client.xml create mode 100755 motan-extension/filter-extension/filter-opentracing/src/test/resources/motan_server.xml create mode 100644 motan-extension/filter-extension/pom.xml diff --git a/motan-extension/filter-extension/filter-opentracing/pom.xml b/motan-extension/filter-extension/filter-opentracing/pom.xml new file mode 100644 index 000000000..d27b7efeb --- /dev/null +++ b/motan-extension/filter-extension/filter-opentracing/pom.xml @@ -0,0 +1,75 @@ + + + + 4.0.0 + + com.weibo + filter-extension + 0.2.3-SNAPSHOT + + filter-opentracing + filter-opentracing + https://github.com/weibocom/motan + + UTF-8 + + + + com.weibo + motan-core + ${project.version} + + + io.opentracing + opentracing-api + 0.20.2 + + + + + io.opentracing + opentracing-mock + 0.20.2 + test + + + io.opentracing.brave + brave-opentracing + 0.16.0 + test + + + io.zipkin.brave + brave-spancollector-http + 3.16.0 + test + + + com.weibo + motan-transport-netty + ${project.version} + test + + + com.weibo + motan-springsupport + ${project.version} + test + + + org.springframework + spring-context + 4.2.4.RELEASE + test + + + diff --git a/motan-extension/filter-extension/filter-opentracing/src/main/java/com/weibo/api/motan/filter/opentracing/OpenTracingContext.java b/motan-extension/filter-extension/filter-opentracing/src/main/java/com/weibo/api/motan/filter/opentracing/OpenTracingContext.java new file mode 100644 index 000000000..7276cef8a --- /dev/null +++ b/motan-extension/filter-extension/filter-opentracing/src/main/java/com/weibo/api/motan/filter/opentracing/OpenTracingContext.java @@ -0,0 +1,53 @@ +/* + * Copyright 2009-2016 Weibo, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ +package com.weibo.api.motan.filter.opentracing; + +import io.opentracing.Span; +import io.opentracing.Tracer; + +import com.weibo.api.motan.rpc.RpcContext; + +/** + * + * @Description OpenTracingContext hold a TracerFactory which can replaced by different tracer + * implementation. + * @author zhanglei + * @date Dec 8, 2016 + * + */ +public class OpenTracingContext { + // replace TracerFactory with any tracer implementation + public static TracerFactory tracerFactory = TracerFactory.DEFAULT; + public static final String ACTIVE_SPAN = "ot_active_span"; + + public static Tracer getTracer() { + return tracerFactory.getTracer(); + } + + public static Span getActiveSpan() { + Object span = RpcContext.getContext().getAttribute(ACTIVE_SPAN); + if (span != null && span instanceof Span) { + return (Span) span; + } + return null; + } + + public static void setActiveSpan(Span span) { + RpcContext.getContext().putAttribute(ACTIVE_SPAN, span); + } + + public void setTracerFactory(TracerFactory tracerFactory) { + OpenTracingContext.tracerFactory = tracerFactory; + } +} diff --git a/motan-extension/filter-extension/filter-opentracing/src/main/java/com/weibo/api/motan/filter/opentracing/OpenTracingFilter.java b/motan-extension/filter-extension/filter-opentracing/src/main/java/com/weibo/api/motan/filter/opentracing/OpenTracingFilter.java new file mode 100644 index 000000000..25a20e04f --- /dev/null +++ b/motan-extension/filter-extension/filter-opentracing/src/main/java/com/weibo/api/motan/filter/opentracing/OpenTracingFilter.java @@ -0,0 +1,160 @@ +/* + * Copyright 2009-2016 Weibo, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ +package com.weibo.api.motan.filter.opentracing; + +import io.opentracing.Span; +import io.opentracing.SpanContext; +import io.opentracing.Tracer; +import io.opentracing.Tracer.SpanBuilder; +import io.opentracing.propagation.Format; +import io.opentracing.propagation.TextMap; +import io.opentracing.propagation.TextMapExtractAdapter; + +import java.util.Iterator; +import java.util.Map.Entry; + +import com.weibo.api.motan.core.extension.Activation; +import com.weibo.api.motan.core.extension.SpiMeta; +import com.weibo.api.motan.filter.Filter; +import com.weibo.api.motan.rpc.Caller; +import com.weibo.api.motan.rpc.Provider; +import com.weibo.api.motan.rpc.Request; +import com.weibo.api.motan.rpc.Response; +import com.weibo.api.motan.util.LoggerUtil; +import com.weibo.api.motan.util.MotanFrameworkUtil; + +/** + * + * @Description This filter enables distributed tracing in Motan clients and servers via @see The OpenTracing Project : a set of consistent, + * expressive, vendor-neutral APIs for distributed tracing and context propagation. + * @author zhanglei + * @date Dec 8, 2016 + * + */ +@SpiMeta(name = "opentracing") +@Activation(sequence = 30) +public class OpenTracingFilter implements Filter { + + @Override + public Response filter(Caller caller, Request request) { + Tracer tracer = OpenTracingContext.getTracer(); + if (tracer == null) { + return caller.call(request); + } + if (caller instanceof Provider) { // server end + return processProviderTrace(tracer, caller, request); + } else { // client end + return processRefererTrace(tracer, caller, request); + } + } + + /** + * process trace in client end + * + * @param caller + * @param request + * @return + */ + protected Response processRefererTrace(Tracer tracer, Caller caller, Request request) { + String operationName = buildOperationName(request); + SpanBuilder spanBuilder = tracer.buildSpan(operationName); + Span activeSpan = OpenTracingContext.getActiveSpan(); + if (activeSpan != null) { + spanBuilder.asChildOf(activeSpan); + } + Span span = spanBuilder.start(); + span.setTag("requestId", request.getRequestId()); + + attachTraceInfo(tracer, span, request); + return process(caller, request, span); + + } + + protected Response process(Caller caller, Request request, Span span) { + Exception ex = null; + boolean exception = true; + try { + Response response = caller.call(request); + if (response.getException() != null) { + ex = response.getException(); + } else { + exception = false; + } + return response; + } catch (RuntimeException e) { + ex = e; + throw e; + } finally { + try { + if (exception) { + span.log("request fail." + (ex == null ? "unknown exception" : ex.getMessage())); + } else { + span.log("request success."); + } + span.finish(); + } catch (Exception e) { + LoggerUtil.error("opentracing span finish error!", e); + } + } + } + + protected String buildOperationName(Request request) { + return "Motan_" + MotanFrameworkUtil.getGroupMethodString(request); + } + + protected void attachTraceInfo(Tracer tracer, Span span, final Request request) { + tracer.inject(span.context(), Format.Builtin.TEXT_MAP, new TextMap() { + + @Override + public void put(String key, String value) { + request.setAttachment(key, value); + } + + @Override + public Iterator> iterator() { + throw new UnsupportedOperationException("TextMapInjectAdapter should only be used with Tracer.inject()"); + } + }); + } + + /** + * process trace in server end + * + * @param caller + * @param request + * @return + */ + protected Response processProviderTrace(Tracer tracer, Caller caller, Request request) { + Span span = extractTraceInfo(request, tracer); + span.setTag("requestId", request.getRequestId()); + OpenTracingContext.setActiveSpan(span); + return process(caller, request, span); + } + + protected Span extractTraceInfo(Request request, Tracer tracer) { + String operationName = buildOperationName(request); + SpanBuilder span = tracer.buildSpan(operationName); + try { + SpanContext spanContext = tracer.extract(Format.Builtin.TEXT_MAP, new TextMapExtractAdapter(request.getAttachments())); + if (spanContext != null) { + span.asChildOf(spanContext); + } + } catch (Exception e) { + span.withTag("Error", "extract from request fail, error msg:" + e.getMessage()); + } + return span.start(); + } + +} diff --git a/motan-extension/filter-extension/filter-opentracing/src/main/java/com/weibo/api/motan/filter/opentracing/TracerFactory.java b/motan-extension/filter-extension/filter-opentracing/src/main/java/com/weibo/api/motan/filter/opentracing/TracerFactory.java new file mode 100644 index 000000000..331bdb2f8 --- /dev/null +++ b/motan-extension/filter-extension/filter-opentracing/src/main/java/com/weibo/api/motan/filter/opentracing/TracerFactory.java @@ -0,0 +1,43 @@ +/* + * Copyright 2009-2016 Weibo, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.weibo.api.motan.filter.opentracing; + +import io.opentracing.Tracer; +/** + * + * @Description TracerFactory + * @author zhanglei + * @date Dec 8, 2016 + * + */ +public interface TracerFactory { + public static final TracerFactory DEFAULT = new DefaultTracerFactory(); + + /** + * get a Tracer implementation. + * this method may called every request, consider whether singleton pattern is needed + * @return + */ + Tracer getTracer(); + + class DefaultTracerFactory implements TracerFactory{ + @Override + public Tracer getTracer() { + return null; + } + + } +} diff --git a/motan-extension/filter-extension/filter-opentracing/src/main/resources/META-INF/services/com.weibo.api.motan.filter.Filter b/motan-extension/filter-extension/filter-opentracing/src/main/resources/META-INF/services/com.weibo.api.motan.filter.Filter new file mode 100644 index 000000000..0203ebedb --- /dev/null +++ b/motan-extension/filter-extension/filter-opentracing/src/main/resources/META-INF/services/com.weibo.api.motan.filter.Filter @@ -0,0 +1,17 @@ +# +# Copyright 2009-2016 Weibo, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +com.weibo.api.motan.filter.opentracing.OpenTracingFilter \ No newline at end of file diff --git a/motan-extension/filter-extension/filter-opentracing/src/test/java/com/weibo/api/motan/filter/opentracing/HelloService.java b/motan-extension/filter-extension/filter-opentracing/src/test/java/com/weibo/api/motan/filter/opentracing/HelloService.java new file mode 100644 index 000000000..784f3af7f --- /dev/null +++ b/motan-extension/filter-extension/filter-opentracing/src/test/java/com/weibo/api/motan/filter/opentracing/HelloService.java @@ -0,0 +1,20 @@ +/* + * Copyright 2009-2016 Weibo, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.weibo.api.motan.filter.opentracing; + +public interface HelloService { + String sayHello(String name); +} diff --git a/motan-extension/filter-extension/filter-opentracing/src/test/java/com/weibo/api/motan/filter/opentracing/HelloServiceImpl.java b/motan-extension/filter-extension/filter-opentracing/src/test/java/com/weibo/api/motan/filter/opentracing/HelloServiceImpl.java new file mode 100644 index 000000000..a3a2f939b --- /dev/null +++ b/motan-extension/filter-extension/filter-opentracing/src/test/java/com/weibo/api/motan/filter/opentracing/HelloServiceImpl.java @@ -0,0 +1,25 @@ +/* + * Copyright 2009-2016 Weibo, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.weibo.api.motan.filter.opentracing; + +public class HelloServiceImpl implements HelloService { + + @Override + public String sayHello(String name) { + return "hello," + name; + } + +} diff --git a/motan-extension/filter-extension/filter-opentracing/src/test/java/com/weibo/api/motan/filter/opentracing/OpenTracingFilterTest.java b/motan-extension/filter-extension/filter-opentracing/src/test/java/com/weibo/api/motan/filter/opentracing/OpenTracingFilterTest.java new file mode 100644 index 000000000..91b9ee410 --- /dev/null +++ b/motan-extension/filter-extension/filter-opentracing/src/test/java/com/weibo/api/motan/filter/opentracing/OpenTracingFilterTest.java @@ -0,0 +1,159 @@ +/* + * Copyright 2009-2016 Weibo, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ +package com.weibo.api.motan.filter.opentracing; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import io.opentracing.Tracer; +import io.opentracing.impl.BraveTracer; +import io.opentracing.mock.MockSpan; +import io.opentracing.mock.MockTracer; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.weibo.api.motan.common.URLParamType; +import com.weibo.api.motan.filter.Filter; +import com.weibo.api.motan.rpc.AbstractReferer; +import com.weibo.api.motan.rpc.DefaultProvider; +import com.weibo.api.motan.rpc.DefaultRequest; +import com.weibo.api.motan.rpc.DefaultResponse; +import com.weibo.api.motan.rpc.Provider; +import com.weibo.api.motan.rpc.Referer; +import com.weibo.api.motan.rpc.Request; +import com.weibo.api.motan.rpc.Response; +import com.weibo.api.motan.rpc.URL; + +/** + * + * @Description UT + * @author zhanglei + * @date Dec 9, 2016 + * + */ +public class OpenTracingFilterTest { + Filter OTFilter; + Tracer tracer; + Referer refer; + Provider provider; + DefaultRequest request; + DefaultResponse response; + + + @Before + public void setUp() throws Exception { + OTFilter = new OpenTracingFilter(); + tracer = new MockTracer(); + OpenTracingContext.tracerFactory = new TracerFactory() { + @Override + public Tracer getTracer() { + return tracer; + } + }; + URL url = new URL("motan", "localhost", 8002, "HelloService"); + request = new DefaultRequest(); + request.setInterfaceName("HelloService"); + request.setAttachment(URLParamType.group.name(), "test"); + request.setMethodName("sayHello"); + request.setParamtersDesc("java.lang.String"); + response = new DefaultResponse(); + refer = new AbstractReferer(HelloService.class, url) { + @Override + public void destroy() {} + + @Override + public boolean isAvailable() { + return true; + } + + @Override + protected Response doCall(Request request) { + return response; + } + + @Override + protected boolean doInit() { + return true; + } + }; + + provider = new DefaultProvider(new HelloServiceImpl(), url, HelloService.class) { + + @Override + public Response call(Request request) { + return response; + } + + }; + } + + @After + public void tearDown() throws Exception { + OpenTracingContext.tracerFactory = TracerFactory.DEFAULT; + } + + @Test + public void testRefererFilter() { + Response res = OTFilter.filter(refer, request); + assertEquals(response, res); + checkMockTracer(); + + tracer = new BraveTracer();// use bravetracer + res = OTFilter.filter(refer, request); + assertEquals(response, res); + checkBraveTrace(); + } + + @Test + public void testProviderFilter() { + Response res = OTFilter.filter(provider, request); + assertEquals(response, res); + checkMockTracer(); + } + + @Test + public void testException() { + response.setException(new RuntimeException("in test")); + Response res = OTFilter.filter(refer, request); + assertEquals(response, res); + if (tracer instanceof MockTracer) { + MockSpan span = ((MockTracer) tracer).finishedSpans().get(0); + assertEquals(span.logEntries().size(), 1); + assertTrue("request fail.in test".equals(span.logEntries().get(0).fields().get("event"))); + } + } + + private void checkMockTracer() { + if (tracer instanceof MockTracer) { + MockTracer mt = (MockTracer) tracer; + assertEquals(1, mt.finishedSpans().size()); + MockSpan span = mt.finishedSpans().get(0); + assertEquals(span.operationName(), "Motan_test_HelloService.sayHello(java.lang.String)"); + assertEquals(span.parentId(), 0); + assertEquals(span.logEntries().size(), 1); + assertTrue("request success.".equals(span.logEntries().get(0).fields().get("event"))); + assertTrue(span.tags().containsKey("requestId")); + } + } + + private void checkBraveTrace() { + if (tracer instanceof BraveTracer) { + assertTrue(request.getAttachments().containsKey("X-B3-TraceId")); + assertTrue(request.getAttachments().containsKey("X-B3-SpanId")); + assertTrue(request.getAttachments().containsKey("X-B3-Sampled")); + } + } + +} diff --git a/motan-extension/filter-extension/filter-opentracing/src/test/java/com/weibo/api/motan/filter/opentracing/zipkin/demo/HelloClient.java b/motan-extension/filter-extension/filter-opentracing/src/test/java/com/weibo/api/motan/filter/opentracing/zipkin/demo/HelloClient.java new file mode 100644 index 000000000..35cd0aab8 --- /dev/null +++ b/motan-extension/filter-extension/filter-opentracing/src/test/java/com/weibo/api/motan/filter/opentracing/zipkin/demo/HelloClient.java @@ -0,0 +1,42 @@ +/* + * Copyright 2009-2016 Weibo, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.weibo.api.motan.filter.opentracing.zipkin.demo; + +import org.springframework.context.ApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +import com.weibo.api.motan.filter.opentracing.HelloService; +import com.weibo.api.motan.filter.opentracing.OpenTracingContext; + +public class HelloClient { + public static void main(String[] args) { + ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:motan_client.xml"); + + // set tracer implementation + OpenTracingContext.tracerFactory = new MyTracerFactory(); + + // use motan + HelloService service = (HelloService) ctx.getBean("helloService"); + for(int i = 0; i< 10; i++){ + try{ + System.out.println(service.sayHello("motan")); + }catch(Exception e){ + e.printStackTrace(); + } + } + System.exit(0); + } +} diff --git a/motan-extension/filter-extension/filter-opentracing/src/test/java/com/weibo/api/motan/filter/opentracing/zipkin/demo/HelloServer.java b/motan-extension/filter-extension/filter-opentracing/src/test/java/com/weibo/api/motan/filter/opentracing/zipkin/demo/HelloServer.java new file mode 100644 index 000000000..287b735ff --- /dev/null +++ b/motan-extension/filter-extension/filter-opentracing/src/test/java/com/weibo/api/motan/filter/opentracing/zipkin/demo/HelloServer.java @@ -0,0 +1,29 @@ +/* + * Copyright 2009-2016 Weibo, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.weibo.api.motan.filter.opentracing.zipkin.demo; + +import org.springframework.context.ApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +public class HelloServer { + public static void main(String[] args) { + //set tracer implementation by spring config. see motan_server.xml + + ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:motan_server.xml"); + System.out.println("server start..."); + } + +} diff --git a/motan-extension/filter-extension/filter-opentracing/src/test/java/com/weibo/api/motan/filter/opentracing/zipkin/demo/MyTracerFactory.java b/motan-extension/filter-extension/filter-opentracing/src/test/java/com/weibo/api/motan/filter/opentracing/zipkin/demo/MyTracerFactory.java new file mode 100644 index 000000000..b1c3142ad --- /dev/null +++ b/motan-extension/filter-extension/filter-opentracing/src/test/java/com/weibo/api/motan/filter/opentracing/zipkin/demo/MyTracerFactory.java @@ -0,0 +1,33 @@ +/* + * Copyright 2009-2016 Weibo, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ +package com.weibo.api.motan.filter.opentracing.zipkin.demo; + +import io.opentracing.Tracer; +import io.opentracing.impl.BraveTracer; +import io.opentracing.mock.MockTracer; + +import com.weibo.api.motan.filter.opentracing.TracerFactory; + +public class MyTracerFactory implements TracerFactory { + // any tracer implementation + final Tracer mockTracer = new MockTracer(); + final Tracer braveTracer = new BraveTracer(); + + @Override + public Tracer getTracer() { +// return mockTracer; + return braveTracer; + } + +} diff --git a/motan-extension/filter-extension/filter-opentracing/src/test/resources/motan_client.xml b/motan-extension/filter-extension/filter-opentracing/src/test/resources/motan_client.xml new file mode 100755 index 000000000..1f71cfde7 --- /dev/null +++ b/motan-extension/filter-extension/filter-opentracing/src/test/resources/motan_client.xml @@ -0,0 +1,25 @@ + + + + + + + \ No newline at end of file diff --git a/motan-extension/filter-extension/filter-opentracing/src/test/resources/motan_server.xml b/motan-extension/filter-extension/filter-opentracing/src/test/resources/motan_server.xml new file mode 100755 index 000000000..3492d3f88 --- /dev/null +++ b/motan-extension/filter-extension/filter-opentracing/src/test/resources/motan_server.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + diff --git a/motan-extension/filter-extension/pom.xml b/motan-extension/filter-extension/pom.xml new file mode 100644 index 000000000..1ccceb060 --- /dev/null +++ b/motan-extension/filter-extension/pom.xml @@ -0,0 +1,26 @@ + + + + 4.0.0 + + com.weibo + motan-extension + 0.2.3-SNAPSHOT + + filter-extension + filter-extension + https://github.com/weibocom/motan + pom + + filter-opentracing + + diff --git a/motan-extension/pom.xml b/motan-extension/pom.xml index 85732f01c..60109833b 100644 --- a/motan-extension/pom.xml +++ b/motan-extension/pom.xml @@ -22,8 +22,16 @@ UTF-8 pom + + + com.weibo + motan-core + ${project.version} + + serialization-extension protocol-extension + filter-extension \ No newline at end of file From 630fab810808f27517c73afa303bce3235290502 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 21 Dec 2016 15:18:03 +0800 Subject: [PATCH 2/4] add default tracer load in DefaultTracerFactory --- .../filter/opentracing/TracerFactory.java | 42 ++++++++++++++++--- 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/motan-extension/filter-extension/filter-opentracing/src/main/java/com/weibo/api/motan/filter/opentracing/TracerFactory.java b/motan-extension/filter-extension/filter-opentracing/src/main/java/com/weibo/api/motan/filter/opentracing/TracerFactory.java index 331bdb2f8..5b7c47bdb 100644 --- a/motan-extension/filter-extension/filter-opentracing/src/main/java/com/weibo/api/motan/filter/opentracing/TracerFactory.java +++ b/motan-extension/filter-extension/filter-opentracing/src/main/java/com/weibo/api/motan/filter/opentracing/TracerFactory.java @@ -15,6 +15,11 @@ */ package com.weibo.api.motan.filter.opentracing; +import java.util.Iterator; +import java.util.ServiceLoader; + +import com.weibo.api.motan.util.LoggerUtil; + import io.opentracing.Tracer; /** * @@ -25,19 +30,44 @@ */ public interface TracerFactory { public static final TracerFactory DEFAULT = new DefaultTracerFactory(); - + /** - * get a Tracer implementation. - * this method may called every request, consider whether singleton pattern is needed + * get a Tracer implementation. this method may called every request, consider whether singleton + * pattern is needed + * * @return */ Tracer getTracer(); - class DefaultTracerFactory implements TracerFactory{ + class DefaultTracerFactory implements TracerFactory { + private static Tracer tracer = null; + + static { + loadDefaultTracer(); + } + + /** + * load SPI Tracer and set default. the first tracer was used if more than one tracer was + * found. + */ + private static void loadDefaultTracer() { + try { + Iterator implementations = ServiceLoader.load(Tracer.class, Tracer.class.getClassLoader()).iterator(); + if (implementations.hasNext()) { + tracer = implementations.next(); + LoggerUtil.info("io.opentracing.Tracer load in DefaultTracerFactory, " + tracer.getClass().getSimpleName() + + " is used as default tracer."); + } + } catch (Exception e) { + LoggerUtil.warn("DefaultTracerFactory load Tracer fail.", e); + } + } + + @Override public Tracer getTracer() { - return null; + return tracer; } - + } } From a179cc0e92dbbd5b6b48a5fc1925c5af28370d0a Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 21 Dec 2016 16:33:02 +0800 Subject: [PATCH 3/4] NoopTracer as default --- .../filter-opentracing/pom.xml | 10 +++++++-- .../filter/opentracing/OpenTracingFilter.java | 9 ++++++-- .../filter/opentracing/TracerFactory.java | 21 ++++++++++++------- 3 files changed, 29 insertions(+), 11 deletions(-) diff --git a/motan-extension/filter-extension/filter-opentracing/pom.xml b/motan-extension/filter-extension/filter-opentracing/pom.xml index d27b7efeb..1b5b102df 100644 --- a/motan-extension/filter-extension/filter-opentracing/pom.xml +++ b/motan-extension/filter-extension/filter-opentracing/pom.xml @@ -21,6 +21,7 @@ https://github.com/weibocom/motan UTF-8 + 0.20.2 @@ -31,14 +32,19 @@ io.opentracing opentracing-api - 0.20.2 + ${opentracing.version} + + + io.opentracing + opentracing-impl + ${opentracing.version} io.opentracing opentracing-mock - 0.20.2 + ${opentracing.version} test diff --git a/motan-extension/filter-extension/filter-opentracing/src/main/java/com/weibo/api/motan/filter/opentracing/OpenTracingFilter.java b/motan-extension/filter-extension/filter-opentracing/src/main/java/com/weibo/api/motan/filter/opentracing/OpenTracingFilter.java index 25a20e04f..b8c334479 100644 --- a/motan-extension/filter-extension/filter-opentracing/src/main/java/com/weibo/api/motan/filter/opentracing/OpenTracingFilter.java +++ b/motan-extension/filter-extension/filter-opentracing/src/main/java/com/weibo/api/motan/filter/opentracing/OpenTracingFilter.java @@ -13,6 +13,7 @@ */ package com.weibo.api.motan.filter.opentracing; +import io.opentracing.NoopTracer; import io.opentracing.Span; import io.opentracing.SpanContext; import io.opentracing.Tracer; @@ -49,8 +50,8 @@ public class OpenTracingFilter implements Filter { @Override public Response filter(Caller caller, Request request) { - Tracer tracer = OpenTracingContext.getTracer(); - if (tracer == null) { + Tracer tracer = getTracer(); + if (tracer == null || tracer instanceof NoopTracer) { return caller.call(request); } if (caller instanceof Provider) { // server end @@ -59,6 +60,10 @@ public Response filter(Caller caller, Request request) { return processRefererTrace(tracer, caller, request); } } + + protected Tracer getTracer(){ + return OpenTracingContext.getTracer(); + } /** * process trace in client end diff --git a/motan-extension/filter-extension/filter-opentracing/src/main/java/com/weibo/api/motan/filter/opentracing/TracerFactory.java b/motan-extension/filter-extension/filter-opentracing/src/main/java/com/weibo/api/motan/filter/opentracing/TracerFactory.java index 5b7c47bdb..d94654b27 100644 --- a/motan-extension/filter-extension/filter-opentracing/src/main/java/com/weibo/api/motan/filter/opentracing/TracerFactory.java +++ b/motan-extension/filter-extension/filter-opentracing/src/main/java/com/weibo/api/motan/filter/opentracing/TracerFactory.java @@ -15,12 +15,13 @@ */ package com.weibo.api.motan.filter.opentracing; +import io.opentracing.NoopTracerFactory; +import io.opentracing.Tracer; + import java.util.Iterator; import java.util.ServiceLoader; import com.weibo.api.motan.util.LoggerUtil; - -import io.opentracing.Tracer; /** * * @Description TracerFactory @@ -40,23 +41,29 @@ public interface TracerFactory { Tracer getTracer(); class DefaultTracerFactory implements TracerFactory { - private static Tracer tracer = null; + private static Tracer tracer = NoopTracerFactory.create(); static { loadDefaultTracer(); } /** - * load SPI Tracer and set default. the first tracer was used if more than one tracer was - * found. + * load SPI Tracer and set default only if one tracer is found. */ private static void loadDefaultTracer() { try { Iterator implementations = ServiceLoader.load(Tracer.class, Tracer.class.getClassLoader()).iterator(); if (implementations.hasNext()) { - tracer = implementations.next(); - LoggerUtil.info("io.opentracing.Tracer load in DefaultTracerFactory, " + tracer.getClass().getSimpleName() + Tracer firstTracer = implementations.next(); + if(!implementations.hasNext()){ + // only one tracer is found. + tracer = firstTracer; + LoggerUtil.info("io.opentracing.Tracer load in DefaultTracerFactory, " + tracer.getClass().getSimpleName() + " is used as default tracer."); + } else { + LoggerUtil.info("io.opentracing.Tracer load in DefaultTracerFactory, NoopTracer is used as default tracer since more than one tracer is found."); + } + } } catch (Exception e) { LoggerUtil.warn("DefaultTracerFactory load Tracer fail.", e); From 4d84acf5255b4300245cf1e308c31694df923133 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 21 Dec 2016 17:04:29 +0800 Subject: [PATCH 4/4] update OT version; remove brave UnitTest since brave-opentracing compiled with jdk8 --- .../filter-opentracing/pom.xml | 2 +- .../opentracing/OpenTracingFilterTest.java | 25 ++++++++++--------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/motan-extension/filter-extension/filter-opentracing/pom.xml b/motan-extension/filter-extension/filter-opentracing/pom.xml index 1b5b102df..3b1a76fbe 100644 --- a/motan-extension/filter-extension/filter-opentracing/pom.xml +++ b/motan-extension/filter-extension/filter-opentracing/pom.xml @@ -21,7 +21,7 @@ https://github.com/weibocom/motan UTF-8 - 0.20.2 + 0.20.4 diff --git a/motan-extension/filter-extension/filter-opentracing/src/test/java/com/weibo/api/motan/filter/opentracing/OpenTracingFilterTest.java b/motan-extension/filter-extension/filter-opentracing/src/test/java/com/weibo/api/motan/filter/opentracing/OpenTracingFilterTest.java index 91b9ee410..8f130ea90 100644 --- a/motan-extension/filter-extension/filter-opentracing/src/test/java/com/weibo/api/motan/filter/opentracing/OpenTracingFilterTest.java +++ b/motan-extension/filter-extension/filter-opentracing/src/test/java/com/weibo/api/motan/filter/opentracing/OpenTracingFilterTest.java @@ -16,7 +16,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import io.opentracing.Tracer; -import io.opentracing.impl.BraveTracer; +//import io.opentracing.impl.BraveTracer; import io.opentracing.mock.MockSpan; import io.opentracing.mock.MockTracer; @@ -110,10 +110,11 @@ public void testRefererFilter() { assertEquals(response, res); checkMockTracer(); - tracer = new BraveTracer();// use bravetracer - res = OTFilter.filter(refer, request); - assertEquals(response, res); - checkBraveTrace(); + // brave test must run with jdk1.8 +// tracer = new BraveTracer();// use bravetracer +// res = OTFilter.filter(refer, request); +// assertEquals(response, res); +// checkBraveTrace(); } @Test @@ -148,12 +149,12 @@ private void checkMockTracer() { } } - private void checkBraveTrace() { - if (tracer instanceof BraveTracer) { - assertTrue(request.getAttachments().containsKey("X-B3-TraceId")); - assertTrue(request.getAttachments().containsKey("X-B3-SpanId")); - assertTrue(request.getAttachments().containsKey("X-B3-Sampled")); - } - } +// private void checkBraveTrace() { +// if (tracer instanceof BraveTracer) { +// assertTrue(request.getAttachments().containsKey("X-B3-TraceId")); +// assertTrue(request.getAttachments().containsKey("X-B3-SpanId")); +// assertTrue(request.getAttachments().containsKey("X-B3-Sampled")); +// } +// } }