Repository: camel Updated Branches: refs/heads/master 4e13eae10 -> 75b424d0d
CAMEL-9795: camel-zipkin - Reuse existing span for complex eips like multicast. Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/75b424d0 Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/75b424d0 Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/75b424d0 Branch: refs/heads/master Commit: 75b424d0d8c49fd6d7daccd6c67e66e4eff129d4 Parents: 4e13eae Author: Claus Ibsen <davscl...@apache.org> Authored: Tue Apr 5 10:22:16 2016 +0200 Committer: Claus Ibsen <davscl...@apache.org> Committed: Tue Apr 5 10:22:16 2016 +0200 ---------------------------------------------------------------------- .../org/apache/camel/util/MessageHelper.java | 18 +++++++- components/camel-zipkin/pom.xml | 2 +- .../zipkin/ZipkinClientRequestAdapter.java | 5 ++- .../zipkin/ZipkinClientResponseAdaptor.java | 5 ++- .../zipkin/ZipkinServerRequestAdapter.java | 5 ++- .../zipkin/ZipkinServerResponseAdapter.java | 5 ++- .../org/apache/camel/zipkin/ZipkinTracer.java | 32 ++++++++++++-- .../zipkin/SpringZipkinSimpleRouteTest.java | 44 ++++++++++++++++++++ .../zipkin/SpringZipkinSimpleRouteTest.xml | 44 ++++++++++++++++++++ 9 files changed, 147 insertions(+), 13 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/75b424d0/camel-core/src/main/java/org/apache/camel/util/MessageHelper.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/util/MessageHelper.java b/camel-core/src/main/java/org/apache/camel/util/MessageHelper.java index 77fa472..2eeac61 100644 --- a/camel-core/src/main/java/org/apache/camel/util/MessageHelper.java +++ b/camel-core/src/main/java/org/apache/camel/util/MessageHelper.java @@ -213,7 +213,23 @@ public final class MessageHelper { streams = message.getExchange().getContext().getTypeConverter().convertTo(Boolean.class, message.getExchange(), property); } } + return extractBodyForLogging(message, prepend, streams, false); + } + /** + * Extracts the body for logging purpose. + * <p/> + * Will clip the body if its too big for logging. + * + * @see org.apache.camel.Exchange#LOG_DEBUG_BODY_STREAMS + * @see org.apache.camel.Exchange#LOG_DEBUG_BODY_MAX_CHARS + * @param message the message + * @param prepend a message to prepend + * @param allowStreams whether or not streams is allowed + * @param allowFiles whether or not files is allowed (currently not in use) + * @return the logging message + */ + public static String extractBodyForLogging(Message message, String prepend, boolean allowStreams, boolean allowFiles) { // default to 1000 chars int maxChars = 1000; @@ -224,7 +240,7 @@ public final class MessageHelper { } } - return extractBodyForLogging(message, prepend, streams, false, maxChars); + return extractBodyForLogging(message, prepend, allowStreams, allowFiles, maxChars); } /** http://git-wip-us.apache.org/repos/asf/camel/blob/75b424d0/components/camel-zipkin/pom.xml ---------------------------------------------------------------------- diff --git a/components/camel-zipkin/pom.xml b/components/camel-zipkin/pom.xml index 72ea58f..2cb8411 100644 --- a/components/camel-zipkin/pom.xml +++ b/components/camel-zipkin/pom.xml @@ -58,7 +58,7 @@ <!-- test dependencies --> <dependency> <groupId>org.apache.camel</groupId> - <artifactId>camel-test</artifactId> + <artifactId>camel-test-spring</artifactId> <scope>test</scope> </dependency> <dependency> http://git-wip-us.apache.org/repos/asf/camel/blob/75b424d0/components/camel-zipkin/src/main/java/org/apache/camel/zipkin/ZipkinClientRequestAdapter.java ---------------------------------------------------------------------- diff --git a/components/camel-zipkin/src/main/java/org/apache/camel/zipkin/ZipkinClientRequestAdapter.java b/components/camel-zipkin/src/main/java/org/apache/camel/zipkin/ZipkinClientRequestAdapter.java index a9664a1..a8f2207 100644 --- a/components/camel-zipkin/src/main/java/org/apache/camel/zipkin/ZipkinClientRequestAdapter.java +++ b/components/camel-zipkin/src/main/java/org/apache/camel/zipkin/ZipkinClientRequestAdapter.java @@ -80,8 +80,9 @@ public final class ZipkinClientRequestAdapter implements ClientRequestAdapter { KeyValueAnnotation key3 = KeyValueAnnotation.create("camel.client.exchange.pattern", exchange.getPattern().name()); KeyValueAnnotation key4 = null; - if (eventNotifier.isIncludeMessageBody()) { - String body = MessageHelper.extractBodyForLogging(exchange.hasOut() ? exchange.getOut() : exchange.getIn(), ""); + if (eventNotifier.isIncludeMessageBody() || eventNotifier.isIncludeMessageBodyStreams()) { + boolean streams = eventNotifier.isIncludeMessageBodyStreams(); + String body = MessageHelper.extractBodyForLogging(exchange.hasOut() ? exchange.getOut() : exchange.getIn(), "", streams, streams); key4 = KeyValueAnnotation.create("camel.client.exchange.message.request.body", body); } http://git-wip-us.apache.org/repos/asf/camel/blob/75b424d0/components/camel-zipkin/src/main/java/org/apache/camel/zipkin/ZipkinClientResponseAdaptor.java ---------------------------------------------------------------------- diff --git a/components/camel-zipkin/src/main/java/org/apache/camel/zipkin/ZipkinClientResponseAdaptor.java b/components/camel-zipkin/src/main/java/org/apache/camel/zipkin/ZipkinClientResponseAdaptor.java index 04ef33e..ec3711d 100644 --- a/components/camel-zipkin/src/main/java/org/apache/camel/zipkin/ZipkinClientResponseAdaptor.java +++ b/components/camel-zipkin/src/main/java/org/apache/camel/zipkin/ZipkinClientResponseAdaptor.java @@ -48,8 +48,9 @@ public class ZipkinClientResponseAdaptor implements ClientResponseAdapter { KeyValueAnnotation key3 = KeyValueAnnotation.create("camel.client.exchange.pattern", exchange.getPattern().name()); KeyValueAnnotation key4 = null; - if (eventNotifier.isIncludeMessageBody()) { - String body = MessageHelper.extractBodyForLogging(exchange.hasOut() ? exchange.getOut() : exchange.getIn(), ""); + if (eventNotifier.isIncludeMessageBody() || eventNotifier.isIncludeMessageBodyStreams()) { + boolean streams = eventNotifier.isIncludeMessageBodyStreams(); + String body = MessageHelper.extractBodyForLogging(exchange.hasOut() ? exchange.getOut() : exchange.getIn(), "", streams, streams); key4 = KeyValueAnnotation.create("camel.client.exchange.message.response.body", body); } http://git-wip-us.apache.org/repos/asf/camel/blob/75b424d0/components/camel-zipkin/src/main/java/org/apache/camel/zipkin/ZipkinServerRequestAdapter.java ---------------------------------------------------------------------- diff --git a/components/camel-zipkin/src/main/java/org/apache/camel/zipkin/ZipkinServerRequestAdapter.java b/components/camel-zipkin/src/main/java/org/apache/camel/zipkin/ZipkinServerRequestAdapter.java index 5d3b02f..3877b5f 100644 --- a/components/camel-zipkin/src/main/java/org/apache/camel/zipkin/ZipkinServerRequestAdapter.java +++ b/components/camel-zipkin/src/main/java/org/apache/camel/zipkin/ZipkinServerRequestAdapter.java @@ -77,8 +77,9 @@ public class ZipkinServerRequestAdapter implements ServerRequestAdapter { KeyValueAnnotation key3 = KeyValueAnnotation.create("camel.server.exchange.pattern", exchange.getPattern().name()); KeyValueAnnotation key4 = null; - if (eventNotifier.isIncludeMessageBody()) { - String body = MessageHelper.extractBodyForLogging(exchange.hasOut() ? exchange.getOut() : exchange.getIn(), ""); + if (eventNotifier.isIncludeMessageBody() || eventNotifier.isIncludeMessageBodyStreams()) { + boolean streams = eventNotifier.isIncludeMessageBodyStreams(); + String body = MessageHelper.extractBodyForLogging(exchange.hasOut() ? exchange.getOut() : exchange.getIn(), "", streams, streams); key4 = KeyValueAnnotation.create("camel.server.exchange.message.request.body", body); } http://git-wip-us.apache.org/repos/asf/camel/blob/75b424d0/components/camel-zipkin/src/main/java/org/apache/camel/zipkin/ZipkinServerResponseAdapter.java ---------------------------------------------------------------------- diff --git a/components/camel-zipkin/src/main/java/org/apache/camel/zipkin/ZipkinServerResponseAdapter.java b/components/camel-zipkin/src/main/java/org/apache/camel/zipkin/ZipkinServerResponseAdapter.java index 83d0e42..31071df 100644 --- a/components/camel-zipkin/src/main/java/org/apache/camel/zipkin/ZipkinServerResponseAdapter.java +++ b/components/camel-zipkin/src/main/java/org/apache/camel/zipkin/ZipkinServerResponseAdapter.java @@ -54,8 +54,9 @@ public class ZipkinServerResponseAdapter implements ServerResponseAdapter { if (exchange.getException() != null) { String message = exchange.getException().getMessage(); key4 = KeyValueAnnotation.create("camel.server.exchange.failure", message); - } else if (eventNotifier.isIncludeMessageBody()) { - String body = MessageHelper.extractBodyForLogging(exchange.hasOut() ? exchange.getOut() : exchange.getIn(), ""); + } else if (eventNotifier.isIncludeMessageBody() || eventNotifier.isIncludeMessageBodyStreams()) { + boolean streams = eventNotifier.isIncludeMessageBodyStreams(); + String body = MessageHelper.extractBodyForLogging(exchange.hasOut() ? exchange.getOut() : exchange.getIn(), "", streams, streams); key4 = KeyValueAnnotation.create("camel.server.exchange.message.response.body", body); } http://git-wip-us.apache.org/repos/asf/camel/blob/75b424d0/components/camel-zipkin/src/main/java/org/apache/camel/zipkin/ZipkinTracer.java ---------------------------------------------------------------------- diff --git a/components/camel-zipkin/src/main/java/org/apache/camel/zipkin/ZipkinTracer.java b/components/camel-zipkin/src/main/java/org/apache/camel/zipkin/ZipkinTracer.java index 546ec51..53a5432 100644 --- a/components/camel-zipkin/src/main/java/org/apache/camel/zipkin/ZipkinTracer.java +++ b/components/camel-zipkin/src/main/java/org/apache/camel/zipkin/ZipkinTracer.java @@ -87,7 +87,7 @@ import static org.apache.camel.builder.ExpressionBuilder.routeIdExpression; * to trap when Camel starts/ends an {@link Exchange} being routed using the {@link RoutePolicy} and during the routing * if the {@link Exchange} sends messages, then we track them using the {@link org.apache.camel.spi.EventNotifier}. */ -@ManagedResource(description = "Managing ZipkinTracer") +@ManagedResource(description = "ZipkinTracer") public class ZipkinTracer extends EventNotifierSupport implements RoutePolicy, RoutePolicyFactory, StatefulService, CamelContextAware { private final Map<String, Brave> braves = new HashMap<>(); @@ -102,10 +102,14 @@ public class ZipkinTracer extends EventNotifierSupport implements RoutePolicy, R private Map<String, String> serverServiceMappings = new HashMap<>(); private Set<String> excludePatterns = new HashSet<>(); private boolean includeMessageBody; + private boolean includeMessageBodyStreams; public ZipkinTracer() { } + /** + * Registers this {@link ZipkinTracer} on the {@link CamelContext}. + */ public void init(CamelContext camelContext) { if (!camelContext.getManagementStrategy().getEventNotifiers().contains(this)) { camelContext.getManagementStrategy().addEventNotifier(this); @@ -123,6 +127,7 @@ public class ZipkinTracer extends EventNotifierSupport implements RoutePolicy, R this.camelContext = camelContext; } + @ManagedAttribute(description = "The hostname for the remote zipkin server to use.") public String getHostName() { return hostName; } @@ -134,6 +139,7 @@ public class ZipkinTracer extends EventNotifierSupport implements RoutePolicy, R this.hostName = hostName; } + @ManagedAttribute(description = "The port number for the remote zipkin server to use.") public int getPort() { return port; } @@ -145,6 +151,7 @@ public class ZipkinTracer extends EventNotifierSupport implements RoutePolicy, R this.port = port; } + @ManagedAttribute(description = "Rates how many events should be traced by zipkin. The rate is expressed as a percentage (1.0f = 100%, 0.5f is 50%, 0.1f is 10%).") public float getRate() { return rate; } @@ -247,12 +254,31 @@ public class ZipkinTracer extends EventNotifierSupport implements RoutePolicy, R * <p/> * This is not recommended for production usage, or when having big payloads. You can limit the size by * configuring the <a href="http://camel.apache.org/how-do-i-set-the-max-chars-when-debug-logging-messages-in-camel.html">max debug log size</a>. + * <p/> + * By default message bodies that are stream based are <b>not</b> included. You can use the option {@link #setIncludeMessageBodyStreams(boolean)} to + * turn that on. */ @ManagedAttribute(description = "Whether to include the Camel message body in the zipkin traces") public void setIncludeMessageBody(boolean includeMessageBody) { this.includeMessageBody = includeMessageBody; } + @ManagedAttribute(description = "Whether to include stream based Camel message bodies in the zipkin traces") + public boolean isIncludeMessageBodyStreams() { + return includeMessageBodyStreams; + } + + /** + * Whether to include message bodies that are stream based in the zipkin traces. + * <p/> + * This is not recommended for production usage, or when having big payloads. You can limit the size by + * configuring the <a href="http://camel.apache.org/how-do-i-set-the-max-chars-when-debug-logging-messages-in-camel.html">max debug log size</a>. + */ + @ManagedAttribute(description = "Whether to include stream based Camel message bodies in the zipkin traces") + public void setIncludeMessageBodyStreams(boolean includeMessageBodyStreams) { + this.includeMessageBodyStreams = includeMessageBodyStreams; + } + @Override protected void doStart() throws Exception { super.doStart(); @@ -277,8 +303,8 @@ public class ZipkinTracer extends EventNotifierSupport implements RoutePolicy, R ObjectHelper.notNull(spanCollector, "SpanCollector", this); - if (clientServiceMappings.isEmpty()) { - log.warn("No service name(s) has been configured. Camel will fallback and use endpoint uris as service names."); + if (clientServiceMappings.isEmpty() && serverServiceMappings.isEmpty()) { + log.warn("No service name(s) has been mapped in clientServiceMappings or serverServiceMappings. Camel will fallback and use endpoint uris as service names."); useFallbackServiceNames = true; } http://git-wip-us.apache.org/repos/asf/camel/blob/75b424d0/components/camel-zipkin/src/test/java/org/apache/camel/zipkin/SpringZipkinSimpleRouteTest.java ---------------------------------------------------------------------- diff --git a/components/camel-zipkin/src/test/java/org/apache/camel/zipkin/SpringZipkinSimpleRouteTest.java b/components/camel-zipkin/src/test/java/org/apache/camel/zipkin/SpringZipkinSimpleRouteTest.java new file mode 100644 index 0000000..9219bcb --- /dev/null +++ b/components/camel-zipkin/src/test/java/org/apache/camel/zipkin/SpringZipkinSimpleRouteTest.java @@ -0,0 +1,44 @@ +/** + * 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 org.apache.camel.zipkin; + +import java.util.concurrent.TimeUnit; + +import org.apache.camel.builder.NotifyBuilder; +import org.apache.camel.test.spring.CamelSpringTestSupport; +import org.junit.Test; +import org.springframework.context.support.AbstractApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +public class SpringZipkinSimpleRouteTest extends CamelSpringTestSupport { + + @Override + protected AbstractApplicationContext createApplicationContext() { + return new ClassPathXmlApplicationContext("org/apache/camel/zipkin/SpringZipkinSimpleRouteTest.xml"); + } + + @Test + public void testZipkinRoute() throws Exception { + NotifyBuilder notify = new NotifyBuilder(context).whenDone(5).create(); + + for (int i = 0; i < 5; i++) { + template.sendBody("seda:dude", "Hello World"); + } + + assertTrue(notify.matches(30, TimeUnit.SECONDS)); + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/75b424d0/components/camel-zipkin/src/test/resources/org/apache/camel/zipkin/SpringZipkinSimpleRouteTest.xml ---------------------------------------------------------------------- diff --git a/components/camel-zipkin/src/test/resources/org/apache/camel/zipkin/SpringZipkinSimpleRouteTest.xml b/components/camel-zipkin/src/test/resources/org/apache/camel/zipkin/SpringZipkinSimpleRouteTest.xml new file mode 100644 index 0000000..089d98a --- /dev/null +++ b/components/camel-zipkin/src/test/resources/org/apache/camel/zipkin/SpringZipkinSimpleRouteTest.xml @@ -0,0 +1,44 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + 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. +--> +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation=" + http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd + http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd + "> + + <!-- to use a logger as the collector (for testing) --> + <bean id="logSpanCollector" class="org.apache.camel.zipkin.ZipkinLoggingSpanCollector"/> + + <!-- setup zipkin tracer --> + <bean id="zipkinTracer" class="org.apache.camel.zipkin.ZipkinTracer"> + <property name="serviceName" value="dude"/> + <property name="spanCollector" ref="logSpanCollector"/> + </bean> + + <camelContext xmlns="http://camel.apache.org/schema/spring"> + <route id="dude"> + <from uri="seda:dude"/> + <log message="Routing at ${routeId}"/> + <delay> + <simple>${random(1000,2000)}</simple> + </delay> + </route> + </camelContext> + +</beans>