diff --git a/.travis.yml b/.travis.yml index 5699bf565..d6bd23957 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,9 +9,6 @@ before_install: - echo "https://$GH_TOKEN:@github.com" > .git/credentials - gem install asciidoctor install: -- ./mvnw install -P docs -q -U -DskipTests=true -Dmaven.test.redirectTestOutputToFile=true -- '[ "${MVN_GOAL}" == "deploy" ] && ./docs/src/main/asciidoc/ghpages.sh || echo "Not updating docs"' -script: - | cat < * * * @author Spencer Gibb @@ -63,7 +63,41 @@ public class Span { public static final String SPAN_NAME_NAME = "X-Span-Name"; public static final String SPAN_ID_NAME = "X-Span-Id"; public static final String SPAN_EXPORT_NAME = "X-Span-Export"; + public static final String SPAN_LOCAL_COMPONENT_TAG_NAME = "lc"; + /** + * cr - Client Receive. Signifies the end of the span. The client has successfully received the + * response from the server side. If one subtracts the cs timestamp from this timestamp one + * will receive the whole time needed by the client to receive the response from the server. + */ + public static final String CLIENT_RECV = "cr"; + + /** + * cs - Client Sent. The client has made a request (a client can be e.g. + * {@link org.springframework.web.client.RestTemplate}. This annotation depicts + * the start of the span. + */ + // For an outbound RPC call, it should log a "cs" annotation. + // If possible, it should log a binary annotation of "sa", indicating the + // destination address. + public static final String CLIENT_SEND = "cs"; + + /** + * sr - Server Receive. The server side got the request and will start processing it. + * If one subtracts the cs timestamp from this timestamp one will receive the network latency. + */ + // If an inbound RPC call, it should log a "sr" annotation. + // If possible, it should log a binary annotation of "ca", indicating the + // caller's address (ex X-Forwarded-For header) + public static final String SERVER_RECV = "sr"; + + /** + * ss - Server Send. Annotated upon completion of request processing (when the response + * got sent back to the client). If one subtracts the sr timestamp from this timestamp one + * will receive the time needed by the server side to process the request. + */ + public static final String SERVER_SEND = "ss"; + /** * As in Open Tracing */ diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/event/ClientSentEvent.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/SpanReporter.java similarity index 58% rename from spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/event/ClientSentEvent.java rename to spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/SpanReporter.java index c7293be24..d66c7b439 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/event/ClientSentEvent.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/SpanReporter.java @@ -14,23 +14,19 @@ * limitations under the License. */ -package org.springframework.cloud.sleuth.event; - -import org.springframework.cloud.sleuth.Span; +package org.springframework.cloud.sleuth; /** - * cs - Client Sent. The client has made a request (a client can be e.g. - * {@link org.springframework.web.client.RestTemplate}. This annotation depicts - * the start of the span. + * Contract for reporting Sleuth spans for collection. For example to Zipkin. + * + * @author Marcin Grzejszczak * - * @author Dave Syer * @since 1.0.0 */ -@SuppressWarnings("serial") -public class ClientSentEvent extends SpanContainingEvent { - - public ClientSentEvent(Object source, Span span) { - super(source, span); - } - -} \ No newline at end of file +public interface SpanReporter { + /** + * Reports a completed span out of band, usually out of process. + * This is typically to a trace depot (ex zipkin) or a log file. + */ + void report(Span span); +} diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/autoconfig/TraceAutoConfiguration.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/autoconfig/TraceAutoConfiguration.java index 77042e7ea..3f46fa2f3 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/autoconfig/TraceAutoConfiguration.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/autoconfig/TraceAutoConfiguration.java @@ -22,13 +22,15 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.cloud.sleuth.DefaultSpanNamer; +import org.springframework.cloud.sleuth.NoOpSpanReporter; import org.springframework.cloud.sleuth.Sampler; import org.springframework.cloud.sleuth.SpanNamer; +import org.springframework.cloud.sleuth.SpanReporter; import org.springframework.cloud.sleuth.TraceKeys; import org.springframework.cloud.sleuth.Tracer; +import org.springframework.cloud.sleuth.log.SpanLogger; import org.springframework.cloud.sleuth.sampler.NeverSampler; import org.springframework.cloud.sleuth.trace.DefaultTracer; -import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -60,9 +62,10 @@ public class TraceAutoConfiguration { @Bean @ConditionalOnMissingBean(Tracer.class) public DefaultTracer traceManager(Sampler sampler, Random random, - ApplicationEventPublisher publisher, - SpanNamer spanNamer) { - return new DefaultTracer(sampler, random, publisher, spanNamer); + SpanNamer spanNamer, SpanLogger spanLogger, + SpanReporter spanReporter) { + return new DefaultTracer(sampler, random, spanNamer, spanLogger, + spanReporter); } @Bean @@ -77,4 +80,10 @@ public class TraceAutoConfiguration { return new DefaultSpanNamer(); } + @Bean + @ConditionalOnMissingBean + public SpanReporter defaultSpanReporter() { + return new NoOpSpanReporter(); + } + } diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/event/ClientReceivedEvent.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/event/ClientReceivedEvent.java deleted file mode 100644 index 9b266b7a0..000000000 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/event/ClientReceivedEvent.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2013-2016 the original author or authors. - * - * 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 org.springframework.cloud.sleuth.event; - -import org.springframework.cloud.sleuth.Span; - -/** - * cr - Client Receive. Signifies the end of the span. The client has successfully received the - * response from the server side. If one subtracts the cs timestamp from this timestamp one - * will receive the whole time needed by the client to receive the response from the server. - * - * @author Dave Syer - * @since 1.0.0 - * - * @see ClientSentEvent - */ -@SuppressWarnings("serial") -public class ClientReceivedEvent extends SpanContainingEvent { - - public ClientReceivedEvent(Object source, Span span) { - super(source, span); - } - -} \ No newline at end of file diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/event/ServerSentEvent.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/event/ServerSentEvent.java deleted file mode 100644 index 3d0a0fe92..000000000 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/event/ServerSentEvent.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2013-2016 the original author or authors. - * - * 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 org.springframework.cloud.sleuth.event; - -import org.springframework.cloud.sleuth.Span; - -/** - * ss - Server Send. Annotated upon completion of request processing (when the response - * got sent back to the client). If one subtracts the sr timestamp from this timestamp one - * will receive the time needed by the server side to process the request. - * - * @author Spencer Gibb - * @since 1.0.0 - * - * @see ServerReceivedEvent - */ -@SuppressWarnings("serial") -public class ServerSentEvent extends SpanParentContainingEvent { - - public ServerSentEvent(Object source, Span span) { - this(source, null, span); - } - - public ServerSentEvent(Object source, Span parent, Span span) { - super(source, parent, span); - } -} \ No newline at end of file diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/event/SpanContainingEvent.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/event/SpanContainingEvent.java deleted file mode 100644 index a8fdea76f..000000000 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/event/SpanContainingEvent.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2013-2016 the original author or authors. - * - * 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 org.springframework.cloud.sleuth.event; - -import java.util.Objects; - -import org.springframework.cloud.sleuth.Span; -import org.springframework.context.ApplicationEvent; - -/** - * @author Marcin Grzejszczak - */ -abstract class SpanContainingEvent extends ApplicationEvent { - private final Span span; - - public SpanContainingEvent(Object source, Span span) { - super(source); - this.span = span; - } - - public Span getSpan() { - return this.span; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - SpanContainingEvent that = (SpanContainingEvent) o; - return Objects.equals(this.span, that.span); - } - - @Override - public int hashCode() { - return this.span != null ? this.span.hashCode() : 0; - } - - @Override - public String toString() { - return getClass().getSimpleName() + "{" + - "span=" + this.span + - '}'; - } -} diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/event/SpanParentContainingEvent.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/event/SpanParentContainingEvent.java deleted file mode 100644 index 9a2ade0f7..000000000 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/event/SpanParentContainingEvent.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2013-2016 the original author or authors. - * - * 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 org.springframework.cloud.sleuth.event; - -import java.util.Objects; - -import org.springframework.cloud.sleuth.Span; -import org.springframework.context.ApplicationEvent; - -/** - * @author Marcin Grzejszczak - */ -abstract class SpanParentContainingEvent extends ApplicationEvent { - - private final Span span; - private final Span parent; - - public SpanParentContainingEvent(Object source, Span span) { - this(source, null, span); - } - - public SpanParentContainingEvent(Object source, Span parent, Span span) { - super(source); - this.parent = parent; - this.span = span; - } - - public Span getParent() { - return this.parent; - } - - public Span getSpan() { - return this.span; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - SpanParentContainingEvent that = (SpanParentContainingEvent) o; - return Objects.equals(this.parent, that.parent) && Objects - .equals(this.span, that.span); - } - - @Override - public int hashCode() { - return Objects.hash(this.parent, this.span); - } - - @Override - public String toString() { - return getClass().getSimpleName() + "{" + - "span=" + this.span + - ", parent=" + this.parent + - '}'; - } -} diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/event/SpanReleasedEvent.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/event/SpanReleasedEvent.java deleted file mode 100644 index ce30e2510..000000000 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/event/SpanReleasedEvent.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2013-2016 the original author or authors. - * - * 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 org.springframework.cloud.sleuth.event; - -import org.springframework.cloud.sleuth.Span; - -/** - * Event emitted upon closing of a span. Results in preparing span for collection - * to external systems (logging, Zipkin etc.) - * - * @author Spencer Gibb - */ -@SuppressWarnings("serial") -public class SpanReleasedEvent extends SpanParentContainingEvent { - - public SpanReleasedEvent(Object source, Span span) { - this(source, null, span); - } - - public SpanReleasedEvent(Object source, Span parent, Span span) { - super(source, parent, span); - } -} \ No newline at end of file diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceFilter.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceFilter.java index c036396f1..273f747a3 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceFilter.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceFilter.java @@ -29,14 +29,10 @@ import javax.servlet.http.HttpServletResponse; import org.springframework.cloud.sleuth.Span; import org.springframework.cloud.sleuth.Span.SpanBuilder; +import org.springframework.cloud.sleuth.SpanReporter; import org.springframework.cloud.sleuth.TraceKeys; import org.springframework.cloud.sleuth.Tracer; -import org.springframework.cloud.sleuth.event.ServerReceivedEvent; -import org.springframework.cloud.sleuth.event.ServerSentEvent; import org.springframework.cloud.sleuth.sampler.NeverSampler; -import org.springframework.context.ApplicationEvent; -import org.springframework.context.ApplicationEventPublisher; -import org.springframework.context.ApplicationEventPublisherAware; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; import org.springframework.util.StringUtils; @@ -68,8 +64,7 @@ import static org.springframework.util.StringUtils.hasText; * @since 1.0.0 */ @Order(Ordered.HIGHEST_PRECEDENCE + 5) -public class TraceFilter extends OncePerRequestFilter - implements ApplicationEventPublisherAware { +public class TraceFilter extends OncePerRequestFilter { protected static final String TRACE_REQUEST_ATTR = TraceFilter.class.getName() + ".TRACE"; @@ -81,25 +76,22 @@ public class TraceFilter extends OncePerRequestFilter private final TraceKeys traceKeys; private final Pattern skipPattern; private final Random random; + private final SpanReporter spanReporter; private UrlPathHelper urlPathHelper = new UrlPathHelper(); - private ApplicationEventPublisher publisher; - public TraceFilter(Tracer tracer, TraceKeys traceKeys) { - this(tracer, traceKeys, Pattern.compile(DEFAULT_SKIP_PATTERN), new Random()); + public TraceFilter(Tracer tracer, TraceKeys traceKeys, SpanReporter spanReporter) { + this(tracer, traceKeys, Pattern.compile(DEFAULT_SKIP_PATTERN), new Random(), + spanReporter); } public TraceFilter(Tracer tracer, TraceKeys traceKeys, Pattern skipPattern, - Random random) { + Random random, SpanReporter spanReporter) { this.tracer = tracer; this.traceKeys = traceKeys; this.skipPattern = skipPattern; this.random = random; - } - - @Override - public void setApplicationEventPublisher(ApplicationEventPublisher publisher) { - this.publisher = publisher; + this.spanReporter = spanReporter; } @Override @@ -152,7 +144,9 @@ public class TraceFilter extends OncePerRequestFilter Span parent = span.build(); spanFromRequest = this.tracer.createSpan(name, parent); - publish(new ServerReceivedEvent(this, parent, spanFromRequest)); + if (parent != null && parent.isRemote()) { + parent.logEvent(Span.SERVER_RECV); + } request.setAttribute(TRACE_REQUEST_ATTR, spanFromRequest); } @@ -193,8 +187,11 @@ public class TraceFilter extends OncePerRequestFilter if (spanFromRequest != null) { addResponseTags(response, exception); if (spanFromRequest.hasSavedSpan()) { - publish(new ServerSentEvent(this, spanFromRequest.getSavedSpan(), - spanFromRequest)); + Span parent = spanFromRequest.getSavedSpan(); + if (parent != null && parent.isRemote()) { + parent.logEvent(Span.SERVER_SEND); + this.spanReporter.report(parent); + } } // Double close to clean up the parent (remote span as well) this.tracer.close(spanFromRequest); @@ -211,12 +208,6 @@ public class TraceFilter extends OncePerRequestFilter } } - private void publish(ApplicationEvent event) { - if (this.publisher != null) { - this.publisher.publishEvent(event); - } - } - /** Override to add annotations not defined in {@link TraceKeys}. */ protected void addRequestTags(HttpServletRequest request) { String uri = this.urlPathHelper.getPathWithinApplication(request); diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebAutoConfiguration.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebAutoConfiguration.java index 5771182ea..9f9b4483e 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebAutoConfiguration.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/TraceWebAutoConfiguration.java @@ -31,10 +31,10 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplicat import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.cloud.sleuth.SpanAccessor; import org.springframework.cloud.sleuth.SpanNamer; +import org.springframework.cloud.sleuth.SpanReporter; import org.springframework.cloud.sleuth.TraceKeys; import org.springframework.cloud.sleuth.Tracer; import org.springframework.cloud.sleuth.autoconfig.TraceAutoConfiguration; -import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.util.StringUtils; @@ -80,10 +80,10 @@ public class TraceWebAutoConfiguration { @Bean @ConditionalOnMissingBean - public TraceFilter traceFilter(ApplicationEventPublisher publisher, Random random, SkipPatternProvider skipPatternProvider) { - TraceFilter filter = new TraceFilter(this.tracer, this.traceKeys, skipPatternProvider.skipPattern(), random); - filter.setApplicationEventPublisher(publisher); - return filter; + public TraceFilter traceFilter(Random random, + SkipPatternProvider skipPatternProvider, SpanReporter spanReporter) { + return new TraceFilter(this.tracer, this.traceKeys, skipPatternProvider.skipPattern(), random, + spanReporter); } @Configuration diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/AbstractTraceHttpRequestInterceptor.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/AbstractTraceHttpRequestInterceptor.java index 8d9ac8c49..a7f9e5fb3 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/AbstractTraceHttpRequestInterceptor.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/AbstractTraceHttpRequestInterceptor.java @@ -20,11 +20,6 @@ import java.net.URI; import org.springframework.cloud.sleuth.Span; import org.springframework.cloud.sleuth.Tracer; -import org.springframework.cloud.sleuth.event.ClientReceivedEvent; -import org.springframework.cloud.sleuth.event.ClientSentEvent; -import org.springframework.context.ApplicationEvent; -import org.springframework.context.ApplicationEventPublisher; -import org.springframework.context.ApplicationEventPublisherAware; import org.springframework.http.HttpRequest; import org.springframework.util.StringUtils; @@ -36,20 +31,14 @@ import org.springframework.util.StringUtils; * * @since 1.0.0 */ -abstract class AbstractTraceHttpRequestInterceptor - implements ApplicationEventPublisherAware { +abstract class AbstractTraceHttpRequestInterceptor { - private ApplicationEventPublisher publisher; protected final Tracer tracer; protected AbstractTraceHttpRequestInterceptor(Tracer tracer) { this.tracer = tracer; } - @Override - public void setApplicationEventPublisher(ApplicationEventPublisher publisher) { - this.publisher = publisher; - } private void enrichWithTraceHeaders(HttpRequest request, Span span) { setIdHeader(request, Span.TRACE_ID_NAME, span.getTraceId()); @@ -88,7 +77,7 @@ abstract class AbstractTraceHttpRequestInterceptor String spanName = uriScheme(uri) + ":" + uri.getPath(); Span newSpan = this.tracer.createSpan(spanName); enrichWithTraceHeaders(request, newSpan); - publish(new ClientSentEvent(this, newSpan)); + newSpan.logEvent(Span.CLIENT_SEND); } private String uriScheme(URI uri) { @@ -96,22 +85,16 @@ abstract class AbstractTraceHttpRequestInterceptor } /** - * Close the current span and emit the ClientReceivedEvent + * Close the current span and log the client received event */ public void finish() { if (!isTracing()) { return; } - publish(new ClientReceivedEvent(this, currentSpan())); + currentSpan().logEvent(Span.CLIENT_RECV); this.tracer.close(this.currentSpan()); } - private void publish(ApplicationEvent event) { - if (this.publisher != null) { - this.publisher.publishEvent(event); - } - } - protected Span currentSpan() { return this.tracer.getCurrentSpan(); } diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceAsyncRestTemplate.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceAsyncRestTemplate.java index d31a03c29..8b906b9dc 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceAsyncRestTemplate.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/TraceAsyncRestTemplate.java @@ -20,10 +20,6 @@ import java.net.URI; import org.springframework.cloud.sleuth.Span; import org.springframework.cloud.sleuth.Tracer; -import org.springframework.cloud.sleuth.event.ClientReceivedEvent; -import org.springframework.context.ApplicationEvent; -import org.springframework.context.ApplicationEventPublisher; -import org.springframework.context.ApplicationEventPublisherAware; import org.springframework.core.task.AsyncListenableTaskExecutor; import org.springframework.http.HttpMethod; import org.springframework.http.client.AsyncClientHttpRequestFactory; @@ -43,10 +39,7 @@ import org.springframework.web.client.RestTemplate; * * @since 1.0.0 */ -class TraceAsyncRestTemplate extends AsyncRestTemplate - implements ApplicationEventPublisherAware { - - private ApplicationEventPublisher publisher; +class TraceAsyncRestTemplate extends AsyncRestTemplate { private final Tracer tracer; @@ -93,16 +86,10 @@ class TraceAsyncRestTemplate extends AsyncRestTemplate if (!isTracing()) { return; } - publish(new ClientReceivedEvent(this, currentSpan())); + currentSpan().logEvent(Span.CLIENT_RECV); this.tracer.close(this.currentSpan()); } - private void publish(ApplicationEvent event) { - if (this.publisher != null) { - this.publisher.publishEvent(event); - } - } - private Span currentSpan() { return this.tracer.getCurrentSpan(); } @@ -111,9 +98,4 @@ class TraceAsyncRestTemplate extends AsyncRestTemplate return this.tracer.isTracing(); } - @Override - public void setApplicationEventPublisher( - ApplicationEventPublisher applicationEventPublisher) { - this.publisher = applicationEventPublisher; - } } diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/FeignBeanPostProcessor.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/FeignBeanPostProcessor.java index a341d02e2..1becb3f52 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/FeignBeanPostProcessor.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/FeignBeanPostProcessor.java @@ -19,7 +19,6 @@ package org.springframework.cloud.sleuth.instrument.web.client.feign; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.cloud.sleuth.Tracer; -import org.springframework.context.ApplicationEventPublisher; import feign.Client; import feign.Retryer; @@ -35,11 +34,9 @@ import feign.codec.Decoder; */ final class FeignBeanPostProcessor implements BeanPostProcessor { - private final ApplicationEventPublisher publisher; private final Tracer tracer; - FeignBeanPostProcessor(ApplicationEventPublisher publisher, Tracer tracer) { - this.publisher = publisher; + FeignBeanPostProcessor(Tracer tracer) { this.tracer = tracer; } @@ -47,11 +44,11 @@ final class FeignBeanPostProcessor implements BeanPostProcessor { public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if (bean instanceof Decoder && !(bean instanceof TraceFeignDecoder)) { - return new TraceFeignDecoder(this.publisher, this.tracer, (Decoder) bean); + return new TraceFeignDecoder(this.tracer, (Decoder) bean); } else if (bean instanceof Retryer && !(bean instanceof TraceFeignRetryer)) { return new TraceFeignRetryer(this.tracer, (Retryer) bean); } else if (bean instanceof Client && !(bean instanceof TraceFeignClient)) { - return new TraceFeignClient(this.publisher, this.tracer, (Client) bean); + return new TraceFeignClient(this.tracer, (Client) bean); } return bean; } diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/FeignEventPublisher.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/FeignEventPublisher.java index 3a4570db0..04f62ddb4 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/FeignEventPublisher.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/FeignEventPublisher.java @@ -18,11 +18,9 @@ package org.springframework.cloud.sleuth.instrument.web.client.feign; import org.springframework.cloud.sleuth.Span; import org.springframework.cloud.sleuth.Tracer; -import org.springframework.cloud.sleuth.event.ClientReceivedEvent; -import org.springframework.context.ApplicationEventPublisher; /** - * Abstract class for publishing {@link org.springframework.cloud.sleuth.event.ClientReceivedEvent} + * Abstract class for publishing logging the client received event * * @author Marcin Grzejszczak * @@ -32,18 +30,16 @@ abstract class FeignEventPublisher { private final FeignRequestContext feignRequestContext = FeignRequestContext.getInstance(); - private final ApplicationEventPublisher publisher; private final Tracer tracer; - protected FeignEventPublisher(ApplicationEventPublisher publisher, Tracer tracer) { - this.publisher = publisher; + protected FeignEventPublisher(Tracer tracer) { this.tracer = tracer; } protected void finish() { Span span = this.feignRequestContext.getCurrentSpan(); if (span != null) { - this.publisher.publishEvent(new ClientReceivedEvent(this, span)); + span.logEvent(Span.CLIENT_RECV); this.tracer.close(span); this.feignRequestContext.clearContext(); } diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/SleuthFeignBuilder.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/SleuthFeignBuilder.java index 0b7420102..1f67e428e 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/SleuthFeignBuilder.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/SleuthFeignBuilder.java @@ -17,7 +17,6 @@ package org.springframework.cloud.sleuth.instrument.web.client.feign; import org.springframework.cloud.sleuth.Tracer; -import org.springframework.context.ApplicationEventPublisher; import feign.Feign; import feign.hystrix.HystrixFeign; @@ -35,10 +34,10 @@ final class SleuthFeignBuilder { private SleuthFeignBuilder() {} - static Feign.Builder builder(ApplicationEventPublisher publisher, Tracer tracer) { + static Feign.Builder builder(Tracer tracer) { return HystrixFeign.builder() - .client(new TraceFeignClient(publisher, tracer)) + .client(new TraceFeignClient(tracer)) .retryer(new TraceFeignRetryer(tracer)) - .decoder(new TraceFeignDecoder(publisher, tracer)); + .decoder(new TraceFeignDecoder(tracer)); } } diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignClient.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignClient.java index ffaa2d1e3..a9a80ccd2 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignClient.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignClient.java @@ -20,7 +20,6 @@ import java.io.IOException; import java.util.Objects; import org.springframework.cloud.sleuth.Tracer; -import org.springframework.context.ApplicationEventPublisher; import feign.Client; import feign.Request; @@ -38,13 +37,13 @@ final class TraceFeignClient extends FeignEventPublisher implements Client { private final Client delegate; - TraceFeignClient(ApplicationEventPublisher publisher, Tracer tracer) { - super(publisher, tracer); + TraceFeignClient(Tracer tracer) { + super(tracer); this.delegate = new Client.Default(null, null); } - TraceFeignClient(ApplicationEventPublisher publisher, Tracer tracer, Client delegate) { - super(publisher, tracer); + TraceFeignClient(Tracer tracer, Client delegate) { + super(tracer); this.delegate = delegate; } diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignClientAutoConfiguration.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignClientAutoConfiguration.java index 1aa92c341..c47299fec 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignClientAutoConfiguration.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignClientAutoConfiguration.java @@ -36,7 +36,6 @@ import org.springframework.cloud.sleuth.Span; import org.springframework.cloud.sleuth.TraceKeys; import org.springframework.cloud.sleuth.Tracer; import org.springframework.cloud.sleuth.instrument.hystrix.SleuthHystrixAutoConfiguration; -import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; @@ -72,9 +71,6 @@ public class TraceFeignClientAutoConfiguration { @Autowired private ObjectFactory messageConverters; - @Autowired - private ApplicationEventPublisher publisher; - @Autowired private Tracer tracer; @@ -85,19 +81,19 @@ public class TraceFeignClientAutoConfiguration { @ConditionalOnClass(HystrixCommand.class) @ConditionalOnProperty(name = "feign.hystrix.enabled", matchIfMissing = true) public Feign.Builder feignHystrixBuilder(Tracer tracer, TraceKeys traceKeys) { - return SleuthFeignBuilder.builder(this.publisher, tracer); + return SleuthFeignBuilder.builder(tracer); } @Bean @ConditionalOnProperty(name = "spring.sleuth.feign.processor.enabled", matchIfMissing = true) public FeignBeanPostProcessor feignBeanPostProcessor(Tracer tracer) { - return new FeignBeanPostProcessor(this.publisher, tracer); + return new FeignBeanPostProcessor(tracer); } @Bean @Primary public Decoder feignDecoder(final Tracer tracer) { - return new TraceFeignDecoder(this.publisher, tracer, new ResponseEntityDecoder(new SpringDecoder(this.messageConverters)) { + return new TraceFeignDecoder(tracer, new ResponseEntityDecoder(new SpringDecoder(this.messageConverters)) { @Override public Object decode(Response response, Type type) throws IOException, FeignException { diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignDecoder.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignDecoder.java index 149e81445..d1d304066 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignDecoder.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignDecoder.java @@ -20,7 +20,6 @@ import java.io.IOException; import java.lang.reflect.Type; import org.springframework.cloud.sleuth.Tracer; -import org.springframework.context.ApplicationEventPublisher; import feign.FeignException; import feign.Response; @@ -38,13 +37,13 @@ final class TraceFeignDecoder extends FeignEventPublisher implements Decoder { private final Decoder delegate; - TraceFeignDecoder(ApplicationEventPublisher publisher, Tracer tracer) { - super(publisher, tracer); + TraceFeignDecoder(Tracer tracer) { + super(tracer); this.delegate = new Decoder.Default(); } - TraceFeignDecoder(ApplicationEventPublisher publisher, Tracer tracer, Decoder delegate) { - super(publisher, tracer); + TraceFeignDecoder(Tracer tracer, Decoder delegate) { + super(tracer); this.delegate = delegate; } diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignRequestInterceptor.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignRequestInterceptor.java index a15fdb28d..d3a7447a6 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignRequestInterceptor.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TraceFeignRequestInterceptor.java @@ -20,10 +20,6 @@ import java.net.URI; import org.springframework.cloud.sleuth.Span; import org.springframework.cloud.sleuth.Tracer; -import org.springframework.cloud.sleuth.event.ClientSentEvent; -import org.springframework.context.ApplicationEvent; -import org.springframework.context.ApplicationEventPublisher; -import org.springframework.context.ApplicationEventPublisherAware; import org.springframework.util.StringUtils; import feign.RequestInterceptor; @@ -37,14 +33,11 @@ import feign.RequestTemplate; * * @since 1.0.0 */ -final class TraceFeignRequestInterceptor implements RequestInterceptor, - ApplicationEventPublisherAware { +final class TraceFeignRequestInterceptor implements RequestInterceptor { private final Tracer tracer; private final FeignRequestContext feignRequestContext = FeignRequestContext.getInstance(); - private ApplicationEventPublisher publisher; - TraceFeignRequestInterceptor(Tracer tracer) { this.tracer = tracer; } @@ -68,7 +61,7 @@ final class TraceFeignRequestInterceptor implements RequestInterceptor, setHeader(template, Span.PARENT_ID_NAME, Span.idToHex(parentId)); } setHeader(template, Span.PROCESS_ID_NAME, span.getProcessId()); - publish(new ClientSentEvent(this, span)); + span.logEvent(Span.CLIENT_SEND); } protected String getSpanName(RequestTemplate template) { @@ -108,15 +101,4 @@ final class TraceFeignRequestInterceptor implements RequestInterceptor, } } - private void publish(ApplicationEvent event) { - if (this.publisher != null) { - this.publisher.publishEvent(event); - } - } - - @Override - public void setApplicationEventPublisher( - ApplicationEventPublisher applicationEventPublisher) { - this.publisher = applicationEventPublisher; - } } diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/zuul/TracePostZuulFilter.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/zuul/TracePostZuulFilter.java index dc399b4a9..9b83ed2c8 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/zuul/TracePostZuulFilter.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/zuul/TracePostZuulFilter.java @@ -18,10 +18,6 @@ package org.springframework.cloud.sleuth.instrument.zuul; import org.springframework.cloud.sleuth.Span; import org.springframework.cloud.sleuth.SpanAccessor; -import org.springframework.cloud.sleuth.event.ClientReceivedEvent; -import org.springframework.context.ApplicationEvent; -import org.springframework.context.ApplicationEventPublisher; -import org.springframework.context.ApplicationEventPublisherAware; import com.netflix.zuul.ZuulFilter; @@ -32,20 +28,12 @@ import com.netflix.zuul.ZuulFilter; * * @since 1.0.0 */ -public class TracePostZuulFilter extends ZuulFilter - implements ApplicationEventPublisherAware { +public class TracePostZuulFilter extends ZuulFilter { - private ApplicationEventPublisher publisher; + private final SpanAccessor spanAccessor; - private final SpanAccessor accessor; - - public TracePostZuulFilter(SpanAccessor accessor) { - this.accessor = accessor; - } - - @Override - public void setApplicationEventPublisher(ApplicationEventPublisher publisher) { - this.publisher = publisher; + public TracePostZuulFilter(SpanAccessor spanAccessor) { + this.spanAccessor = spanAccessor; } @Override @@ -56,7 +44,7 @@ public class TracePostZuulFilter extends ZuulFilter @Override public Object run() { // TODO: the client sent event should come from the client not the filter! - publish(new ClientReceivedEvent(this, getCurrentSpan())); + getCurrentSpan().logEvent(Span.CLIENT_RECV); return null; } @@ -70,13 +58,7 @@ public class TracePostZuulFilter extends ZuulFilter return 0; } - private void publish(ApplicationEvent event) { - if (this.publisher != null) { - this.publisher.publishEvent(event); - } - } - private Span getCurrentSpan() { - return this.accessor.getCurrentSpan(); + return this.spanAccessor.getCurrentSpan(); } } diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/zuul/TracePreZuulFilter.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/zuul/TracePreZuulFilter.java index 8c804a865..70147c445 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/zuul/TracePreZuulFilter.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/zuul/TracePreZuulFilter.java @@ -20,10 +20,6 @@ import java.util.Map; import org.springframework.cloud.sleuth.Span; import org.springframework.cloud.sleuth.SpanAccessor; -import org.springframework.cloud.sleuth.event.ClientSentEvent; -import org.springframework.context.ApplicationEvent; -import org.springframework.context.ApplicationEventPublisher; -import org.springframework.context.ApplicationEventPublisherAware; import org.springframework.util.ReflectionUtils; import org.springframework.util.StringUtils; @@ -38,10 +34,7 @@ import com.netflix.zuul.context.RequestContext; * * @since 1.0.0 */ -public class TracePreZuulFilter extends ZuulFilter - implements ApplicationEventPublisherAware { - - private ApplicationEventPublisher publisher; +public class TracePreZuulFilter extends ZuulFilter { private final SpanAccessor accessor; @@ -49,11 +42,6 @@ public class TracePreZuulFilter extends ZuulFilter this.accessor = accessor; } - @Override - public void setApplicationEventPublisher(ApplicationEventPublisher publisher) { - this.publisher = publisher; - } - @Override public boolean shouldFilter() { return true; @@ -78,7 +66,7 @@ public class TracePreZuulFilter extends ZuulFilter setHeader(requestHeaders, Span.PARENT_ID_NAME, getParentId(span)); setHeader(requestHeaders, Span.PROCESS_ID_NAME, span.getProcessId()); // TODO: the client sent event should come from the client not the filter! - publish(new ClientSentEvent(this, span)); + span.logEvent(Span.CLIENT_SEND); } catch (Exception ex) { ReflectionUtils.rethrowRuntimeException(ex); @@ -116,10 +104,4 @@ public class TracePreZuulFilter extends ZuulFilter return 0; } - private void publish(ApplicationEvent event) { - if (this.publisher != null) { - this.publisher.publishEvent(event); - } - } - } diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/zuul/TraceRestClientRibbonCommandFactory.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/zuul/TraceRestClientRibbonCommandFactory.java index a7d040852..a52d55eda 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/zuul/TraceRestClientRibbonCommandFactory.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/zuul/TraceRestClientRibbonCommandFactory.java @@ -27,10 +27,6 @@ import org.springframework.cloud.netflix.zuul.filters.route.RestClientRibbonComm import org.springframework.cloud.netflix.zuul.filters.route.RibbonCommandContext; import org.springframework.cloud.sleuth.Span; import org.springframework.cloud.sleuth.SpanAccessor; -import org.springframework.cloud.sleuth.event.ClientSentEvent; -import org.springframework.context.ApplicationEvent; -import org.springframework.context.ApplicationEventPublisher; -import org.springframework.context.ApplicationEventPublisherAware; import org.springframework.util.MultiValueMap; import com.netflix.client.http.HttpRequest; @@ -43,13 +39,10 @@ import com.netflix.niws.client.http.RestClient; * * @since 1.0.0 */ -public class TraceRestClientRibbonCommandFactory extends RestClientRibbonCommandFactory - implements ApplicationEventPublisherAware { +public class TraceRestClientRibbonCommandFactory extends RestClientRibbonCommandFactory { private static final Log log = LogFactory.getLog(TraceRestClientRibbonCommandFactory.class); - private ApplicationEventPublisher publisher; - private final SpanAccessor accessor; public TraceRestClientRibbonCommandFactory(SpringClientFactory clientFactory, @@ -58,11 +51,6 @@ public class TraceRestClientRibbonCommandFactory extends RestClientRibbonCommand this.accessor = accessor; } - @Override - public void setApplicationEventPublisher(ApplicationEventPublisher publisher) { - this.publisher = publisher; - } - @Override @SuppressWarnings("deprecation") public RestClientRibbonCommand create(RibbonCommandContext context) { @@ -72,7 +60,7 @@ public class TraceRestClientRibbonCommandFactory extends RestClientRibbonCommand return new TraceRestClientRibbonCommand(context.getServiceId(), restClient, getVerb(context.getVerb()), context.getUri(), context.getRetryable(), context.getHeaders(), context.getParams(), context.getRequestEntity(), - this.publisher, this.accessor); + this.accessor); } catch (URISyntaxException e) { log.error("Exception occurred while trying to create the TraceRestClientRibbonCommand", e); @@ -82,8 +70,6 @@ public class TraceRestClientRibbonCommandFactory extends RestClientRibbonCommand class TraceRestClientRibbonCommand extends RestClientRibbonCommand { - private ApplicationEventPublisher publisher; - private final SpanAccessor accessor; @SuppressWarnings("deprecation") @@ -91,11 +77,10 @@ public class TraceRestClientRibbonCommandFactory extends RestClientRibbonCommand HttpRequest.Verb verb, String uri, Boolean retryable, MultiValueMap headers, MultiValueMap params, InputStream requestEntity, - ApplicationEventPublisher publisher, SpanAccessor accessor) + SpanAccessor accessor) throws URISyntaxException { super(commandKey, restClient, verb, uri, retryable, headers, params, requestEntity); - this.publisher = publisher; this.accessor = accessor; } @@ -115,13 +100,7 @@ public class TraceRestClientRibbonCommandFactory extends RestClientRibbonCommand } setHeader(requestBuilder, Span.PROCESS_ID_NAME, span.getProcessId()); - publish(new ClientSentEvent(this, span)); - } - - private void publish(ApplicationEvent event) { - if (this.publisher != null) { - this.publisher.publishEvent(event); - } + span.logEvent(Span.CLIENT_SEND); } private Long getParentId(Span span) { diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/event/SpanAcquiredEvent.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/log/NoOpSpanLogger.java similarity index 63% rename from spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/event/SpanAcquiredEvent.java rename to spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/log/NoOpSpanLogger.java index 7b65d45c1..dda150c2d 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/event/SpanAcquiredEvent.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/log/NoOpSpanLogger.java @@ -14,24 +14,30 @@ * limitations under the License. */ -package org.springframework.cloud.sleuth.event; +package org.springframework.cloud.sleuth.log; import org.springframework.cloud.sleuth.Span; /** - * Event emitted when a parent or a child span was created. + * Logger of Spans that does nothing + * + * @author Marcin Grzejszczak * - * @author Spencer Gibb * @since 1.0.0 */ -@SuppressWarnings("serial") -public class SpanAcquiredEvent extends SpanParentContainingEvent { +public class NoOpSpanLogger implements SpanLogger { + @Override + public void logStartedSpan(Span parent, Span span) { - public SpanAcquiredEvent(Object source, Span span) { - this(source, null, span); } - public SpanAcquiredEvent(Object source, Span parent, Span span) { - super(source, parent, span); + @Override + public void logContinuedSpan(Span span) { + } -} \ No newline at end of file + + @Override + public void logStoppedSpan(Span parent, Span span) { + + } +} diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/log/SleuthLogAutoConfiguration.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/log/SleuthLogAutoConfiguration.java index 8653071e0..d3434e8e3 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/log/SleuthLogAutoConfiguration.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/log/SleuthLogAutoConfiguration.java @@ -21,6 +21,8 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.cloud.sleuth.Tracer; import org.springframework.cloud.sleuth.autoconfig.TraceAutoConfiguration; @@ -29,7 +31,7 @@ import org.springframework.context.annotation.Configuration; /** * {@link org.springframework.boot.autoconfigure.EnableAutoConfiguration Auto-configuration} - * enables a {@link Slf4jSpanListener} that prints tracing information in the logs. + * enables a {@link Slf4jSpanLogger} that prints tracing information in the logs. *

* Note: this is only available for Slf4j * @@ -53,9 +55,22 @@ public class SleuthLogAutoConfiguration { @Bean @ConditionalOnProperty(value = "spring.sleuth.log.slf4j.enabled", matchIfMissing = true) - public Slf4jSpanListener slf4jSpanStartedListener() { + public SpanLogger slf4jSpanLogger() { // Sets up MDC entries X-Trace-Id and X-Span-Id - return new Slf4jSpanListener(this.nameSkipPattern); + return new Slf4jSpanLogger(this.nameSkipPattern); + } + + @Bean + @ConditionalOnProperty(value = "spring.sleuth.log.slf4j.enabled", havingValue = "false") + public SpanLogger noOpSlf4jSpanLogger() { + return new NoOpSpanLogger(); } } + + @Bean + @ConditionalOnMissingClass("org.slf4j.MDC") + @ConditionalOnMissingBean + public SpanLogger defaultLoggedSpansHandler() { + return new NoOpSpanLogger(); + } } diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/log/Slf4jSpanListener.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/log/Slf4jSpanLogger.java similarity index 58% rename from spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/log/Slf4jSpanListener.java rename to spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/log/Slf4jSpanLogger.java index d53778f0e..fb9d79eb0 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/log/Slf4jSpanListener.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/log/Slf4jSpanLogger.java @@ -21,12 +21,6 @@ import java.util.regex.Pattern; import org.slf4j.Logger; import org.slf4j.MDC; import org.springframework.cloud.sleuth.Span; -import org.springframework.cloud.sleuth.event.SpanAcquiredEvent; -import org.springframework.cloud.sleuth.event.SpanContinuedEvent; -import org.springframework.cloud.sleuth.event.SpanReleasedEvent; -import org.springframework.context.event.EventListener; -import org.springframework.core.Ordered; -import org.springframework.core.annotation.Order; /** * Span listener that logs to the console when a span got @@ -36,53 +30,48 @@ import org.springframework.core.annotation.Order; * * @since 1.0.0 */ -public class Slf4jSpanListener { +public class Slf4jSpanLogger implements SpanLogger { private final Logger log; private final Pattern nameSkipPattern; - public Slf4jSpanListener(String nameSkipPattern) { + public Slf4jSpanLogger(String nameSkipPattern) { this.nameSkipPattern = Pattern.compile(nameSkipPattern); this.log = org.slf4j.LoggerFactory - .getLogger(Slf4jSpanListener.class); + .getLogger(Slf4jSpanLogger.class); } - Slf4jSpanListener(String nameSkipPattern, Logger log) { + Slf4jSpanLogger(String nameSkipPattern, Logger log) { this.nameSkipPattern = Pattern.compile(nameSkipPattern); this.log = log; } - @EventListener(SpanAcquiredEvent.class) - @Order(Ordered.LOWEST_PRECEDENCE) - public void start(SpanAcquiredEvent event) { - Span span = event.getSpan(); + @Override + public void logStartedSpan(Span parent, Span span) { MDC.put(Span.SPAN_ID_NAME, Span.idToHex(span.getSpanId())); MDC.put(Span.SPAN_EXPORT_NAME, String.valueOf(span.isExportable())); MDC.put(Span.TRACE_ID_NAME, Span.idToHex(span.getTraceId())); log("Starting span: {}", span); - if (event.getParent() != null) { - log("With parent: {}", event.getParent()); + if (parent != null) { + log("With parent: {}", parent); } } - @EventListener(SpanContinuedEvent.class) - @Order(Ordered.LOWEST_PRECEDENCE) - public void continued(SpanContinuedEvent event) { - Span span = event.getSpan(); + @Override + public void logContinuedSpan(Span span) { MDC.put(Span.SPAN_ID_NAME, Span.idToHex(span.getSpanId())); MDC.put(Span.TRACE_ID_NAME, Span.idToHex(span.getTraceId())); MDC.put(Span.SPAN_EXPORT_NAME, String.valueOf(span.isExportable())); - log("Continued span: {}", event.getSpan()); + log("Continued span: {}", span); } - @EventListener(SpanReleasedEvent.class) - @Order(Ordered.LOWEST_PRECEDENCE) - public void stop(SpanReleasedEvent event) { - log("Stopped span: {}", event.getSpan()); - if (event.getParent() != null) { - log("With parent: {}", event.getParent()); - MDC.put(Span.SPAN_ID_NAME, Span.idToHex(event.getParent().getSpanId())); - MDC.put(Span.SPAN_EXPORT_NAME, String.valueOf(event.getParent().isExportable())); + @Override + public void logStoppedSpan(Span parent, Span span) { + log("Stopped span: {}", span); + if (parent != null) { + log("With parent: {}", parent); + MDC.put(Span.SPAN_ID_NAME, Span.idToHex(parent.getSpanId())); + MDC.put(Span.SPAN_EXPORT_NAME, String.valueOf(parent.isExportable())); } else { MDC.remove(Span.SPAN_ID_NAME); diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/event/ServerReceivedEvent.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/log/SpanLogger.java similarity index 53% rename from spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/event/ServerReceivedEvent.java rename to spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/log/SpanLogger.java index 5c69c37d8..537891270 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/event/ServerReceivedEvent.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/log/SpanLogger.java @@ -14,27 +14,37 @@ * limitations under the License. */ -package org.springframework.cloud.sleuth.event; +package org.springframework.cloud.sleuth.log; import org.springframework.cloud.sleuth.Span; /** - * sr - Server Receive. The server side got the request and will start processing it. - * If one subtracts the cs timestamp from this timestamp one will receive the network latency. + * Contract for implementations responsible for logging Spans + * + * @author Marcin Grzejszczak * - * @author Spencer Gibb * @since 1.0.0 - * - * @see ClientSentEvent */ -@SuppressWarnings("serial") -public class ServerReceivedEvent extends SpanParentContainingEvent { +public interface SpanLogger { - public ServerReceivedEvent(Object source, Span span) { - this(source, null, span); - } + /** + * Logic to run when a Span gets started + * + * @param parent - maybe be nullable + * @param span - current span + */ + void logStartedSpan(Span parent, Span span); - public ServerReceivedEvent(Object source, Span parent, Span span) { - super(source, parent, span); - } + /** + * Logic to run when a Span gets continued + */ + void logContinuedSpan(Span span); + + /** + * Logic to run when a Span gets stopped (closed or detached) + * + * @param parent - maybe be nullable + * @param span - current span + */ + void logStoppedSpan(Span parent, Span span); } diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/metric/CounterServiceBasedSpanReporterService.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/metric/CounterServiceBasedSpanMetricReporter.java similarity index 85% rename from spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/metric/CounterServiceBasedSpanReporterService.java rename to spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/metric/CounterServiceBasedSpanMetricReporter.java index c186ccec5..a4b3253d1 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/metric/CounterServiceBasedSpanReporterService.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/metric/CounterServiceBasedSpanMetricReporter.java @@ -10,12 +10,12 @@ import org.springframework.boot.actuate.metrics.CounterService; * * @since 1.0.0 */ -public class CounterServiceBasedSpanReporterService implements SpanReporterService { +public class CounterServiceBasedSpanMetricReporter implements SpanMetricReporter { private final String acceptedSpansMetricName; private final String droppedSpansMetricName; private final CounterService counterService; - public CounterServiceBasedSpanReporterService(String acceptedSpansMetricName, + public CounterServiceBasedSpanMetricReporter(String acceptedSpansMetricName, String droppedSpansMetricName, CounterService counterService) { this.acceptedSpansMetricName = acceptedSpansMetricName; this.droppedSpansMetricName = droppedSpansMetricName; diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/metric/NoOpSpanReporterService.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/metric/NoOpSpanMetricReporter.java similarity index 65% rename from spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/metric/NoOpSpanReporterService.java rename to spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/metric/NoOpSpanMetricReporter.java index 7ce415c84..08d8649ba 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/metric/NoOpSpanReporterService.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/metric/NoOpSpanMetricReporter.java @@ -1,13 +1,13 @@ package org.springframework.cloud.sleuth.metric; /** - * {@link SpanReporterService} that does nothing + * {@link SpanMetricReporter} that does nothing * * @author Marcin Grzejszczak * * @since 1.0.0 */ -public class NoOpSpanReporterService implements SpanReporterService { +public class NoOpSpanMetricReporter implements SpanMetricReporter { public void incrementAcceptedSpans(long quantity) { diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/metric/SpanReporterService.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/metric/SpanMetricReporter.java similarity index 93% rename from spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/metric/SpanReporterService.java rename to spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/metric/SpanMetricReporter.java index 4ada25e21..734d91a27 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/metric/SpanReporterService.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/metric/SpanMetricReporter.java @@ -7,7 +7,7 @@ package org.springframework.cloud.sleuth.metric; * * @since 1.0.0 */ -public interface SpanReporterService { +public interface SpanMetricReporter { /** * Called when spans are submitted to span collector for processing. diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/metric/TraceMetricsAutoConfiguration.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/metric/TraceMetricsAutoConfiguration.java index bfb473fd8..83635c142 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/metric/TraceMetricsAutoConfiguration.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/metric/TraceMetricsAutoConfiguration.java @@ -47,27 +47,27 @@ public class TraceMetricsAutoConfiguration { @Configuration @ConditionalOnClass(CounterService.class) - @ConditionalOnMissingBean(SpanReporterService.class) + @ConditionalOnMissingBean(SpanMetricReporter.class) protected static class CounterServiceSpanReporterConfig { @Bean @ConditionalOnBean(CounterService.class) - public SpanReporterService spanReporterCounterService(CounterService counterService, + public SpanMetricReporter spanReporterCounterService(CounterService counterService, SleuthMetricProperties sleuthMetricProperties) { - return new CounterServiceBasedSpanReporterService(sleuthMetricProperties.getSpan().getAcceptedName(), + return new CounterServiceBasedSpanMetricReporter(sleuthMetricProperties.getSpan().getAcceptedName(), sleuthMetricProperties.getSpan().getDroppedName(), counterService); } @Bean @ConditionalOnMissingBean(CounterService.class) - public SpanReporterService noOpSpanReporterCounterService() { - return new NoOpSpanReporterService(); + public SpanMetricReporter noOpSpanReporterCounterService() { + return new NoOpSpanMetricReporter(); } } @Bean @ConditionalOnMissingClass("org.springframework.boot.actuate.metrics.CounterService") - @ConditionalOnMissingBean(SpanReporterService.class) - public SpanReporterService noOpSpanReporterCounterService() { - return new NoOpSpanReporterService(); + @ConditionalOnMissingBean(SpanMetricReporter.class) + public SpanMetricReporter noOpSpanReporterCounterService() { + return new NoOpSpanMetricReporter(); } } diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/trace/DefaultTracer.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/trace/DefaultTracer.java index 553d19658..f03f1881b 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/trace/DefaultTracer.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/trace/DefaultTracer.java @@ -22,14 +22,12 @@ import java.util.concurrent.Callable; import org.springframework.cloud.sleuth.Sampler; import org.springframework.cloud.sleuth.Span; import org.springframework.cloud.sleuth.SpanNamer; -import org.springframework.cloud.sleuth.Tracer; -import org.springframework.cloud.sleuth.event.SpanAcquiredEvent; -import org.springframework.cloud.sleuth.event.SpanContinuedEvent; -import org.springframework.cloud.sleuth.event.SpanReleasedEvent; +import org.springframework.cloud.sleuth.SpanReporter; import org.springframework.cloud.sleuth.TraceCallable; import org.springframework.cloud.sleuth.TraceRunnable; +import org.springframework.cloud.sleuth.Tracer; +import org.springframework.cloud.sleuth.log.SpanLogger; import org.springframework.cloud.sleuth.util.ExceptionUtils; -import org.springframework.context.ApplicationEventPublisher; /** * Default implementation of {@link Tracer} @@ -42,18 +40,22 @@ public class DefaultTracer implements Tracer { private final Sampler defaultSampler; - private final ApplicationEventPublisher publisher; - private final Random random; private final SpanNamer spanNamer; + private final SpanLogger spanLogger; + + private final SpanReporter spanReporter; + public DefaultTracer(Sampler defaultSampler, Random random, - ApplicationEventPublisher publisher, SpanNamer spanNamer) { + SpanNamer spanNamer, SpanLogger spanLogger, + SpanReporter spanReporter) { this.defaultSampler = defaultSampler; this.random = random; - this.publisher = publisher; this.spanNamer = spanNamer; + this.spanLogger = spanLogger; + this.spanReporter = spanReporter; } @Override @@ -87,7 +89,7 @@ public class DefaultTracer implements Tracer { span = Span.builder().begin(span.getBegin()).name(name).traceId(id) .spanId(id).exportable(false).build(); } - this.publisher.publishEvent(new SpanAcquiredEvent(this, span)); + this.spanLogger.logStartedSpan(null, span); } return continueSpan(span); } @@ -124,11 +126,13 @@ public class DefaultTracer implements Tracer { else { span.stop(); if (savedSpan != null && span.getParents().contains(savedSpan.getSpanId())) { - this.publisher.publishEvent(new SpanReleasedEvent(this, savedSpan, span)); + this.spanReporter.report(span); + this.spanLogger.logStoppedSpan(savedSpan, span); } else { if (!span.isRemote()) { - this.publisher.publishEvent(new SpanReleasedEvent(this, span)); + this.spanReporter.report(span); + this.spanLogger.logStoppedSpan(null, span); } } SpanContextHolder.close(); @@ -141,7 +145,7 @@ public class DefaultTracer implements Tracer { if (parent == null) { Span span = Span.builder().begin(System.currentTimeMillis()).name(name) .traceId(id).spanId(id).build(); - this.publisher.publishEvent(new SpanAcquiredEvent(this, span)); + this.spanLogger.logStartedSpan(null, span); return span; } else { @@ -152,7 +156,7 @@ public class DefaultTracer implements Tracer { .traceId(parent.getTraceId()).parent(parent.getSpanId()).spanId(id) .processId(parent.getProcessId()).savedSpan(parent) .exportable(parent.isExportable()).build(); - this.publisher.publishEvent(new SpanAcquiredEvent(this, parent, span)); + this.spanLogger.logStartedSpan(parent, span); return span; } } @@ -164,7 +168,7 @@ public class DefaultTracer implements Tracer { @Override public Span continueSpan(Span span) { if (span != null) { - this.publisher.publishEvent(new SpanContinuedEvent(this, span)); + this.spanLogger.logContinuedSpan(span); } else { return null; } diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/event/ArrayListSpanAccumulator.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/util/ArrayListSpanAccumulator.java similarity index 79% rename from spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/event/ArrayListSpanAccumulator.java rename to spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/util/ArrayListSpanAccumulator.java index 1b5d07ef8..daf1f7bc4 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/event/ArrayListSpanAccumulator.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/util/ArrayListSpanAccumulator.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package org.springframework.cloud.sleuth.event; +package org.springframework.cloud.sleuth.util; import java.util.ArrayList; import java.util.List; import org.springframework.cloud.sleuth.Span; -import org.springframework.context.ApplicationListener; +import org.springframework.cloud.sleuth.SpanReporter; /** * Accumulator of {@link org.springframework.cloud.sleuth.Tracer#close(Span) @@ -29,14 +29,9 @@ import org.springframework.context.ApplicationListener; * @author Spencer Gibb * @since 1.0.0 */ -public class ArrayListSpanAccumulator implements ApplicationListener { +public class ArrayListSpanAccumulator implements SpanReporter { private final List spans = new ArrayList<>(); - @Override - public void onApplicationEvent(SpanReleasedEvent event) { - this.spans.add(event.getSpan()); - } - public List getSpans() { return this.spans; } @@ -47,4 +42,9 @@ public class ArrayListSpanAccumulator implements ApplicationListener callable = new Callable() { diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/TraceCallableTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/TraceCallableTests.java index 5a45497c7..328a1b63e 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/TraceCallableTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/TraceCallableTests.java @@ -8,17 +8,17 @@ import java.util.concurrent.Executors; import org.junit.After; import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.Mockito; import org.mockito.runners.MockitoJUnitRunner; import org.springframework.cloud.sleuth.DefaultSpanNamer; +import org.springframework.cloud.sleuth.NoOpSpanReporter; import org.springframework.cloud.sleuth.Span; import org.springframework.cloud.sleuth.SpanName; import org.springframework.cloud.sleuth.TraceCallable; import org.springframework.cloud.sleuth.Tracer; +import org.springframework.cloud.sleuth.log.NoOpSpanLogger; import org.springframework.cloud.sleuth.sampler.AlwaysSampler; import org.springframework.cloud.sleuth.trace.DefaultTracer; import org.springframework.cloud.sleuth.trace.TestSpanContextHolder; -import org.springframework.context.ApplicationEventPublisher; import static org.springframework.cloud.sleuth.assertions.SleuthAssertions.then; @@ -27,7 +27,8 @@ public class TraceCallableTests { ExecutorService executor = Executors.newSingleThreadExecutor(); Tracer tracer = new DefaultTracer(new AlwaysSampler(), - new Random(), Mockito.mock(ApplicationEventPublisher.class), new DefaultSpanNamer()); + new Random(), new DefaultSpanNamer(), + new NoOpSpanLogger(), new NoOpSpanReporter()); @After public void clean() { diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/TraceRunnableTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/TraceRunnableTests.java index 583b66245..c4da6d66f 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/TraceRunnableTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/TraceRunnableTests.java @@ -8,17 +8,17 @@ import java.util.concurrent.atomic.AtomicReference; import org.junit.After; import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.Mockito; import org.mockito.runners.MockitoJUnitRunner; import org.springframework.cloud.sleuth.DefaultSpanNamer; +import org.springframework.cloud.sleuth.NoOpSpanReporter; import org.springframework.cloud.sleuth.Span; import org.springframework.cloud.sleuth.SpanName; import org.springframework.cloud.sleuth.TraceRunnable; import org.springframework.cloud.sleuth.Tracer; +import org.springframework.cloud.sleuth.log.NoOpSpanLogger; import org.springframework.cloud.sleuth.sampler.AlwaysSampler; import org.springframework.cloud.sleuth.trace.DefaultTracer; import org.springframework.cloud.sleuth.trace.TestSpanContextHolder; -import org.springframework.context.ApplicationEventPublisher; import static org.springframework.cloud.sleuth.assertions.SleuthAssertions.then; @@ -27,7 +27,8 @@ public class TraceRunnableTests { ExecutorService executor = Executors.newSingleThreadExecutor(); Tracer tracer = new DefaultTracer(new AlwaysSampler(), - new Random(), Mockito.mock(ApplicationEventPublisher.class), new DefaultSpanNamer()); + new Random(), new DefaultSpanNamer(), + new NoOpSpanLogger(), new NoOpSpanReporter()); @After public void cleanup() { diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/TraceableExecutorServiceTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/TraceableExecutorServiceTests.java index d4d6a1308..c74d4f770 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/TraceableExecutorServiceTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/TraceableExecutorServiceTests.java @@ -15,14 +15,15 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; +import org.springframework.cloud.sleuth.NoOpSpanReporter; import org.springframework.cloud.sleuth.Span; import org.springframework.cloud.sleuth.SpanNamer; -import org.springframework.cloud.sleuth.Tracer; import org.springframework.cloud.sleuth.TraceKeys; +import org.springframework.cloud.sleuth.Tracer; +import org.springframework.cloud.sleuth.log.NoOpSpanLogger; import org.springframework.cloud.sleuth.sampler.AlwaysSampler; import org.springframework.cloud.sleuth.trace.DefaultTracer; import org.springframework.cloud.sleuth.trace.TestSpanContextHolder; -import org.springframework.context.ApplicationEventPublisher; import static java.util.stream.Collectors.toList; import static org.assertj.core.api.BDDAssertions.then; @@ -31,7 +32,6 @@ import static org.assertj.core.api.BDDAssertions.then; public class TraceableExecutorServiceTests { private static int TOTAL_THREADS = 10; - @Mock ApplicationEventPublisher publisher; @Mock SpanNamer spanNamer; Tracer tracer; ExecutorService executorService = Executors.newFixedThreadPool(3); @@ -40,8 +40,8 @@ public class TraceableExecutorServiceTests { @Before public void setup() { - this.tracer = new DefaultTracer(new AlwaysSampler(), new Random(), this.publisher, - this.spanNamer); + this.tracer = new DefaultTracer(new AlwaysSampler(), new Random(), + this.spanNamer, new NoOpSpanLogger(), new NoOpSpanReporter()); this.traceManagerableExecutorService = new TraceableExecutorService(this.executorService, this.tracer, new TraceKeys(), this.spanNamer); TestSpanContextHolder.removeCurrentSpan(); diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/hystrix/TraceCommandTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/hystrix/TraceCommandTests.java index aa6d92bd9..909b61d81 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/hystrix/TraceCommandTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/hystrix/TraceCommandTests.java @@ -5,15 +5,15 @@ import java.util.Random; import org.junit.After; import org.junit.Before; import org.junit.Test; -import org.mockito.Mockito; import org.springframework.cloud.sleuth.DefaultSpanNamer; +import org.springframework.cloud.sleuth.NoOpSpanReporter; import org.springframework.cloud.sleuth.Span; import org.springframework.cloud.sleuth.TraceKeys; import org.springframework.cloud.sleuth.Tracer; +import org.springframework.cloud.sleuth.log.NoOpSpanLogger; import org.springframework.cloud.sleuth.sampler.AlwaysSampler; import org.springframework.cloud.sleuth.trace.DefaultTracer; import org.springframework.cloud.sleuth.trace.TestSpanContextHolder; -import org.springframework.context.ApplicationEventPublisher; import com.netflix.hystrix.HystrixCommand; import com.netflix.hystrix.HystrixCommandGroupKey; @@ -31,7 +31,7 @@ public class TraceCommandTests { static final long EXPECTED_TRACE_ID = 1L; Tracer tracer = new DefaultTracer(new AlwaysSampler(), new Random(), - Mockito.mock(ApplicationEventPublisher.class), new DefaultSpanNamer()); + new DefaultSpanNamer(), new NoOpSpanLogger(), new NoOpSpanReporter()); @Before public void setup() { @@ -85,7 +85,7 @@ public class TraceCommandTests { @Test public void should_pass_tracing_information_when_using_Hystrix_commands() { Tracer tracer = new DefaultTracer(new AlwaysSampler(), new Random(), - Mockito.mock(ApplicationEventPublisher.class), new DefaultSpanNamer()); + new DefaultSpanNamer(), new NoOpSpanLogger(), new NoOpSpanReporter()); TraceKeys traceKeys = new TraceKeys(); HystrixCommand.Setter setter = HystrixCommand.Setter .withGroupKey(HystrixCommandGroupKey.Factory.asKey("group")) diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/TraceChannelInterceptorTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/TraceChannelInterceptorTests.java index 12dde98d2..f8deb754a 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/TraceChannelInterceptorTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/TraceChannelInterceptorTests.java @@ -16,9 +16,6 @@ package org.springframework.cloud.sleuth.instrument.messaging; -import java.util.ArrayList; -import java.util.List; - import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -30,13 +27,12 @@ import org.springframework.boot.test.IntegrationTest; import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.cloud.sleuth.Span; import org.springframework.cloud.sleuth.Tracer; -import org.springframework.cloud.sleuth.event.SpanReleasedEvent; +import org.springframework.cloud.sleuth.util.ArrayListSpanAccumulator; import org.springframework.cloud.sleuth.instrument.messaging.TraceChannelInterceptorTests.App; import org.springframework.cloud.sleuth.sampler.AlwaysSampler; import org.springframework.cloud.sleuth.trace.TestSpanContextHolder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.context.event.EventListener; import org.springframework.integration.channel.DirectChannel; import org.springframework.integration.core.MessagingTemplate; import org.springframework.integration.support.MessageBuilder; @@ -72,7 +68,7 @@ public class TraceChannelInterceptorTests implements MessageHandler { private MessagingTemplate messagingTemplate; @Autowired - private App app; + private ArrayListSpanAccumulator accumulator; private Message message; @@ -120,7 +116,7 @@ public class TraceChannelInterceptorTests implements MessageHandler { .hexToId(this.message.getHeaders().get(Span.TRACE_ID_NAME, String.class)); then(traceId).isEqualTo(10L); then(spanId).isNotEqualTo(20L); - assertEquals(1, this.app.events.size()); + assertEquals(1, this.accumulator.getSpans().size()); } @Test @@ -171,11 +167,9 @@ public class TraceChannelInterceptorTests implements MessageHandler { @EnableAutoConfiguration static class App { - private List events = new ArrayList<>(); - - @EventListener - public void handle(SpanReleasedEvent event) { - this.events.add(event); + @Bean + ArrayListSpanAccumulator arrayListSpanAccumulator() { + return new ArrayListSpanAccumulator(); } @Bean diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceFilterAlwaysSamplerIntegrationTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceFilterAlwaysSamplerIntegrationTests.java index a524d4d39..1c360ee55 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceFilterAlwaysSamplerIntegrationTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceFilterAlwaysSamplerIntegrationTests.java @@ -10,6 +10,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.SpringApplicationConfiguration; +import org.springframework.cloud.sleuth.NoOpSpanReporter; import org.springframework.cloud.sleuth.Span; import org.springframework.cloud.sleuth.Tracer; import org.springframework.cloud.sleuth.instrument.DefaultTestAutoConfiguration; @@ -74,7 +75,8 @@ public class TraceFilterAlwaysSamplerIntegrationTests extends AbstractMvcIntegra @Override protected void configureMockMvcBuilder(DefaultMockMvcBuilder mockMvcBuilder) { - mockMvcBuilder.addFilters(new TraceFilter(this.tracer, this.traceKeys)); + mockMvcBuilder.addFilters(new TraceFilter(this.tracer, this.traceKeys, + new NoOpSpanReporter())); } private MvcResult whenSentPingWithTraceIdAndNotSampling(Long traceId) diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceFilterMockChainIntegrationTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceFilterMockChainIntegrationTests.java index 877366978..77458441d 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceFilterMockChainIntegrationTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceFilterMockChainIntegrationTests.java @@ -21,13 +21,14 @@ import java.util.Random; import org.junit.Before; import org.junit.Test; import org.springframework.cloud.sleuth.DefaultSpanNamer; +import org.springframework.cloud.sleuth.NoOpSpanReporter; import org.springframework.cloud.sleuth.Span; -import org.springframework.cloud.sleuth.Tracer; import org.springframework.cloud.sleuth.TraceKeys; +import org.springframework.cloud.sleuth.Tracer; +import org.springframework.cloud.sleuth.log.NoOpSpanLogger; import org.springframework.cloud.sleuth.sampler.AlwaysSampler; import org.springframework.cloud.sleuth.trace.DefaultTracer; import org.springframework.cloud.sleuth.trace.TestSpanContextHolder; -import org.springframework.context.support.StaticApplicationContext; import org.springframework.http.MediaType; import org.springframework.mock.web.MockFilterChain; import org.springframework.mock.web.MockHttpServletRequest; @@ -44,10 +45,9 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilder */ public class TraceFilterMockChainIntegrationTests { - private StaticApplicationContext context = new StaticApplicationContext(); - private Tracer tracer = new DefaultTracer(new AlwaysSampler(), - new Random(), this.context, new DefaultSpanNamer()); + new Random(), new DefaultSpanNamer(), + new NoOpSpanLogger(), new NoOpSpanReporter()); private TraceKeys traceKeys = new TraceKeys(); private MockHttpServletRequest request; @@ -57,7 +57,6 @@ public class TraceFilterMockChainIntegrationTests { @Before public void init() { TestSpanContextHolder.removeCurrentSpan(); - this.context.refresh(); this.request = builder().buildRequest(new MockServletContext()); this.response = new MockHttpServletResponse(); this.response.setContentType(MediaType.APPLICATION_JSON_VALUE); @@ -71,7 +70,7 @@ public class TraceFilterMockChainIntegrationTests { @Test public void startsNewTrace() throws Exception { - TraceFilter filter = new TraceFilter(this.tracer, this.traceKeys); + TraceFilter filter = new TraceFilter(this.tracer, this.traceKeys, new NoOpSpanReporter()); filter.doFilter(this.request, this.response, this.filterChain); assertNull(TestSpanContextHolder.getCurrentSpan()); } @@ -81,7 +80,7 @@ public class TraceFilterMockChainIntegrationTests { Random generator = new Random(); this.request = builder().header(Span.SPAN_ID_NAME, generator.nextLong()) .header(Span.TRACE_ID_NAME, generator.nextLong()).buildRequest(new MockServletContext()); - TraceFilter filter = new TraceFilter(this.tracer, this.traceKeys); + TraceFilter filter = new TraceFilter(this.tracer, this.traceKeys, new NoOpSpanReporter()); filter.doFilter(this.request, this.response, this.filterChain); assertNull(TestSpanContextHolder.getCurrentSpan()); } diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceFilterTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceFilterTests.java index a9c9b5b1e..188b1bce0 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceFilterTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceFilterTests.java @@ -24,13 +24,14 @@ import org.mockito.Mock; import org.springframework.cloud.sleuth.DefaultSpanNamer; import org.springframework.cloud.sleuth.Sampler; import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.SpanReporter; import org.springframework.cloud.sleuth.Tracer; import org.springframework.cloud.sleuth.TraceKeys; +import org.springframework.cloud.sleuth.log.SpanLogger; import org.springframework.cloud.sleuth.sampler.AlwaysSampler; import org.springframework.cloud.sleuth.sampler.NeverSampler; import org.springframework.cloud.sleuth.trace.DefaultTracer; import org.springframework.cloud.sleuth.trace.TestSpanContextHolder; -import org.springframework.context.ApplicationEventPublisher; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.mock.web.MockFilterChain; @@ -52,8 +53,8 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilder */ public class TraceFilterTests { - @Mock - private ApplicationEventPublisher publisher; + @Mock SpanLogger spanLogger; + @Mock SpanReporter spanReporter; private Tracer tracer; private TraceKeys traceKeys = new TraceKeys(); @@ -69,7 +70,7 @@ public class TraceFilterTests { public void init() { initMocks(this); this.tracer = new DefaultTracer(new DelegateSampler(), new Random(), - this.publisher, new DefaultSpanNamer()) { + new DefaultSpanNamer(), this.spanLogger, this.spanReporter) { @Override public Span continueSpan(Span span) { TraceFilterTests.this.span = super.continueSpan(span); @@ -90,7 +91,7 @@ public class TraceFilterTests { @Test public void notTraced() throws Exception { this.sampler = NeverSampler.INSTANCE; - TraceFilter filter = new TraceFilter(this.tracer, this.traceKeys); + TraceFilter filter = new TraceFilter(this.tracer, this.traceKeys, spanReporter); this.request = get("/favicon.ico").accept(MediaType.ALL) .buildRequest(new MockServletContext()); @@ -103,7 +104,7 @@ public class TraceFilterTests { @Test public void startsNewTrace() throws Exception { - TraceFilter filter = new TraceFilter(this.tracer, this.traceKeys); + TraceFilter filter = new TraceFilter(this.tracer, this.traceKeys, spanReporter); filter.doFilter(this.request, this.response, this.filterChain); verifyHttpTags(); assertNull(TestSpanContextHolder.getCurrentSpan()); @@ -116,7 +117,7 @@ public class TraceFilterTests { .header(Span.TRACE_ID_NAME, Span.idToHex(2L)) .header(Span.PARENT_ID_NAME, Span.idToHex(3L)) .buildRequest(new MockServletContext()); - TraceFilter filter = new TraceFilter(this.tracer, this.traceKeys); + TraceFilter filter = new TraceFilter(this.tracer, this.traceKeys, spanReporter); filter.doFilter(this.request, this.response, this.filterChain); @@ -132,7 +133,7 @@ public class TraceFilterTests { // It should have been removed from the thread local context so simulate that TestSpanContextHolder.removeCurrentSpan(); - TraceFilter filter = new TraceFilter(this.tracer, this.traceKeys); + TraceFilter filter = new TraceFilter(this.tracer, this.traceKeys, spanReporter); filter.doFilter(this.request, this.response, this.filterChain); verifyHttpTags(); @@ -145,7 +146,7 @@ public class TraceFilterTests { this.request = builder().header(Span.SPAN_ID_NAME, 10L) .header(Span.TRACE_ID_NAME, 20L).buildRequest(new MockServletContext()); - TraceFilter filter = new TraceFilter(this.tracer, this.traceKeys); + TraceFilter filter = new TraceFilter(this.tracer, this.traceKeys, spanReporter); filter.doFilter(this.request, this.response, this.filterChain); verifyHttpTags(); @@ -159,7 +160,7 @@ public class TraceFilterTests { .header(Span.TRACE_ID_NAME, 20L).buildRequest(new MockServletContext()); this.traceKeys.getHttp().getHeaders().add("x-foo"); - TraceFilter filter = new TraceFilter(this.tracer, this.traceKeys); + TraceFilter filter = new TraceFilter(this.tracer, this.traceKeys, spanReporter); this.request.addHeader("X-Foo", "bar"); filter.doFilter(this.request, this.response, this.filterChain); @@ -174,7 +175,7 @@ public class TraceFilterTests { .header(Span.TRACE_ID_NAME, 20L).buildRequest(new MockServletContext()); this.traceKeys.getHttp().getHeaders().add("x-foo"); - TraceFilter filter = new TraceFilter(this.tracer, this.traceKeys); + TraceFilter filter = new TraceFilter(this.tracer, this.traceKeys, spanReporter); this.request.addHeader("X-Foo", "bar"); this.request.addHeader("X-Foo", "spam"); filter.doFilter(this.request, this.response, this.filterChain); @@ -186,7 +187,7 @@ public class TraceFilterTests { @Test public void catchesException() throws Exception { - TraceFilter filter = new TraceFilter(this.tracer, this.traceKeys); + TraceFilter filter = new TraceFilter(this.tracer, this.traceKeys, spanReporter); this.filterChain = new MockFilterChain() { @Override public void doFilter(javax.servlet.ServletRequest request, diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceAsyncListenableTaskExecutorTest.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceAsyncListenableTaskExecutorTest.java index 5466a3de8..eadf81b78 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceAsyncListenableTaskExecutorTest.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceAsyncListenableTaskExecutorTest.java @@ -22,12 +22,13 @@ import java.util.concurrent.Callable; import org.junit.Test; import org.mockito.BDDMockito; import org.springframework.cloud.sleuth.DefaultSpanNamer; +import org.springframework.cloud.sleuth.NoOpSpanReporter; import org.springframework.cloud.sleuth.TraceCallable; import org.springframework.cloud.sleuth.TraceRunnable; import org.springframework.cloud.sleuth.Tracer; +import org.springframework.cloud.sleuth.log.NoOpSpanLogger; import org.springframework.cloud.sleuth.sampler.AlwaysSampler; import org.springframework.cloud.sleuth.trace.DefaultTracer; -import org.springframework.context.ApplicationEventPublisher; import org.springframework.core.task.AsyncListenableTaskExecutor; import static org.hamcrest.Matchers.instanceOf; @@ -39,9 +40,8 @@ import static org.mockito.BDDMockito.mock; public class TraceAsyncListenableTaskExecutorTest { AsyncListenableTaskExecutor delegate = mock(AsyncListenableTaskExecutor.class); - ApplicationEventPublisher publisher = mock(ApplicationEventPublisher.class); Tracer tracer = new DefaultTracer(new AlwaysSampler(), new Random(), - this.publisher, new DefaultSpanNamer()) { + new DefaultSpanNamer(), new NoOpSpanLogger(), new NoOpSpanReporter()) { @Override public boolean isTracing() { return true; } diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRestTemplateInterceptorIntegrationTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRestTemplateInterceptorIntegrationTests.java index df15096b5..8992cb46b 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRestTemplateInterceptorIntegrationTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRestTemplateInterceptorIntegrationTests.java @@ -27,12 +27,13 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.springframework.cloud.sleuth.DefaultSpanNamer; +import org.springframework.cloud.sleuth.NoOpSpanReporter; import org.springframework.cloud.sleuth.Span; import org.springframework.cloud.sleuth.assertions.SleuthAssertions; +import org.springframework.cloud.sleuth.log.NoOpSpanLogger; import org.springframework.cloud.sleuth.sampler.AlwaysSampler; import org.springframework.cloud.sleuth.trace.DefaultTracer; import org.springframework.cloud.sleuth.trace.TestSpanContextHolder; -import org.springframework.context.support.StaticApplicationContext; import org.springframework.http.client.ClientHttpRequestFactory; import org.springframework.http.client.ClientHttpRequestInterceptor; import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; @@ -53,13 +54,10 @@ public class TraceRestTemplateInterceptorIntegrationTests { private DefaultTracer tracer; - private StaticApplicationContext publisher = new StaticApplicationContext(); - @Before public void setup() { - this.publisher.refresh(); - this.tracer = new DefaultTracer(new AlwaysSampler(), new Random(), this.publisher, - new DefaultSpanNamer()); + this.tracer = new DefaultTracer(new AlwaysSampler(), new Random(), + new DefaultSpanNamer(), new NoOpSpanLogger(), new NoOpSpanReporter()); this.template.setInterceptors(Arrays.asList( new TraceRestTemplateInterceptor(this.tracer))); TestSpanContextHolder.removeCurrentSpan(); diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRestTemplateInterceptorTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRestTemplateInterceptorTests.java index ee1e6b202..d105dcc9f 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRestTemplateInterceptorTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRestTemplateInterceptorTests.java @@ -26,11 +26,12 @@ import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.springframework.cloud.sleuth.DefaultSpanNamer; +import org.springframework.cloud.sleuth.NoOpSpanReporter; import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.log.NoOpSpanLogger; import org.springframework.cloud.sleuth.sampler.AlwaysSampler; import org.springframework.cloud.sleuth.trace.DefaultTracer; import org.springframework.cloud.sleuth.trace.TestSpanContextHolder; -import org.springframework.context.support.StaticApplicationContext; import org.springframework.http.HttpHeaders; import org.springframework.http.client.ClientHttpRequestInterceptor; import org.springframework.test.web.client.MockMvcClientHttpRequestFactory; @@ -59,13 +60,10 @@ public class TraceRestTemplateInterceptorTests { private DefaultTracer tracer; - private StaticApplicationContext publisher = new StaticApplicationContext(); - @Before public void setup() { - this.publisher.refresh(); - this.tracer = new DefaultTracer(new AlwaysSampler(), new Random(), this.publisher, - new DefaultSpanNamer()); + this.tracer = new DefaultTracer(new AlwaysSampler(), new Random(), + new DefaultSpanNamer(), new NoOpSpanLogger(), new NoOpSpanReporter()); this.template.setInterceptors(Arrays.asList( new TraceRestTemplateInterceptor(this.tracer))); TestSpanContextHolder.removeCurrentSpan(); diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/WebClientTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/WebClientTests.java index b5880bc6e..a067199c4 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/WebClientTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/WebClientTests.java @@ -38,14 +38,11 @@ import org.springframework.cloud.netflix.feign.EnableFeignClients; import org.springframework.cloud.netflix.feign.FeignClient; import org.springframework.cloud.netflix.ribbon.RibbonClient; import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.SpanReporter; import org.springframework.cloud.sleuth.Tracer; -import org.springframework.cloud.sleuth.event.ClientReceivedEvent; -import org.springframework.cloud.sleuth.event.ClientSentEvent; import org.springframework.cloud.sleuth.trace.TestSpanContextHolder; -import org.springframework.context.ApplicationEvent; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.context.event.EventListener; import org.springframework.http.HttpHeaders; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Component; @@ -65,7 +62,7 @@ import junitparams.JUnitParamsRunner; import junitparams.Parameters; import static junitparams.JUnitParamsRunner.$; -import static org.assertj.core.api.BDDAssertions.then; +import static org.springframework.cloud.sleuth.assertions.SleuthAssertions.then; @RunWith(JUnitParamsRunner.class) @SpringApplicationConfiguration(classes = { WebClientTests.TestConfiguration.class }) @@ -137,7 +134,17 @@ public class WebClientTests { then(Span.hexToId(getHeader(response, Span.TRACE_ID_NAME))) .isEqualTo(currentTraceId); - thenRegisteredClientSentAndReceivedEvents(); + thenRegisteredClientSentAndReceivedEvents(spanWithClientEvents()); + } + + private Span spanWithClientEvents() { + return this.listener.getEvents() + .stream() + .filter(span -> span.logs() + .stream() + .filter(log -> log.getEvent().contains(Span.CLIENT_RECV) || log.getEvent().contains(Span.CLIENT_SEND)) + .findFirst().isPresent()) + .findFirst().get(); } private Object[] parametersForShouldAttachTraceIdWhenCallingAnotherService() { @@ -158,8 +165,8 @@ public class WebClientTests { provider.get(this); - thenRegisteredClientSentAndReceivedEvents(); then(this.tracer.getCurrentSpan()).isEqualTo(span); + thenRegisteredClientSentAndReceivedEvents(spanWithClientEvents()); } private Object[] parametersForShouldAttachTraceIdWhenUsingFeignClientWithoutResponseBody() { @@ -167,10 +174,9 @@ public class WebClientTests { (ResponseEntityProvider) (tests) -> tests.template.getForEntity("http://fooservice/noresponse", String.class)); } - private void thenRegisteredClientSentAndReceivedEvents() { - then(this.listener.getEvents().size()).isEqualTo(2); - then(this.listener.getEvents().get(0)).isExactlyInstanceOf(ClientSentEvent.class); - then(this.listener.getEvents().get(1)).isExactlyInstanceOf(ClientReceivedEvent.class); + private void thenRegisteredClientSentAndReceivedEvents(Span span) { + then(span).hasLoggedAnEvent(Span.CLIENT_RECV); + then(span).hasLoggedAnEvent(Span.CLIENT_SEND); } private Long generatedId() { @@ -221,27 +227,24 @@ public class WebClientTests { } @Component - public static class Listener { - private List events = new ArrayList<>(); + public static class Listener implements SpanReporter { + private List events = new ArrayList<>(); - @EventListener(ClientSentEvent.class) - public void sent(ClientSentEvent event) { - this.events.add(event); - } - - @EventListener(ClientReceivedEvent.class) - public void received(ClientReceivedEvent event) { - this.events.add(event); - } - - public List getEvents() { + public List getEvents() { return this.events; } + + @Override + public void report(Span span) { + this.events.add(span); + } } @RestController public static class FooController { + @Autowired Tracer tracer; + @RequestMapping(value = "/notrace", method = RequestMethod.GET) public String notrace( @RequestHeader(name = Span.TRACE_ID_NAME, required = false) String traceId) { diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/common/AbstractMvcWiremockIntegrationTest.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/common/AbstractMvcWiremockIntegrationTest.java index eef32bcd3..52ecf4d53 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/common/AbstractMvcWiremockIntegrationTest.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/common/AbstractMvcWiremockIntegrationTest.java @@ -2,9 +2,11 @@ package org.springframework.cloud.sleuth.instrument.web.common; import org.junit.Before; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cloud.sleuth.NoOpSpanReporter; import org.springframework.cloud.sleuth.Tracer; import org.springframework.cloud.sleuth.TraceKeys; import org.springframework.cloud.sleuth.instrument.web.TraceFilter; +import org.springframework.cloud.sleuth.log.NoOpSpanLogger; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.web.servlet.setup.DefaultMockMvcBuilder; @@ -53,6 +55,7 @@ public abstract class AbstractMvcWiremockIntegrationTest extends AbstractMvcInte @Override protected void configureMockMvcBuilder(DefaultMockMvcBuilder mockMvcBuilder) { - mockMvcBuilder.addFilters(new TraceFilter(this.tracer, this.traceKeys)); + mockMvcBuilder.addFilters(new TraceFilter(this.tracer, this.traceKeys, + new NoOpSpanReporter())); } } diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/multiple/MultipleHopsIntegrationTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/multiple/MultipleHopsIntegrationTests.java index c4659aa2c..69a4b4c7c 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/multiple/MultipleHopsIntegrationTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/multiple/MultipleHopsIntegrationTests.java @@ -6,8 +6,9 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.sleuth.Sampler; import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.SpanReporter; import org.springframework.cloud.sleuth.Tracer; -import org.springframework.cloud.sleuth.event.ArrayListSpanAccumulator; +import org.springframework.cloud.sleuth.util.ArrayListSpanAccumulator; import org.springframework.cloud.sleuth.TraceKeys; import org.springframework.cloud.sleuth.instrument.web.TraceFilter; import org.springframework.cloud.sleuth.instrument.web.common.AbstractMvcIntegrationTest; @@ -32,10 +33,12 @@ public class MultipleHopsIntegrationTests extends AbstractMvcIntegrationTest { @Autowired Tracer tracer; @Autowired TraceKeys traceKeys; @Autowired ArrayListSpanAccumulator arrayListSpanAccumulator; + @Autowired SpanReporter spanReporter; @Override protected void configureMockMvcBuilder(DefaultMockMvcBuilder mockMvcBuilder) { - mockMvcBuilder.addFilters(new TraceFilter(this.tracer, this.traceKeys)); + mockMvcBuilder.addFilters(new TraceFilter(this.tracer, this.traceKeys, + this.spanReporter)); } @Test diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/zuul/TracePostZuulFilterTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/zuul/TracePostZuulFilterTests.java index 49e59d806..01238c71f 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/zuul/TracePostZuulFilterTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/zuul/TracePostZuulFilterTests.java @@ -18,20 +18,20 @@ package org.springframework.cloud.sleuth.instrument.zuul; import java.util.Random; -import com.netflix.zuul.context.RequestContext; import org.junit.After; import org.junit.Before; import org.junit.Test; -import org.mockito.Mockito; import org.springframework.cloud.sleuth.DefaultSpanNamer; -import org.springframework.cloud.sleuth.event.ClientReceivedEvent; +import org.springframework.cloud.sleuth.NoOpSpanReporter; +import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.log.NoOpSpanLogger; import org.springframework.cloud.sleuth.sampler.AlwaysSampler; import org.springframework.cloud.sleuth.trace.DefaultTracer; import org.springframework.cloud.sleuth.trace.TestSpanContextHolder; -import org.springframework.context.ApplicationEventPublisher; -import static org.mockito.Matchers.isA; -import static org.mockito.Mockito.verify; +import com.netflix.zuul.context.RequestContext; + +import static org.springframework.cloud.sleuth.assertions.SleuthAssertions.then; /** * @author Dave Syer @@ -39,11 +39,8 @@ import static org.mockito.Mockito.verify; */ public class TracePostZuulFilterTests { - private ApplicationEventPublisher publisher = Mockito.mock(ApplicationEventPublisher.class); - private DefaultTracer tracer = new DefaultTracer(new AlwaysSampler(), - new Random(), Mockito.mock(ApplicationEventPublisher.class), - new DefaultSpanNamer()); + new Random(), new DefaultSpanNamer(), new NoOpSpanLogger(), new NoOpSpanReporter()); private TracePostZuulFilter filter = new TracePostZuulFilter(this.tracer); @@ -56,9 +53,9 @@ public class TracePostZuulFilterTests { @Test public void filterPublishesEvent() throws Exception { - this.filter.setApplicationEventPublisher(this.publisher); - this.tracer.createSpan("http:start"); + Span span = this.tracer.createSpan("http:start"); this.filter.run(); - verify(this.publisher).publishEvent(isA(ClientReceivedEvent.class)); + + then(span).hasLoggedAnEvent(Span.CLIENT_RECV); } } diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/zuul/TracePreZuulFilterTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/zuul/TracePreZuulFilterTests.java index 4c8a1b591..ebbcca0ca 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/zuul/TracePreZuulFilterTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/zuul/TracePreZuulFilterTests.java @@ -18,18 +18,19 @@ package org.springframework.cloud.sleuth.instrument.zuul; import java.util.Random; -import com.netflix.zuul.context.RequestContext; import org.junit.After; import org.junit.Before; import org.junit.Test; -import org.mockito.Mockito; import org.springframework.cloud.sleuth.DefaultSpanNamer; +import org.springframework.cloud.sleuth.NoOpSpanReporter; import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.log.NoOpSpanLogger; import org.springframework.cloud.sleuth.sampler.AlwaysSampler; import org.springframework.cloud.sleuth.sampler.NeverSampler; import org.springframework.cloud.sleuth.trace.DefaultTracer; import org.springframework.cloud.sleuth.trace.TestSpanContextHolder; -import org.springframework.context.ApplicationEventPublisher; + +import com.netflix.zuul.context.RequestContext; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.notNullValue; @@ -42,11 +43,8 @@ import static org.junit.Assert.assertThat; */ public class TracePreZuulFilterTests { - private ApplicationEventPublisher publisher = Mockito - .mock(ApplicationEventPublisher.class); - private DefaultTracer tracer = new DefaultTracer(new AlwaysSampler(), new Random(), - this.publisher, new DefaultSpanNamer()); + new DefaultSpanNamer(), new NoOpSpanLogger(), new NoOpSpanReporter()); private TracePreZuulFilter filter = new TracePreZuulFilter(this.tracer); diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/zuul/TraceRestClientRibbonCommandFactoryTest.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/zuul/TraceRestClientRibbonCommandFactoryTest.java index 4bd3d17d7..f19d76dcb 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/zuul/TraceRestClientRibbonCommandFactoryTest.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/zuul/TraceRestClientRibbonCommandFactoryTest.java @@ -26,7 +26,6 @@ import org.springframework.cloud.netflix.zuul.filters.route.RestClientRibbonComm import org.springframework.cloud.netflix.zuul.filters.route.RibbonCommandContext; import org.springframework.cloud.sleuth.Span; import org.springframework.cloud.sleuth.SpanAccessor; -import org.springframework.context.ApplicationEventPublisher; import com.netflix.client.http.HttpRequest; import com.netflix.niws.client.http.RestClient; @@ -42,7 +41,6 @@ import static org.mockito.Matchers.anyString; @RunWith(MockitoJUnitRunner.class) public class TraceRestClientRibbonCommandFactoryTest { - @Mock ApplicationEventPublisher publisher; @Mock SpanAccessor accessor; @Mock SpringClientFactory springClientFactory; TraceRestClientRibbonCommandFactory traceRestClientRibbonCommandFactory; @@ -52,7 +50,6 @@ public class TraceRestClientRibbonCommandFactoryTest { public void setup() { this.traceRestClientRibbonCommandFactory = new TraceRestClientRibbonCommandFactory( this.springClientFactory, this.accessor); - this.traceRestClientRibbonCommandFactory.setApplicationEventPublisher(this.publisher); given(this.springClientFactory.getClient(anyString(), any(Class.class))).willReturn(new RestClient()); Span span = Span.builder() .name("name") diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/log/Slf4jSpanListenerTest.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/log/Slf4JSpanLoggerTest.java similarity index 67% rename from spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/log/Slf4jSpanListenerTest.java rename to spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/log/Slf4JSpanLoggerTest.java index 995731f35..d6ddb6a27 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/log/Slf4jSpanListenerTest.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/log/Slf4JSpanLoggerTest.java @@ -20,9 +20,6 @@ import org.junit.Test; import org.mockito.Mockito; import org.slf4j.Logger; import org.springframework.cloud.sleuth.Span; -import org.springframework.cloud.sleuth.event.SpanAcquiredEvent; -import org.springframework.cloud.sleuth.event.SpanContinuedEvent; -import org.springframework.cloud.sleuth.event.SpanReleasedEvent; import static org.mockito.BDDMockito.then; import static org.mockito.Matchers.anyList; @@ -33,79 +30,79 @@ import static org.mockito.Mockito.times; /** * @author Marcin Grzejszczak */ -public class Slf4jSpanListenerTest { +public class Slf4JSpanLoggerTest { Span spanWithNameToBeExcluded = Span.builder().name("Hystrix").build(); Span spanWithNameNotToBeExcluded = Span.builder().name("Aspect").build(); String nameExcludingPattern = "^.*Hystrix.*$"; Logger log = Mockito.mock(Logger.class); - Slf4jSpanListener slf4jSpanListener = new Slf4jSpanListener(this.nameExcludingPattern, this.log); + Slf4jSpanLogger slf4JSpanLogger = new Slf4jSpanLogger(this.nameExcludingPattern, this.log); @Test public void should_log_when_start_event_arrived_and_pattern_doesnt_match_span_name() throws Exception { - this.slf4jSpanListener.start(new SpanAcquiredEvent(this, this.spanWithNameNotToBeExcluded, - this.spanWithNameNotToBeExcluded)); + this.slf4JSpanLogger.logStartedSpan(this.spanWithNameNotToBeExcluded, + this.spanWithNameNotToBeExcluded); then(this.log).should(times(2)).trace(anyString(), anyList()); } @Test public void should_log_once_when_start_event_arrived_and_pattern_matches_only_parent_span_name() throws Exception { - this.slf4jSpanListener.start(new SpanAcquiredEvent(this, this.spanWithNameToBeExcluded, - this.spanWithNameNotToBeExcluded)); + this.slf4JSpanLogger.logStartedSpan(this.spanWithNameToBeExcluded, + this.spanWithNameNotToBeExcluded); then(this.log).should().trace(anyString(), anyList()); } @Test public void should_log_when_continue_event_arrived_and_pattern_doesnt_match_span_name() throws Exception { - this.slf4jSpanListener.continued(new SpanContinuedEvent(this, - this.spanWithNameNotToBeExcluded)); + this.slf4JSpanLogger.logContinuedSpan( + this.spanWithNameNotToBeExcluded); then(this.log).should().trace(anyString(), anyList()); } @Test public void should_not_log_when_continue_event_arrived_and_pattern_matches_name() throws Exception { - this.slf4jSpanListener.continued(new SpanContinuedEvent(this, this.spanWithNameToBeExcluded)); + this.slf4JSpanLogger.logContinuedSpan(this.spanWithNameToBeExcluded); then(this.log).should(never()).trace(anyString(), anyList()); } @Test public void should_log_when_close_event_arrived_and_pattern_doesnt_match_span_name() throws Exception { - this.slf4jSpanListener.stop(new SpanReleasedEvent(this, this.spanWithNameNotToBeExcluded)); + this.slf4JSpanLogger.logStoppedSpan(null, this.spanWithNameNotToBeExcluded); then(this.log).should().trace(anyString(), anyList()); } @Test public void should_log_both_spans_when_their_names_dont_match_pattern() throws Exception { - this.slf4jSpanListener.stop(new SpanReleasedEvent(this, this.spanWithNameNotToBeExcluded, - this.spanWithNameNotToBeExcluded)); + this.slf4JSpanLogger.logStoppedSpan(this.spanWithNameNotToBeExcluded, + this.spanWithNameNotToBeExcluded); then(this.log).should(times(2)).trace(anyString(), anyList()); } @Test public void should_not_log_any_spans_if_both_match_pattern() throws Exception { - this.slf4jSpanListener.stop(new SpanReleasedEvent(this, this.spanWithNameToBeExcluded, - this.spanWithNameToBeExcluded)); + this.slf4JSpanLogger.logStoppedSpan(this.spanWithNameToBeExcluded, + this.spanWithNameToBeExcluded); then(this.log).should(never()).trace(anyString(), anyList()); } @Test public void should_log_only_current_span_if_parent_span_name_matches_pattern() throws Exception { - this.slf4jSpanListener.stop(new SpanReleasedEvent(this, this.spanWithNameNotToBeExcluded, - this.spanWithNameToBeExcluded)); + this.slf4JSpanLogger.logStoppedSpan(this.spanWithNameNotToBeExcluded, + this.spanWithNameToBeExcluded); then(this.log).should().trace(anyString(), anyList()); } @Test public void should_log_only_current_span_if_there_is_no_parent() throws Exception { - this.slf4jSpanListener.stop(new SpanReleasedEvent(this, this.spanWithNameNotToBeExcluded)); + this.slf4JSpanLogger.logStoppedSpan(null, this.spanWithNameNotToBeExcluded); then(this.log).should().trace(anyString(), anyList()); } diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/trace/DefaultTracerTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/trace/DefaultTracerTests.java index f8c8bf88f..f365cd601 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/trace/DefaultTracerTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/trace/DefaultTracerTests.java @@ -24,23 +24,20 @@ import org.junit.After; import org.junit.Before; import org.junit.Test; import org.mockito.ArgumentCaptor; +import org.mockito.Mockito; import org.springframework.cloud.sleuth.DefaultSpanNamer; import org.springframework.cloud.sleuth.Span; import org.springframework.cloud.sleuth.SpanNamer; +import org.springframework.cloud.sleuth.SpanReporter; import org.springframework.cloud.sleuth.Tracer; -import org.springframework.cloud.sleuth.event.SpanAcquiredEvent; -import org.springframework.cloud.sleuth.event.SpanReleasedEvent; +import org.springframework.cloud.sleuth.log.SpanLogger; import org.springframework.cloud.sleuth.sampler.AlwaysSampler; import org.springframework.cloud.sleuth.sampler.NeverSampler; -import org.springframework.context.ApplicationEvent; -import org.springframework.context.ApplicationEventPublisher; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertThat; -import static org.mockito.Matchers.isA; import static org.mockito.Mockito.atLeast; -import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.springframework.cloud.sleuth.assertions.SleuthAssertions.then; @@ -56,13 +53,13 @@ public class DefaultTracerTests { public static final String IMPORTANT_WORK_1 = "http:important work 1"; public static final String IMPORTANT_WORK_2 = "http:important work 2"; public static final int NUM_SPANS = 3; - private ApplicationEventPublisher publisher; private SpanNamer spanNamer = new DefaultSpanNamer(); + private SpanLogger spanLogger = Mockito.mock(SpanLogger.class); + private SpanReporter spanReporter = Mockito.mock(SpanReporter.class); @Before public void setup() { TestSpanContextHolder.removeCurrentSpan(); - this.publisher = mock(ApplicationEventPublisher.class); } @After @@ -74,7 +71,7 @@ public class DefaultTracerTests { public void tracingWorks() { DefaultTracer tracer = new DefaultTracer(NeverSampler.INSTANCE, new Random(), - this.publisher, new DefaultSpanNamer()); + new DefaultSpanNamer(), this.spanLogger, this.spanReporter); Span span = tracer.createSpan(CREATE_SIMPLE_TRACE, new AlwaysSampler()); try { @@ -84,21 +81,16 @@ public class DefaultTracerTests { tracer.close(span); } - verify(this.publisher, times(NUM_SPANS)) - .publishEvent(isA(SpanAcquiredEvent.class)); - verify(this.publisher, times(NUM_SPANS)) - .publishEvent(isA(SpanReleasedEvent.class)); + verify(this.spanLogger, times(NUM_SPANS)) + .logStartedSpan(Mockito.any(Span.class), Mockito.any(Span.class)); + verify(this.spanReporter, times(NUM_SPANS)) + .report(Mockito.any(Span.class)); - ArgumentCaptor captor = ArgumentCaptor - .forClass(ApplicationEvent.class); - verify(this.publisher, atLeast(NUM_SPANS)).publishEvent(captor.capture()); + ArgumentCaptor captor = ArgumentCaptor + .forClass(Span.class); + verify(this.spanReporter, atLeast(NUM_SPANS)).report(captor.capture()); - List spans = new ArrayList<>(); - for (ApplicationEvent event : captor.getAllValues()) { - if (event instanceof SpanReleasedEvent) { - spans.add(((SpanReleasedEvent) event).getSpan()); - } - } + List spans = new ArrayList<>(captor.getAllValues()); assertThat("spans was wrong size", spans.size(), is(NUM_SPANS)); @@ -113,7 +105,7 @@ public class DefaultTracerTests { @Test public void nonExportable() { DefaultTracer tracer = new DefaultTracer(NeverSampler.INSTANCE, new Random(), - this.publisher, this.spanNamer); + this.spanNamer, this.spanLogger, this.spanReporter); Span span = tracer.createSpan(CREATE_SIMPLE_TRACE); assertThat(span.isExportable(), is(false)); } @@ -121,7 +113,7 @@ public class DefaultTracerTests { @Test public void exportable() { DefaultTracer tracer = new DefaultTracer(new AlwaysSampler(), new Random(), - this.publisher, this.spanNamer); + this.spanNamer, this.spanLogger, this.spanReporter); Span span = tracer.createSpan(CREATE_SIMPLE_TRACE); assertThat(span.isExportable(), is(true)); } @@ -129,7 +121,7 @@ public class DefaultTracerTests { @Test public void exportableInheritedFromParent() { DefaultTracer tracer = new DefaultTracer(new AlwaysSampler(), new Random(), - this.publisher, this.spanNamer); + this.spanNamer, this.spanLogger, this.spanReporter); Span span = tracer.createSpan(CREATE_SIMPLE_TRACE, NeverSampler.INSTANCE); assertThat(span.isExportable(), is(false)); Span child = tracer.createSpan(CREATE_SIMPLE_TRACE_SPAN_NAME + "/child", span); @@ -139,7 +131,7 @@ public class DefaultTracerTests { @Test public void parentNotRemovedIfActiveOnJoin() { DefaultTracer tracer = new DefaultTracer(new AlwaysSampler(), new Random(), - this.publisher, this.spanNamer); + this.spanNamer, this.spanLogger, this.spanReporter); Span parent = tracer.createSpan(CREATE_SIMPLE_TRACE); Span span = tracer.createSpan(IMPORTANT_WORK_1, parent); tracer.close(span); @@ -149,7 +141,7 @@ public class DefaultTracerTests { @Test public void parentRemovedIfNotActiveOnJoin() { DefaultTracer tracer = new DefaultTracer(new AlwaysSampler(), new Random(), - this.publisher, this.spanNamer); + this.spanNamer, this.spanLogger, this.spanReporter); Span parent = Span.builder().name(CREATE_SIMPLE_TRACE).traceId(1L).spanId(1L) .build(); Span span = tracer.createSpan(IMPORTANT_WORK_1, parent); @@ -160,7 +152,7 @@ public class DefaultTracerTests { @Test public void grandParentRestoredAfterAutoClose() { DefaultTracer tracer = new DefaultTracer(new AlwaysSampler(), new Random(), - this.publisher, this.spanNamer); + this.spanNamer, this.spanLogger, this.spanReporter); Span grandParent = tracer.createSpan(CREATE_SIMPLE_TRACE); Span parent = Span.builder().name(IMPORTANT_WORK_1).traceId(1L).spanId(1L) .build(); @@ -172,7 +164,7 @@ public class DefaultTracerTests { @Test public void shouldUpdateLogsInSpanWhenItGetsContinued() { DefaultTracer tracer = new DefaultTracer(new AlwaysSampler(), new Random(), - this.publisher, this.spanNamer); + this.spanNamer, this.spanLogger, this.spanReporter); Span span = Span.builder().name(IMPORTANT_WORK_1).traceId(1L).spanId(1L) .build(); Span continuedSpan = tracer.continueSpan(span); diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/src/test/java/integration/ZipkinTests.java b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/src/test/java/integration/ZipkinTests.java index 6a9178018..c6b2c9dec 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/src/test/java/integration/ZipkinTests.java +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/src/test/java/integration/ZipkinTests.java @@ -27,7 +27,7 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.boot.test.WebIntegrationTest; -import org.springframework.cloud.sleuth.metric.SpanReporterService; +import org.springframework.cloud.sleuth.metric.SpanMetricReporter; import org.springframework.cloud.sleuth.zipkin.HttpZipkinSpanReporter; import org.springframework.cloud.sleuth.zipkin.ZipkinProperties; import org.springframework.cloud.sleuth.zipkin.ZipkinSpanReporter; @@ -81,13 +81,13 @@ public class ZipkinTests extends AbstractIntegrationTest { @Bean public ZipkinSpanReporter spanCollector(final ZipkinProperties zipkin, - final SpanReporterService spanReporterService) { + final SpanMetricReporter spanMetricReporter) { await().until(new Runnable() { @Override public void run() { try { WaitUntilZipkinIsUpConfig.this.getSpanCollector(zipkin, - spanReporterService); + spanMetricReporter); } catch (Exception e) { log.error("Exception occurred while trying to connect to zipkin [" @@ -96,13 +96,13 @@ public class ZipkinTests extends AbstractIntegrationTest { } } }); - return getSpanCollector(zipkin, spanReporterService); + return getSpanCollector(zipkin, spanMetricReporter); } private ZipkinSpanReporter getSpanCollector(ZipkinProperties zipkin, - SpanReporterService spanReporterService) { + SpanMetricReporter spanMetricReporter) { return new HttpZipkinSpanReporter(zipkin.getBaseUrl(), zipkin.getFlushInterval(), - zipkin.getCompression().isEnabled(), spanReporterService); + zipkin.getCompression().isEnabled(), spanMetricReporter); } } diff --git a/spring-cloud-sleuth-stream/src/main/java/org/springframework/cloud/sleuth/stream/SleuthStreamAutoConfiguration.java b/spring-cloud-sleuth-stream/src/main/java/org/springframework/cloud/sleuth/stream/SleuthStreamAutoConfiguration.java index ddc260fe8..c34239bc2 100644 --- a/spring-cloud-sleuth-stream/src/main/java/org/springframework/cloud/sleuth/stream/SleuthStreamAutoConfiguration.java +++ b/spring-cloud-sleuth-stream/src/main/java/org/springframework/cloud/sleuth/stream/SleuthStreamAutoConfiguration.java @@ -27,7 +27,7 @@ import org.springframework.boot.autoconfigure.web.ServerProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.cloud.client.discovery.DiscoveryClient; import org.springframework.cloud.sleuth.Sampler; -import org.springframework.cloud.sleuth.metric.SpanReporterService; +import org.springframework.cloud.sleuth.metric.SpanMetricReporter; import org.springframework.cloud.sleuth.sampler.PercentageBasedSampler; import org.springframework.cloud.sleuth.sampler.SamplerProperties; import org.springframework.cloud.stream.annotation.EnableBinding; @@ -64,14 +64,14 @@ public class SleuthStreamAutoConfiguration { @Bean @GlobalChannelInterceptor(patterns = SleuthSource.OUTPUT, order = Ordered.HIGHEST_PRECEDENCE) - public ChannelInterceptor zipkinChannelInterceptor(SpanReporterService spanReporterService) { - return new TracerIgnoringChannelInterceptor(spanReporterService); + public ChannelInterceptor zipkinChannelInterceptor(SpanMetricReporter spanMetricReporter) { + return new TracerIgnoringChannelInterceptor(spanMetricReporter); } @Bean public StreamSpanListener sleuthTracer(HostLocator endpointLocator, - SpanReporterService spanReporterService) { - return new StreamSpanListener(endpointLocator, spanReporterService); + SpanMetricReporter spanMetricReporter) { + return new StreamSpanListener(endpointLocator, spanMetricReporter); } @Configuration diff --git a/spring-cloud-sleuth-stream/src/main/java/org/springframework/cloud/sleuth/stream/StreamSpanListener.java b/spring-cloud-sleuth-stream/src/main/java/org/springframework/cloud/sleuth/stream/StreamSpanListener.java index 58732eed4..79ded708d 100644 --- a/spring-cloud-sleuth-stream/src/main/java/org/springframework/cloud/sleuth/stream/StreamSpanListener.java +++ b/spring-cloud-sleuth-stream/src/main/java/org/springframework/cloud/sleuth/stream/StreamSpanListener.java @@ -23,15 +23,8 @@ import java.util.List; import java.util.concurrent.ConcurrentLinkedQueue; import org.springframework.cloud.sleuth.Span; -import org.springframework.cloud.sleuth.event.ClientReceivedEvent; -import org.springframework.cloud.sleuth.event.ClientSentEvent; -import org.springframework.cloud.sleuth.event.ServerReceivedEvent; -import org.springframework.cloud.sleuth.event.ServerSentEvent; -import org.springframework.cloud.sleuth.event.SpanAcquiredEvent; -import org.springframework.cloud.sleuth.event.SpanReleasedEvent; -import org.springframework.cloud.sleuth.metric.SpanReporterService; -import org.springframework.context.event.EventListener; -import org.springframework.core.annotation.Order; +import org.springframework.cloud.sleuth.SpanReporter; +import org.springframework.cloud.sleuth.metric.SpanMetricReporter; import org.springframework.integration.annotation.InboundChannelAdapter; import org.springframework.integration.annotation.MessageEndpoint; @@ -44,70 +37,21 @@ import org.springframework.integration.annotation.MessageEndpoint; * @since 1.0.0 */ @MessageEndpoint -public class StreamSpanListener { - - public static final String CLIENT_RECV = "cr"; - public static final String CLIENT_SEND = "cs"; - public static final String SERVER_RECV = "sr"; - public static final String SERVER_SEND = "ss"; +public class StreamSpanListener implements SpanReporter { private Collection queue = new ConcurrentLinkedQueue<>(); private final HostLocator endpointLocator; - private final SpanReporterService spanReporterService; + private final SpanMetricReporter spanMetricReporter; - public StreamSpanListener(HostLocator endpointLocator, SpanReporterService spanReporterService) { + public StreamSpanListener(HostLocator endpointLocator, SpanMetricReporter spanMetricReporter) { this.endpointLocator = endpointLocator; - this.spanReporterService = spanReporterService; + this.spanMetricReporter = spanMetricReporter; } public void setQueue(Collection queue) { this.queue = queue; } - @EventListener - @Order(0) - public void start(SpanAcquiredEvent event) { - event.getSpan().logEvent("acquire"); - } - - @EventListener - @Order(0) - public void serverReceived(ServerReceivedEvent event) { - if (event.getParent() != null && event.getParent().isRemote()) { - event.getParent().logEvent(SERVER_RECV); - } - } - - @EventListener - @Order(0) - public void clientSend(ClientSentEvent event) { - event.getSpan().logEvent(CLIENT_SEND); - } - - @EventListener - @Order(0) - public void clientReceive(ClientReceivedEvent event) { - event.getSpan().logEvent(CLIENT_RECV); - } - - @EventListener - @Order(0) - public void serverSend(ServerSentEvent event) { - if (event.getParent() != null && event.getParent().isRemote()) { - event.getParent().logEvent(SERVER_SEND); - this.queue.add(event.getParent()); - } - } - - @EventListener - @Order(0) - public void release(SpanReleasedEvent event) { - event.getSpan().logEvent("release"); - if (event.getSpan().isExportable()) { - this.queue.add(event.getSpan()); - } - } - @InboundChannelAdapter(value = SleuthSource.OUTPUT) public Spans poll() { List result = new ArrayList<>(this.queue); @@ -121,8 +65,14 @@ public class StreamSpanListener { if (result.isEmpty()) { return null; } - this.spanReporterService.incrementAcceptedSpans(result.size()); + this.spanMetricReporter.incrementAcceptedSpans(result.size()); return new Spans(this.endpointLocator.locate(result.get(0)), result); } + @Override + public void report(Span span) { + if (span.isExportable()) { + this.queue.add(span); + } + } } diff --git a/spring-cloud-sleuth-stream/src/main/java/org/springframework/cloud/sleuth/stream/TracerIgnoringChannelInterceptor.java b/spring-cloud-sleuth-stream/src/main/java/org/springframework/cloud/sleuth/stream/TracerIgnoringChannelInterceptor.java index caa14f4a3..a61d11ced 100644 --- a/spring-cloud-sleuth-stream/src/main/java/org/springframework/cloud/sleuth/stream/TracerIgnoringChannelInterceptor.java +++ b/spring-cloud-sleuth-stream/src/main/java/org/springframework/cloud/sleuth/stream/TracerIgnoringChannelInterceptor.java @@ -17,7 +17,7 @@ package org.springframework.cloud.sleuth.stream; import org.springframework.cloud.sleuth.Span; -import org.springframework.cloud.sleuth.metric.SpanReporterService; +import org.springframework.cloud.sleuth.metric.SpanMetricReporter; import org.springframework.integration.support.MessageBuilder; import org.springframework.messaging.Message; import org.springframework.messaging.MessageChannel; @@ -31,10 +31,10 @@ import org.springframework.messaging.support.ChannelInterceptorAdapter; */ class TracerIgnoringChannelInterceptor extends ChannelInterceptorAdapter { - private final SpanReporterService spanReporterService; + private final SpanMetricReporter spanMetricReporter; - public TracerIgnoringChannelInterceptor(SpanReporterService spanReporterService) { - this.spanReporterService = spanReporterService; + public TracerIgnoringChannelInterceptor(SpanMetricReporter spanMetricReporter) { + this.spanMetricReporter = spanMetricReporter; } /** @@ -55,9 +55,9 @@ class TracerIgnoringChannelInterceptor extends ChannelInterceptorAdapter { Spans spans = (Spans) message.getPayload(); int spanNumber = spans.getSpans().size(); if (sent) { - this.spanReporterService.incrementAcceptedSpans(spanNumber); + this.spanMetricReporter.incrementAcceptedSpans(spanNumber); } else { - this.spanReporterService.incrementDroppedSpans(spanNumber); + this.spanMetricReporter.incrementDroppedSpans(spanNumber); } } } diff --git a/spring-cloud-sleuth-stream/src/test/java/org/springframework/cloud/sleuth/stream/StreamSpanListenerTests.java b/spring-cloud-sleuth-stream/src/test/java/org/springframework/cloud/sleuth/stream/StreamSpanListenerTests.java index 2dbbb6718..3e9b241bd 100644 --- a/spring-cloud-sleuth-stream/src/test/java/org/springframework/cloud/sleuth/stream/StreamSpanListenerTests.java +++ b/spring-cloud-sleuth-stream/src/test/java/org/springframework/cloud/sleuth/stream/StreamSpanListenerTests.java @@ -35,12 +35,11 @@ import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfigurati import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.cloud.sleuth.Sampler; import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.SpanReporter; import org.springframework.cloud.sleuth.Tracer; import org.springframework.cloud.sleuth.autoconfig.TraceAutoConfiguration; -import org.springframework.cloud.sleuth.event.ClientReceivedEvent; -import org.springframework.cloud.sleuth.event.ClientSentEvent; -import org.springframework.cloud.sleuth.event.ServerReceivedEvent; -import org.springframework.cloud.sleuth.event.ServerSentEvent; +import org.springframework.cloud.sleuth.log.NoOpSpanLogger; +import org.springframework.cloud.sleuth.log.SpanLogger; import org.springframework.cloud.sleuth.metric.TraceMetricsAutoConfiguration; import org.springframework.cloud.sleuth.sampler.AlwaysSampler; import org.springframework.cloud.sleuth.stream.StreamSpanListenerTests.TestConfiguration; @@ -68,6 +67,7 @@ public class StreamSpanListenerTests { @Autowired ZipkinTestConfiguration test; @Autowired StreamSpanListener listener; @Autowired CounterService counterService; + @Autowired SpanReporter spanReporter; @PostConstruct public void init() { @@ -86,20 +86,30 @@ public class StreamSpanListenerTests { Span parent = Span.builder().traceId(1L).name("http:parent").remote(true) .build(); Span context = this.tracer.createSpan("http:child", parent); - this.application.publishEvent(new ClientSentEvent(this, context)); - this.application - .publishEvent(new ServerReceivedEvent(this, parent, context)); - this.application - .publishEvent(new ServerSentEvent(this, parent, context)); - this.application.publishEvent(new ClientReceivedEvent(this, context)); + context.logEvent(Span.CLIENT_SEND); + logServerReceived(parent); + logServerSent(this.spanReporter, parent); this.tracer.close(context); assertEquals(2, this.test.spans.size()); } + void logServerReceived(Span parent) { + if (parent != null && parent.isRemote()) { + parent.logEvent(Span.SERVER_RECV); + } + } + + void logServerSent(SpanReporter spanReporter, Span parent) { + if (parent != null && parent.isRemote()) { + parent.logEvent(Span.SERVER_SEND); + spanReporter.report(parent); + } + } + @Test public void nullSpanName() { Span span = this.tracer.createSpan(null); - this.application.publishEvent(new ClientSentEvent(this, span)); + span.logEvent(Span.CLIENT_SEND); this.tracer.close(span); assertEquals(1, this.test.spans.size()); this.listener.poll(); @@ -135,6 +145,11 @@ public class StreamSpanListenerTests { public void handle(Message msg) { } + @Bean + SpanLogger spanLogger() { + return new NoOpSpanLogger(); + } + @Bean public Sampler defaultSampler() { return new AlwaysSampler(); diff --git a/spring-cloud-sleuth-stream/src/test/java/org/springframework/cloud/sleuth/stream/TracerIgnoringChannelInterceptorTest.java b/spring-cloud-sleuth-stream/src/test/java/org/springframework/cloud/sleuth/stream/TracerIgnoringChannelInterceptorTest.java index e678a5af9..768c4b815 100644 --- a/spring-cloud-sleuth-stream/src/test/java/org/springframework/cloud/sleuth/stream/TracerIgnoringChannelInterceptorTest.java +++ b/spring-cloud-sleuth-stream/src/test/java/org/springframework/cloud/sleuth/stream/TracerIgnoringChannelInterceptorTest.java @@ -25,7 +25,7 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; import org.springframework.cloud.sleuth.Span; -import org.springframework.cloud.sleuth.metric.SpanReporterService; +import org.springframework.cloud.sleuth.metric.SpanMetricReporter; import org.springframework.integration.support.MessageBuilder; import org.springframework.messaging.Message; import org.springframework.messaging.MessageChannel; @@ -40,7 +40,7 @@ import static org.mockito.Mockito.verifyZeroInteractions; public class TracerIgnoringChannelInterceptorTest { @Mock MessageChannel messageChannel; - @Mock SpanReporterService spanReporterService; + @Mock SpanMetricReporter spanMetricReporter; @InjectMocks TracerIgnoringChannelInterceptor tracerIgnoringChannelInterceptor; @Test @@ -59,7 +59,7 @@ public class TracerIgnoringChannelInterceptorTest { this.tracerIgnoringChannelInterceptor.afterSendCompletion(message, this.messageChannel, true, null); - verifyZeroInteractions(this.spanReporterService); + verifyZeroInteractions(this.spanMetricReporter); } @Test @@ -71,7 +71,7 @@ public class TracerIgnoringChannelInterceptorTest { this.tracerIgnoringChannelInterceptor.afterSendCompletion(message, this.messageChannel, true, null); - BDDMockito.then(this.spanReporterService).should().incrementAcceptedSpans(2); + BDDMockito.then(this.spanMetricReporter).should().incrementAcceptedSpans(2); } @Test @@ -83,6 +83,6 @@ public class TracerIgnoringChannelInterceptorTest { this.tracerIgnoringChannelInterceptor.afterSendCompletion(message, this.messageChannel, false, null); - BDDMockito.then(this.spanReporterService).should().incrementDroppedSpans(2); + BDDMockito.then(this.spanMetricReporter).should().incrementDroppedSpans(2); } } \ No newline at end of file diff --git a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin/HttpZipkinSpanReporter.java b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin/HttpZipkinSpanReporter.java index 2e3ba3b11..f33e0b412 100644 --- a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin/HttpZipkinSpanReporter.java +++ b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin/HttpZipkinSpanReporter.java @@ -16,7 +16,7 @@ import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ScheduledExecutorService; import org.apache.commons.logging.Log; -import org.springframework.cloud.sleuth.metric.SpanReporterService; +import org.springframework.cloud.sleuth.metric.SpanMetricReporter; import zipkin.Codec; import zipkin.Span; @@ -41,20 +41,20 @@ public final class HttpZipkinSpanReporter private final BlockingQueue pending = new LinkedBlockingQueue<>(1000); private final Flusher flusher; // Nullable for testing private final boolean compressionEnabled; - private final SpanReporterService spanReporterService; + private final SpanMetricReporter spanMetricReporter; /** * @param baseUrl URL of the zipkin query server instance. Like: http://localhost:9411/ * @param flushInterval in seconds. 0 implies spans are {@link #flush() flushed} externally. * @param compressionEnabled compress spans using gzip before posting to the zipkin server. - * @param spanReporterService service to count number of accepted / dropped spans + * @param spanMetricReporter service to count number of accepted / dropped spans */ public HttpZipkinSpanReporter(String baseUrl, int flushInterval, boolean compressionEnabled, - SpanReporterService spanReporterService) { + SpanMetricReporter spanMetricReporter) { this.url = baseUrl + (baseUrl.endsWith("/") ? "" : "/") + "api/v1/spans"; this.flusher = flushInterval > 0 ? new Flusher(this, flushInterval) : null; this.compressionEnabled = compressionEnabled; - this.spanReporterService = spanReporterService; + this.spanMetricReporter = spanMetricReporter; } /** @@ -64,9 +64,9 @@ public final class HttpZipkinSpanReporter */ @Override public void report(Span span) { - this.spanReporterService.incrementAcceptedSpans(1); + this.spanMetricReporter.incrementAcceptedSpans(1); if (!this.pending.offer(span)) { - this.spanReporterService.incrementDroppedSpans(1); + this.spanMetricReporter.incrementDroppedSpans(1); } } @@ -87,7 +87,7 @@ public final class HttpZipkinSpanReporter // NOTE: https://github.com/openzipkin/zipkin-java/issues/66 will throw instead of return null. if (json == null) { log.debug("failed to encode spans, dropping them: " + drained); - this.spanReporterService.incrementDroppedSpans(drained.size()); + this.spanMetricReporter.incrementDroppedSpans(drained.size()); return; } @@ -102,7 +102,7 @@ public final class HttpZipkinSpanReporter "error POSTing spans to " + this.url + ": as json: " + new String(json, UTF_8), e); } - this.spanReporterService.incrementDroppedSpans(drained.size()); + this.spanMetricReporter.incrementDroppedSpans(drained.size()); } } @@ -164,6 +164,6 @@ public final class HttpZipkinSpanReporter this.flusher.scheduler.shutdown(); // throw any outstanding spans on the floor int dropped = this.pending.drainTo(new LinkedList<>()); - this.spanReporterService.incrementDroppedSpans(dropped); + this.spanMetricReporter.incrementDroppedSpans(dropped); } } diff --git a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin/ZipkinAutoConfiguration.java b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin/ZipkinAutoConfiguration.java index 06fd29091..415aa93ca 100644 --- a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin/ZipkinAutoConfiguration.java +++ b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin/ZipkinAutoConfiguration.java @@ -28,7 +28,7 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties import org.springframework.cloud.client.discovery.DiscoveryClient; import org.springframework.cloud.sleuth.Sampler; import org.springframework.cloud.sleuth.autoconfig.TraceAutoConfiguration; -import org.springframework.cloud.sleuth.metric.SpanReporterService; +import org.springframework.cloud.sleuth.metric.SpanMetricReporter; import org.springframework.cloud.sleuth.sampler.PercentageBasedSampler; import org.springframework.cloud.sleuth.sampler.SamplerProperties; import org.springframework.context.annotation.Bean; @@ -52,9 +52,9 @@ public class ZipkinAutoConfiguration { @Bean @ConditionalOnMissingBean(ZipkinSpanReporter.class) - public ZipkinSpanReporter reporter(SpanReporterService spanReporterService, ZipkinProperties zipkin) { + public ZipkinSpanReporter reporter(SpanMetricReporter spanMetricReporter, ZipkinProperties zipkin) { return new HttpZipkinSpanReporter(zipkin.getBaseUrl(), zipkin.getFlushInterval(), - zipkin.getCompression().isEnabled(), spanReporterService); + zipkin.getCompression().isEnabled(), spanMetricReporter); } @Bean diff --git a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin/ZipkinSpanListener.java b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin/ZipkinSpanListener.java index a3c441f04..0300a8c45 100644 --- a/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin/ZipkinSpanListener.java +++ b/spring-cloud-sleuth-zipkin/src/main/java/org/springframework/cloud/sleuth/zipkin/ZipkinSpanListener.java @@ -23,14 +23,7 @@ import java.util.Map; import org.springframework.cloud.sleuth.Log; import org.springframework.cloud.sleuth.Span; -import org.springframework.cloud.sleuth.event.ClientReceivedEvent; -import org.springframework.cloud.sleuth.event.ClientSentEvent; -import org.springframework.cloud.sleuth.event.ServerReceivedEvent; -import org.springframework.cloud.sleuth.event.ServerSentEvent; -import org.springframework.cloud.sleuth.event.SpanAcquiredEvent; -import org.springframework.cloud.sleuth.event.SpanReleasedEvent; -import org.springframework.context.event.EventListener; -import org.springframework.core.annotation.Order; +import org.springframework.cloud.sleuth.SpanReporter; import org.springframework.util.StringUtils; import zipkin.Annotation; @@ -45,7 +38,7 @@ import zipkin.Endpoint; * * @since 1.0.0 */ -public class ZipkinSpanListener { +public class ZipkinSpanListener implements SpanReporter { private static final List ZIPKIN_START_EVENTS = Arrays.asList( Constants.CLIENT_RECV, Constants.SERVER_RECV ); @@ -68,59 +61,6 @@ public class ZipkinSpanListener { this.endpointLocator = endpointLocator; } - @EventListener - @Order(0) - public void start(SpanAcquiredEvent event) { - // Zipkin Span.timestamp corresponds with Sleuth's Span.begin - assert event.getSpan().getBegin() != 0; - } - - @EventListener - @Order(0) - public void serverReceived(ServerReceivedEvent event) { - if (event.getParent() != null && event.getParent().isRemote()) { - // If an inbound RPC call, it should log a "sr" annotation. - // If possible, it should log a binary annotation of "ca", indicating the - // caller's address (ex X-Forwarded-For header) - event.getParent().logEvent(Constants.SERVER_RECV); - } - } - - @EventListener - @Order(0) - public void clientSend(ClientSentEvent event) { - // For an outbound RPC call, it should log a "cs" annotation. - // If possible, it should log a binary annotation of "sa", indicating the - // destination address. - event.getSpan().logEvent(Constants.CLIENT_SEND); - } - - @EventListener - @Order(0) - public void clientReceive(ClientReceivedEvent event) { - event.getSpan().logEvent(Constants.CLIENT_RECV); - } - - @EventListener - @Order(0) - public void serverSend(ServerSentEvent event) { - if (event.getParent() != null && event.getParent().isRemote()) { - event.getParent().logEvent(Constants.SERVER_SEND); - this.reporter.report(convert(event.getParent())); - } - } - - @EventListener - @Order(0) - public void release(SpanReleasedEvent event) { - // Ending a span in zipkin means adding duration and sending it out - // Zipkin Span.duration corresponds with Sleuth's Span.begin and end - assert event.getSpan().getEnd() != 0; - if (event.getSpan().isExportable()) { - this.reporter.report(convert(event.getSpan())); - } - } - /** * Converts a given Sleuth span to a Zipkin Span. *

    @@ -232,4 +172,8 @@ public class ZipkinSpanListener { } } + @Override + public void report(Span span) { + this.reporter.report(convert(span)); + } } diff --git a/spring-cloud-sleuth-zipkin/src/test/java/org/springframework/cloud/sleuth/zipkin/HttpZipkinSpanReporterTest.java b/spring-cloud-sleuth-zipkin/src/test/java/org/springframework/cloud/sleuth/zipkin/HttpZipkinSpanReporterTest.java index 83e081323..2bc1d88a3 100644 --- a/spring-cloud-sleuth-zipkin/src/test/java/org/springframework/cloud/sleuth/zipkin/HttpZipkinSpanReporterTest.java +++ b/spring-cloud-sleuth-zipkin/src/test/java/org/springframework/cloud/sleuth/zipkin/HttpZipkinSpanReporterTest.java @@ -2,8 +2,8 @@ package org.springframework.cloud.sleuth.zipkin; import org.junit.Rule; import org.junit.Test; -import org.springframework.cloud.sleuth.metric.CounterServiceBasedSpanReporterService; -import org.springframework.cloud.sleuth.metric.SpanReporterService; +import org.springframework.cloud.sleuth.metric.CounterServiceBasedSpanMetricReporter; +import org.springframework.cloud.sleuth.metric.SpanMetricReporter; import zipkin.Span; import zipkin.junit.HttpFailure; @@ -16,14 +16,14 @@ public class HttpZipkinSpanReporterTest { @Rule public final ZipkinRule zipkin = new ZipkinRule(); InMemorySpanCounter inMemorySpanCounter = new InMemorySpanCounter(); - SpanReporterService spanReporterService = new CounterServiceBasedSpanReporterService("accepted", "dropped", + SpanMetricReporter spanMetricReporter = new CounterServiceBasedSpanMetricReporter("accepted", "dropped", this.inMemorySpanCounter); HttpZipkinSpanReporter reporter = new HttpZipkinSpanReporter( this.zipkin.httpUrl(), 0, // so that tests can drive flushing explicitly false, // disable compression - this.spanReporterService + this.spanMetricReporter ); @Test @@ -72,7 +72,7 @@ public class HttpZipkinSpanReporterTest { this.zipkin.httpUrl(), 0, // so that tests can drive flushing explicitly false, // enable compression - this.spanReporterService + this.spanMetricReporter ); this.reporter.report(span(1L, "foo")); diff --git a/spring-cloud-sleuth-zipkin/src/test/java/org/springframework/cloud/sleuth/zipkin/ZipkinSpanListenerTests.java b/spring-cloud-sleuth-zipkin/src/test/java/org/springframework/cloud/sleuth/zipkin/ZipkinSpanListenerTests.java index eaf6c15b9..584ec3db3 100644 --- a/spring-cloud-sleuth-zipkin/src/test/java/org/springframework/cloud/sleuth/zipkin/ZipkinSpanListenerTests.java +++ b/spring-cloud-sleuth-zipkin/src/test/java/org/springframework/cloud/sleuth/zipkin/ZipkinSpanListenerTests.java @@ -28,12 +28,11 @@ import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfigurati import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.cloud.sleuth.Sampler; import org.springframework.cloud.sleuth.Span; +import org.springframework.cloud.sleuth.SpanReporter; import org.springframework.cloud.sleuth.Tracer; import org.springframework.cloud.sleuth.autoconfig.TraceAutoConfiguration; -import org.springframework.cloud.sleuth.event.ClientReceivedEvent; -import org.springframework.cloud.sleuth.event.ClientSentEvent; -import org.springframework.cloud.sleuth.event.ServerReceivedEvent; -import org.springframework.cloud.sleuth.event.ServerSentEvent; +import org.springframework.cloud.sleuth.log.NoOpSpanLogger; +import org.springframework.cloud.sleuth.log.SpanLogger; import org.springframework.cloud.sleuth.sampler.AlwaysSampler; import org.springframework.cloud.sleuth.zipkin.ZipkinSpanListenerTests.TestConfiguration; import org.springframework.context.ApplicationContext; @@ -55,17 +54,11 @@ import static org.junit.Assert.assertEquals; @RunWith(SpringJUnit4ClassRunner.class) public class ZipkinSpanListenerTests { - @Autowired - private Tracer tracer; - - @Autowired - private ApplicationContext application; - - @Autowired - private ZipkinTestConfiguration test; - - @Autowired - private ZipkinSpanListener listener; + @Autowired Tracer tracer; + @Autowired ApplicationContext application; + @Autowired ZipkinTestConfiguration test; + @Autowired ZipkinSpanListener listener; + @Autowired SpanReporter spanReporter; @PostConstruct public void init() { @@ -130,14 +123,26 @@ public class ZipkinSpanListenerTests { @Test public void rpcAnnotations() { Span context = this.tracer.createSpan("http:child", this.parent); - this.application.publishEvent(new ClientSentEvent(this, context)); - this.application.publishEvent(new ServerReceivedEvent(this, this.parent, context)); - this.application.publishEvent(new ServerSentEvent(this, this.parent, context)); - this.application.publishEvent(new ClientReceivedEvent(this, context)); + context.logEvent(Span.CLIENT_SEND); + logServerReceived(this.parent); + logServerSent(this.spanReporter, this.parent); this.tracer.close(context); assertEquals(2, this.test.spans.size()); } + void logServerReceived(Span parent) { + if (parent != null && parent.isRemote()) { + parent.logEvent(Span.SERVER_RECV); + } + } + + void logServerSent(SpanReporter spanReporter, Span parent) { + if (parent != null && parent.isRemote()) { + parent.logEvent(Span.SERVER_SEND); + spanReporter.report(parent); + } + } + @Test public void appendsLocalComponentTagIfNoZipkinLogIsPresent() { this.parent.logEvent("hystrix/retry"); @@ -181,6 +186,11 @@ public class ZipkinSpanListenerTests { @Import({ ZipkinTestConfiguration.class, ZipkinAutoConfiguration.class, TraceAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class }) protected static class TestConfiguration { + + @Bean + SpanLogger spanLogger() { + return new NoOpSpanLogger(); + } } @Configuration