Merge pull request #212 from spring-cloud/issues_#156_refactor_events
Removed events and replaced them with method calls
This commit is contained in:
11
.travis.yml
11
.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 <<EOF
|
||||
|
||||
@@ -23,15 +20,21 @@ script:
|
||||
VERSION=${VERSION}
|
||||
MILESTONE=${MILESTONE}
|
||||
MVN_PROFILE=${MVN_PROFILE}
|
||||
TRAVIS_BRANCH=${TRAVIS_BRANCH}
|
||||
TRAVIS_REPO_SLUG=${TRAVIS_REPO_SLUG}
|
||||
TRAVIS_PULL_REQUEST=${TRAVIS_PULL_REQUEST}
|
||||
|
||||
EOF
|
||||
- ./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:
|
||||
- './mvnw -s .settings.xml $MVN_GOAL $MVN_PROFILE -nsu -Dmaven.test.redirectTestOutputToFile=true'
|
||||
env:
|
||||
global:
|
||||
- GIT_NAME="Spencer Gibb"
|
||||
- GIT_EMAIL=sgibb@pivotal.io
|
||||
- CI_DEPLOY_USERNAME=sgibb
|
||||
- FEATURE_BRANCH=$(echo ${TRAVIS_BRANCH} | grep "^.*/.*$" && echo true || echo false)
|
||||
- FEATURE_BRANCH=$(echo ${TRAVIS_BRANCH} | grep -v "master" && echo true || echo false)
|
||||
- SPRING_CLOUD_BUILD=$(echo ${TRAVIS_REPO_SLUG} | grep -q "^spring-cloud/.*$" && echo true || echo false)
|
||||
- MVN_GOAL=$([ "${TRAVIS_PULL_REQUEST}" == "false" -a "${TRAVIS_TAG}" == "" -a "${FEATURE_BRANCH}" == "false" -a "${SPRING_CLOUD_BUILD}" == "true" ] && echo deploy || echo install)
|
||||
- VERSION=$(mvn validate | grep Building | head -1 | sed -e 's/.* //')
|
||||
|
||||
@@ -52,4 +52,11 @@ public class Log {
|
||||
public String getEvent() {
|
||||
return this.event;
|
||||
}
|
||||
|
||||
@Override public String toString() {
|
||||
return "Log{" +
|
||||
"timestamp=" + this.timestamp +
|
||||
", event='" + this.event + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,20 +14,18 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.sleuth.event;
|
||||
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
package org.springframework.cloud.sleuth;
|
||||
|
||||
/**
|
||||
* Emitted when a span was continued.
|
||||
* Span reporter that does nothing
|
||||
*
|
||||
* @author Spencer Gibb
|
||||
* @author Marcin Grzejszczak
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class SpanContinuedEvent extends SpanContainingEvent {
|
||||
public class NoOpSpanReporter implements SpanReporter {
|
||||
@Override
|
||||
public void report(Span span) {
|
||||
|
||||
public SpanContinuedEvent(Object source, Span span) {
|
||||
super(source, span);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -39,10 +39,10 @@ import org.springframework.util.StringUtils;
|
||||
* of the core annotations used to define the start and stop of a request:
|
||||
* <p>
|
||||
* <ul>
|
||||
* <li><b>cs</b> - {@link org.springframework.cloud.sleuth.event.ClientSentEvent Client Sent}</li>
|
||||
* <li><b>sr</b> - {@link org.springframework.cloud.sleuth.event.ServerReceivedEvent Server Received}</li>
|
||||
* <li><b>ss</b> - {@link org.springframework.cloud.sleuth.event.ServerSentEvent Server Sent}</li>
|
||||
* <li><b>cr</b> - {@link org.springframework.cloud.sleuth.event.ClientReceivedEvent Client Received}</li>
|
||||
* <li><b>cs</b> - Client Sent</li>
|
||||
* <li><b>sr</b> - Server Received</li>
|
||||
* <li><b>ss</b> - Server Sent</li>
|
||||
* <li><b>cr</b> - Client Received</li>
|
||||
* </ul>
|
||||
*
|
||||
* @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";
|
||||
/**
|
||||
* <b>cr</b> - 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";
|
||||
|
||||
/**
|
||||
* <b>cs</b> - 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";
|
||||
|
||||
/**
|
||||
* <b>sr</b> - 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";
|
||||
|
||||
/**
|
||||
* <b>ss</b> - 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";
|
||||
|
||||
/**
|
||||
* <a href="https://github.com/opentracing/opentracing-go/blob/master/ext/tags.go">As in Open Tracing</a>
|
||||
*/
|
||||
|
||||
@@ -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;
|
||||
|
||||
/**
|
||||
* <b>cs</b> - 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);
|
||||
}
|
||||
|
||||
}
|
||||
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);
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
/**
|
||||
* <b>cr</b> - 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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/**
|
||||
* <b>ss</b> - 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);
|
||||
}
|
||||
}
|
||||
@@ -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 +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -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 +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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<HttpMessageConverters> 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 {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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<String, String> headers,
|
||||
MultiValueMap<String, String> 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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logStoppedSpan(Span parent, Span span) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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.
|
||||
* <p>
|
||||
* 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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
@@ -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;
|
||||
|
||||
/**
|
||||
* <b>sr</b> - 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);
|
||||
}
|
||||
@@ -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;
|
||||
@@ -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) {
|
||||
|
||||
@@ -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.
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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<SpanReleasedEvent> {
|
||||
public class ArrayListSpanAccumulator implements SpanReporter {
|
||||
private final List<Span> spans = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(SpanReleasedEvent event) {
|
||||
this.spans.add(event.getSpan());
|
||||
}
|
||||
|
||||
public List<Span> getSpans() {
|
||||
return this.spans;
|
||||
}
|
||||
@@ -47,4 +42,9 @@ public class ArrayListSpanAccumulator implements ApplicationListener<SpanRelease
|
||||
"spans=" + this.spans +
|
||||
'}';
|
||||
}
|
||||
|
||||
@Override
|
||||
public void report(Span span) {
|
||||
this.spans.add(span);
|
||||
}
|
||||
}
|
||||
@@ -27,6 +27,7 @@ import org.junit.Test;
|
||||
import org.mockito.BDDMockito;
|
||||
import org.mockito.Mockito;
|
||||
import org.springframework.cloud.sleuth.DefaultSpanNamer;
|
||||
import org.springframework.cloud.sleuth.NoOpSpanReporter;
|
||||
import org.springframework.cloud.sleuth.Sampler;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.SpanName;
|
||||
@@ -34,9 +35,9 @@ import org.springframework.cloud.sleuth.SpanNamer;
|
||||
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.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@@ -115,8 +116,8 @@ public class SpringCloudSleuthDocTests {
|
||||
executorService.shutdown();
|
||||
}
|
||||
|
||||
ApplicationEventPublisher publisher = Mockito.mock(ApplicationEventPublisher.class);
|
||||
Tracer tracer = new DefaultTracer(new AlwaysSampler(), new Random(), this.publisher, new DefaultSpanNamer());
|
||||
Tracer tracer = new DefaultTracer(new AlwaysSampler(), new Random(), new DefaultSpanNamer(),
|
||||
new NoOpSpanLogger(), new NoOpSpanReporter());
|
||||
|
||||
@Test
|
||||
public void should_create_a_span_with_tracer() {
|
||||
@@ -222,7 +223,8 @@ public class SpringCloudSleuthDocTests {
|
||||
@Test
|
||||
public void should_wrap_runnable_in_its_sleuth_representative() {
|
||||
SpanNamer spanNamer = new DefaultSpanNamer();
|
||||
Tracer tracer = new DefaultTracer(new AlwaysSampler(), new Random(), this.publisher, spanNamer);
|
||||
Tracer tracer = new DefaultTracer(new AlwaysSampler(), new Random(), spanNamer,
|
||||
new NoOpSpanLogger(), new NoOpSpanReporter());
|
||||
Span initialSpan = tracer.createSpan("initialSpan");
|
||||
// tag::trace_runnable[]
|
||||
Runnable runnable = new Runnable() {
|
||||
@@ -251,7 +253,8 @@ public class SpringCloudSleuthDocTests {
|
||||
@Test
|
||||
public void should_wrap_callable_in_its_sleuth_representative() {
|
||||
SpanNamer spanNamer = new DefaultSpanNamer();
|
||||
Tracer tracer = new DefaultTracer(new AlwaysSampler(), new Random(), this.publisher, spanNamer);
|
||||
Tracer tracer = new DefaultTracer(new AlwaysSampler(), new Random(), spanNamer,
|
||||
new NoOpSpanLogger(), new NoOpSpanReporter());
|
||||
Span initialSpan = tracer.createSpan("initialSpan");
|
||||
// tag::trace_callable[]
|
||||
Callable<String> callable = new Callable<String>() {
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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"))
|
||||
|
||||
@@ -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<SpanReleasedEvent> events = new ArrayList<>();
|
||||
|
||||
@EventListener
|
||||
public void handle(SpanReleasedEvent event) {
|
||||
this.events.add(event);
|
||||
@Bean
|
||||
ArrayListSpanAccumulator arrayListSpanAccumulator() {
|
||||
return new ArrayListSpanAccumulator();
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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.<ClientHttpRequestInterceptor>asList(
|
||||
new TraceRestTemplateInterceptor(this.tracer)));
|
||||
TestSpanContextHolder.removeCurrentSpan();
|
||||
|
||||
@@ -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.<ClientHttpRequestInterceptor>asList(
|
||||
new TraceRestTemplateInterceptor(this.tracer)));
|
||||
TestSpanContextHolder.removeCurrentSpan();
|
||||
|
||||
@@ -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<ApplicationEvent> events = new ArrayList<>();
|
||||
public static class Listener implements SpanReporter {
|
||||
private List<Span> 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<ApplicationEvent> getEvents() {
|
||||
public List<Span> 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) {
|
||||
|
||||
@@ -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()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
@@ -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<ApplicationEvent> captor = ArgumentCaptor
|
||||
.forClass(ApplicationEvent.class);
|
||||
verify(this.publisher, atLeast(NUM_SPANS)).publishEvent(captor.capture());
|
||||
ArgumentCaptor<Span> captor = ArgumentCaptor
|
||||
.forClass(Span.class);
|
||||
verify(this.spanReporter, atLeast(NUM_SPANS)).report(captor.capture());
|
||||
|
||||
List<Span> spans = new ArrayList<>();
|
||||
for (ApplicationEvent event : captor.getAllValues()) {
|
||||
if (event instanceof SpanReleasedEvent) {
|
||||
spans.add(((SpanReleasedEvent) event).getSpan());
|
||||
}
|
||||
}
|
||||
List<Span> 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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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<Span> 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<Span> 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<Span> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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<Span> 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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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<String> 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.
|
||||
* <ul>
|
||||
@@ -232,4 +172,8 @@ public class ZipkinSpanListener {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void report(Span span) {
|
||||
this.reporter.report(convert(span));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"));
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user