Removed deprecated apis; fixes gh-1564

This commit is contained in:
Marcin Grzejszczak
2020-02-18 13:30:00 +01:00
parent b65e7ca20e
commit 0d237b564f
38 changed files with 53 additions and 1398 deletions

View File

@@ -166,7 +166,6 @@ Starting with version `2.0.0`, Spring Cloud Sleuth uses https://github.com/openz
Consequently, Sleuth no longer takes care of storing the context but delegates that work to Brave.
Due to the fact that Sleuth had different naming and tagging conventions than Brave, we decided to follow Brave's conventions from now on.
However, if you want to use the legacy Sleuth approaches, you can set the `spring.sleuth.http.legacy.enabled` property to `true`.
==== Live examples

View File

@@ -12,12 +12,10 @@
|spring.sleuth.feign.processor.enabled | true | Enable post processor that wraps Feign Context in its tracing representations.
|spring.sleuth.grpc.enabled | true | Enable span information propagation when using GRPC.
|spring.sleuth.http.enabled | true |
|spring.sleuth.http.legacy.enabled | false | Enables the legacy Sleuth setup.
|spring.sleuth.http.legacy.enabled | false |
|spring.sleuth.integration.enabled | true | Enable Spring Integration sleuth instrumentation.
|spring.sleuth.integration.patterns | [!hystrixStreamOutput*, *, !channel*] | An array of patterns against which channel names will be matched. @see org.springframework.integration.config.GlobalChannelInterceptor#patterns() Defaults to any channel name not matching the Hystrix Stream and functional Stream channel names.
|spring.sleuth.integration.websockets.enabled | true | Enable tracing for WebSockets.
|spring.sleuth.keys.http.headers | | Additional headers that should be added as tags if they exist. If the header value is multi-valued, the tag value will be a comma-separated, single-quoted list.
|spring.sleuth.keys.http.prefix | http. | Prefix for header names if they are added as tags.
|spring.sleuth.local-keys | | Same as {@link #propagationKeys} except that this field is not propagated to remote services. @see brave.propagation.ExtraFieldPropagation.FactoryBuilder#addRedactedField(String)
|spring.sleuth.log.slf4j.enabled | true | Enable a {@link Slf4jScopeDecorator} that prints tracing information in the logs.
|spring.sleuth.log.slf4j.whitelisted-mdc-keys | | A list of keys to be put from baggage to MDC.

View File

@@ -118,7 +118,6 @@ Starting with version `2.0.0`, Spring Cloud Sleuth uses https://github.com/openz
Consequently, Sleuth no longer takes care of storing the context but delegates that work to Brave.
Due to the fact that Sleuth had different naming and tagging conventions than Brave, we decided to follow Brave's conventions from now on.
However, if you want to use the legacy Sleuth approaches, you can set the `spring.sleuth.http.legacy.enabled` property to `true`.
==== Live examples

View File

@@ -1,44 +0,0 @@
/*
* Copyright 2013-2019 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
*
* https://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;
import zipkin2.Span;
/**
* Deprecated Span Adjuster.
*
* @deprecated use {@link brave.handler.FinishedSpanHandler}
* @author Marcin Grzejszczak
*/
@Deprecated
public interface SpanAdjuster {
/**
* You can adjust the {@link zipkin2.Span} by creating a new one using the
* {@link Span#toBuilder()} before reporting it.
*
* With the legacy Sleuth approach we're generating spans with a fixed name. Some
* users want to modify the name depending on some values of tags. Implementation of
* this interface can be used to alter then name. Example:
*
* {@code span -> span.toBuilder().name(scrub(span.getName())).build();}
* @param span to adjust
* @return - adjusted span
*/
Span adjust(Span span);
}

View File

@@ -52,7 +52,6 @@ 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.LocalServiceName;
import org.springframework.cloud.sleuth.SpanAdjuster;
import org.springframework.cloud.sleuth.SpanNamer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -83,9 +82,6 @@ public class TraceAutoConfiguration {
*/
public static final String DEFAULT_SERVICE_NAME = "default";
@Autowired(required = false)
List<SpanAdjuster> spanAdjusters = new ArrayList<>();
@Autowired(required = false)
List<FinishedSpanHandler> finishedSpanHandlers = new ArrayList<>();
@@ -116,7 +112,7 @@ public class TraceAutoConfiguration {
.localServiceName(StringUtils.isEmpty(serviceName) ? DEFAULT_SERVICE_NAME
: serviceName)
.propagationFactory(factory).currentTraceContext(currentTraceContext)
.spanReporter(new CompositeReporter(this.spanAdjusters,
.spanReporter(new CompositeReporter(
spanReporters != null ? spanReporters : Collections.emptyList()))
.traceId128Bit(sleuthProperties.isTraceId128())
.supportsJoin(sleuthProperties.isSupportsJoin());
@@ -228,30 +224,21 @@ public class TraceAutoConfiguration {
private static final Log log = LogFactory.getLog(CompositeReporter.class);
private final List<SpanAdjuster> spanAdjusters;
private final Reporter<zipkin2.Span> spanReporter;
private CompositeReporter(List<SpanAdjuster> spanAdjusters,
List<Reporter<Span>> spanReporters) {
this.spanAdjusters = spanAdjusters;
private CompositeReporter(List<Reporter<Span>> spanReporters) {
this.spanReporter = spanReporters.size() == 1 ? spanReporters.get(0)
: new ListReporter(spanReporters);
}
@Override
public void report(Span span) {
Span spanToAdjust = span;
for (SpanAdjuster spanAdjuster : this.spanAdjusters) {
spanToAdjust = spanAdjuster.adjust(spanToAdjust);
}
this.spanReporter.report(spanToAdjust);
this.spanReporter.report(span);
}
@Override
public String toString() {
return "CompositeReporter{" + "spanAdjusters=" + this.spanAdjusters
+ ", spanReporters=" + this.spanReporter + '}';
return "CompositeReporter{ spanReporters=" + this.spanReporter + '}';
}
private static final class ListReporter implements Reporter<zipkin2.Span> {

View File

@@ -1,178 +0,0 @@
/*
* Copyright 2013-2019 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
*
* https://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.instrument.reactor;
import java.util.concurrent.atomic.AtomicBoolean;
import brave.Span;
import brave.Tracer;
import brave.Tracing;
import brave.propagation.CurrentTraceContext;
import brave.propagation.CurrentTraceContext.Scope;
import brave.propagation.TraceContext;
import org.reactivestreams.Subscriber;
import org.reactivestreams.Subscription;
import reactor.util.Logger;
import reactor.util.Loggers;
import reactor.util.context.Context;
/**
* A trace representation of the {@link Subscriber}.
*
* @deprecated use {@link ScopePassingSpanSubscriber} instead
* @param <T> - return type of the subscriber
* @author Stephane Maldini
* @author Marcin Grzejszczak
* @since 2.0.0
*/
@Deprecated
final class SpanSubscriber<T> extends AtomicBoolean implements SpanSubscription<T> {
private static final Logger log = Loggers.getLogger(SpanSubscriber.class);
private final Span span;
private final TraceContext parent;
private final Subscriber<? super T> subscriber;
private final Context context;
private final Tracer tracer;
private final CurrentTraceContext currentTraceContext;
private Subscription s;
SpanSubscriber(Subscriber<? super T> subscriber, Context ctx, Tracing tracing,
String name) {
this.subscriber = subscriber;
this.tracer = tracing.tracer();
this.currentTraceContext = tracing.currentTraceContext();
TraceContext parent = ctx.getOrDefault(TraceContext.class, null);
if (parent == null) {
parent = currentTraceContext.get();
}
if (log.isTraceEnabled()) {
log.trace("Span from context [{}]", parent);
}
this.parent = parent;
if (log.isTraceEnabled()) {
log.trace("Stored context parent span [{}]", this.parent);
}
this.span = parent != null ? this.tracer.newChild(parent).name(name)
: this.tracer.newTrace().name(name);
if (log.isTraceEnabled()) {
log.trace("Created span [{}], with name [{}]", this.span, name);
}
this.context = ctx.put(TraceContext.class, this.span.context());
}
@Override
public void onSubscribe(Subscription subscription) {
if (log.isTraceEnabled()) {
log.trace("On subscribe");
}
this.s = subscription;
try (Scope ws = this.currentTraceContext.maybeScope(this.span.context())) {
if (log.isTraceEnabled()) {
log.trace("On subscribe - span continued");
}
this.subscriber.onSubscribe(this);
}
}
@Override
public void request(long n) {
if (log.isTraceEnabled()) {
log.trace("Request");
}
try (Scope ws = this.currentTraceContext.maybeScope(this.span.context())) {
if (log.isTraceEnabled()) {
log.trace("Request - continued");
}
this.s.request(n);
// no additional cleaning is required cause we operate on scopes
if (log.isTraceEnabled()) {
log.trace("Request after cleaning. Current span [{}]",
this.span.context());
}
}
}
@Override
public void cancel() {
try {
if (log.isTraceEnabled()) {
log.trace("Cancel");
}
this.s.cancel();
}
finally {
cleanup();
}
}
@Override
public void onNext(T o) {
this.subscriber.onNext(o);
}
@Override
public void onError(Throwable throwable) {
try {
this.subscriber.onError(throwable);
}
finally {
cleanup();
}
}
@Override
public void onComplete() {
try {
this.subscriber.onComplete();
}
finally {
cleanup();
}
}
void cleanup() {
if (compareAndSet(false, true)) {
if (log.isTraceEnabled()) {
log.trace("Cleaning up");
}
this.span.finish();
if (log.isTraceEnabled()) {
log.trace("Span closed");
}
if (this.parent != null) {
this.tracer.toSpan(parent).finish(); // TODO: why are we closing this?
if (log.isTraceEnabled()) {
log.trace("Closed parent span");
}
}
}
}
@Override
public Context currentContext() {
return this.context;
}
}

View File

@@ -1,51 +0,0 @@
/*
* Copyright 2013-2019 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
*
* https://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.instrument.web;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.beans.factory.annotation.Qualifier;
/**
* Annotate a client {@link brave.http.HttpSampler} that hsould be injected to
* {@link brave.http.HttpTracing}.
*
* @author Marcin Grzejszczak
* @since 2.0.0
* @see Qualifier
* @deprecated Since 2.2.0, please use {@link HttpClientSampler}
*/
@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE,
ElementType.ANNOTATION_TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
@Qualifier(ClientSampler.NAME)
@Deprecated
public @interface ClientSampler {
/**
* Default name for Sleuth client sampler.
*/
String NAME = "sleuthClientSampler";
}

View File

@@ -1,51 +0,0 @@
/*
* Copyright 2013-2019 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
*
* https://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.instrument.web;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.beans.factory.annotation.Qualifier;
/**
* Annotate a server {@link brave.http.HttpSampler} that hsould be injected to
* {@link brave.http.HttpTracing}.
*
* @author Marcin Grzejszczak
* @since 2.0.0
* @see Qualifier
* @deprecated Since 2.2.0, please use {@link HttpServerSampler}
*/
@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE,
ElementType.ANNOTATION_TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
@Qualifier(ServerSampler.NAME)
@Deprecated
public @interface ServerSampler {
/**
* Default name for the Sleuth server sampler.
*/
String NAME = "sleuthServerSampler";
}

View File

@@ -1,94 +0,0 @@
/*
* Copyright 2013-2019 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
*
* https://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.instrument.web;
import java.net.URI;
import brave.SpanCustomizer;
import brave.http.HttpAdapter;
import brave.http.HttpClientParser;
import org.springframework.cloud.sleuth.util.SpanNameUtil;
/**
* An {@link HttpClientParser} that behaves like Sleuth in versions 1.x.
*
* @author Marcin Grzejszczak
* @since 2.0.0
*/
class SleuthHttpClientParser extends HttpClientParser {
private static final String HOST_KEY = "http.host";
private static final String METHOD_KEY = "http.method";
private static final String PATH_KEY = "http.path";
private static final String URL_KEY = "http.url";
private final TraceKeys traceKeys;
SleuthHttpClientParser(TraceKeys traceKeys) {
this.traceKeys = traceKeys;
}
@Override
protected <Req> String spanName(HttpAdapter<Req, ?> adapter, Req req) {
return getName(URI.create(adapter.url(req)));
}
@Override
public <Req> void request(HttpAdapter<Req, ?> adapter, Req req,
SpanCustomizer customizer) {
super.request(adapter, req, customizer);
String url = adapter.url(req);
URI uri = URI.create(url);
addRequestTags(customizer, url, uri.getHost(), uri.getPath(),
adapter.method(req));
for (String header : this.traceKeys.getHttp().getHeaders()) {
String headerValue = adapter.requestHeader(req, header);
if (headerValue != null) {
customizer.tag(key(header), headerValue);
}
}
}
private String key(String key) {
return this.traceKeys.getHttp().getPrefix() + key.toLowerCase();
}
private String getName(URI uri) {
// The returned name should comply with RFC 882 - Section 3.1.2.
// i.e Header values must composed of printable ASCII values.
return SpanNameUtil.shorten(uriScheme(uri) + ":" + uri.getRawPath());
}
private String uriScheme(URI uri) {
return uri.getScheme() == null ? "http" : uri.getScheme();
}
private void addRequestTags(SpanCustomizer customizer, String url, String host,
String path, String method) {
customizer.tag(URL_KEY, url);
if (host != null) {
customizer.tag(HOST_KEY, host);
}
customizer.tag(PATH_KEY, path);
customizer.tag(METHOD_KEY, method);
}
}

View File

@@ -1,43 +0,0 @@
/*
* Copyright 2013-2019 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
*
* https://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.instrument.web;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* Legacy HTTP Sleuth properties.
*
* @author Marcin Grzejszczak
* @since 2.0.0
*/
@ConfigurationProperties("spring.sleuth.http.legacy")
public class SleuthHttpLegacyProperties {
/**
* Enables the legacy Sleuth setup.
*/
private boolean enabled;
public boolean isEnabled() {
return this.enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
}

View File

@@ -1,87 +0,0 @@
/*
* Copyright 2013-2019 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
*
* https://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.instrument.web;
import javax.servlet.http.HttpServletResponse;
import brave.ErrorParser;
import brave.SpanCustomizer;
import brave.http.HttpAdapter;
import brave.http.HttpClientParser;
import brave.http.HttpServerParser;
/**
* An {@link HttpClientParser} that behaves like Sleuth in versions 1.x.
*
* @author Marcin Grzejszczak
* @since 2.0.0
*/
class SleuthHttpServerParser extends HttpServerParser {
private static final String STATUS_CODE_KEY = "http.status_code";
private final SleuthHttpClientParser clientParser;
private final ErrorParser errorParser;
SleuthHttpServerParser(TraceKeys traceKeys, ErrorParser errorParser) {
this.clientParser = new SleuthHttpClientParser(traceKeys);
this.errorParser = errorParser;
}
@Override
protected ErrorParser errorParser() {
return this.errorParser;
}
@Override
protected <Req> String spanName(HttpAdapter<Req, ?> adapter, Req req) {
return this.clientParser.spanName(adapter, req);
}
@Override
public <Req> void request(HttpAdapter<Req, ?> adapter, Req req,
SpanCustomizer customizer) {
this.clientParser.request(adapter, req, customizer);
}
@Override
public <Resp> void response(HttpAdapter<?, Resp> adapter, Resp res, Throwable error,
SpanCustomizer customizer) {
if (res == null) {
error(null, error, customizer);
return;
}
Integer httpStatus = adapter.statusCode(res);
if (httpStatus == null) {
error(httpStatus, error, customizer);
return;
}
if (httpStatus == HttpServletResponse.SC_OK && error != null) {
// Filter chain threw exception but the response status may not have been set
// yet, so we have to guess.
customizer.tag(STATUS_CODE_KEY,
String.valueOf(HttpServletResponse.SC_INTERNAL_SERVER_ERROR));
}
// only tag valid http statuses
else if (httpStatus >= 100 && (httpStatus < 200) || (httpStatus > 399)) {
customizer.tag(STATUS_CODE_KEY, String.valueOf(httpStatus));
}
error(httpStatus, error, customizer);
}
}

View File

@@ -23,7 +23,6 @@ import brave.ErrorParser;
import brave.Tracing;
import brave.http.HttpClientParser;
import brave.http.HttpRequest;
import brave.http.HttpSampler;
import brave.http.HttpServerParser;
import brave.http.HttpTracing;
import brave.http.HttpTracingCustomizer;
@@ -34,7 +33,6 @@ import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
@@ -52,7 +50,6 @@ import org.springframework.lang.Nullable;
@ConditionalOnProperty(name = "spring.sleuth.http.enabled", havingValue = "true",
matchIfMissing = true)
@AutoConfigureAfter(TraceWebAutoConfiguration.class)
@EnableConfigurationProperties({ TraceKeys.class, SleuthHttpLegacyProperties.class })
public class TraceHttpAutoConfiguration {
static final int TRACING_FILTER_ORDER = Ordered.HIGHEST_PRECEDENCE + 5;
@@ -66,11 +63,7 @@ public class TraceHttpAutoConfiguration {
HttpTracing httpTracing(Tracing tracing, SkipPatternProvider provider,
HttpClientParser clientParser, HttpServerParser serverParser,
@HttpClientSampler SamplerFunction<HttpRequest> httpClientSampler,
@Nullable @ServerSampler HttpSampler serverSampler,
@Nullable @HttpServerSampler SamplerFunction<HttpRequest> httpServerSampler) {
if (httpServerSampler == null) {
httpServerSampler = serverSampler;
}
SamplerFunction<HttpRequest> combinedSampler = combineUserProvidedSamplerWithSkipPatternSampler(
httpServerSampler, provider);
HttpTracing.Builder builder = HttpTracing.newBuilder(tracing)
@@ -94,15 +87,6 @@ public class TraceHttpAutoConfiguration {
}
@Bean
@ConditionalOnProperty(name = "spring.sleuth.http.legacy.enabled",
havingValue = "true")
HttpClientParser sleuthHttpClientParser(TraceKeys traceKeys) {
return new SleuthHttpClientParser(traceKeys);
}
@Bean
@ConditionalOnProperty(name = "spring.sleuth.http.legacy.enabled",
havingValue = "false", matchIfMissing = true)
@ConditionalOnMissingBean
HttpClientParser httpClientParser(ErrorParser errorParser) {
return new HttpClientParser() {
@@ -114,16 +98,6 @@ public class TraceHttpAutoConfiguration {
}
@Bean
@ConditionalOnProperty(name = "spring.sleuth.http.legacy.enabled",
havingValue = "true")
HttpServerParser sleuthHttpServerParser(TraceKeys traceKeys,
ErrorParser errorParser) {
return new SleuthHttpServerParser(traceKeys, errorParser);
}
@Bean
@ConditionalOnProperty(name = "spring.sleuth.http.legacy.enabled",
havingValue = "false", matchIfMissing = true)
@ConditionalOnMissingBean
HttpServerParser defaultHttpServerParser() {
return new HttpServerParser();
@@ -132,11 +106,7 @@ public class TraceHttpAutoConfiguration {
@Bean
@ConditionalOnMissingBean(name = HttpClientSampler.NAME)
SamplerFunction<HttpRequest> sleuthHttpClientSampler(
@Nullable @ClientSampler HttpSampler sleuthClientSampler,
SleuthWebProperties sleuthWebProperties) {
if (sleuthClientSampler != null) {
return sleuthClientSampler;
}
return new SkipPatternHttpClientSampler(sleuthWebProperties);
}

View File

@@ -1,77 +0,0 @@
/*
* Copyright 2013-2019 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
*
* https://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.instrument.web;
import java.util.Collection;
import java.util.LinkedHashSet;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* Well-known {@link brave.Span#tag(String, String) span tag} keys. With the deprecation
* we only left the option to pass a list of HTTP request headers that will be set as tags
*
* @since 1.0.0
* @deprecated the Brave's defaults are suggested to be used
*/
@ConfigurationProperties("spring.sleuth.keys")
@Deprecated
class TraceKeys {
private Http http = new Http();
public Http getHttp() {
return this.http;
}
public void setHttp(Http http) {
this.http = http;
}
public static class Http {
/**
* Prefix for header names if they are added as tags.
*/
private String prefix = "http.";
/**
* Additional headers that should be added as tags if they exist. If the header
* value is multi-valued, the tag value will be a comma-separated, single-quoted
* list.
*/
private Collection<String> headers = new LinkedHashSet<String>();
public String getPrefix() {
return this.prefix;
}
public void setPrefix(String prefix) {
this.prefix = prefix;
}
public Collection<String> getHeaders() {
return this.headers;
}
public void setHeaders(Collection<String> headers) {
this.headers = headers;
}
}
}

View File

@@ -1,167 +0,0 @@
/*
* Copyright 2013-2019 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
*
* https://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.log;
import brave.internal.HexCodec;
import brave.internal.Nullable;
import brave.propagation.CurrentTraceContext;
import brave.propagation.TraceContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
/**
* Adds {@linkplain org.slf4j.MDC} properties "traceId", "parentId", "spanId" and
* "spanExportable" when a {@link brave.Tracer#currentSpan() span is current}. These can
* be used in log correlation. Supports backward compatibility of MDC entries by adding
* legacy "X-B3" entries to MDC context "X-B3-TraceId", "X-B3-ParentSpanId", "X-B3-SpanId"
* and "X-B3-Sampled"
*
* Due to the migration to {@link brave.propagation.CurrentTraceContext.ScopeDecorator}
* approach, we are making the default implementation package scope since you can register
* your own implementation of the Scope Decorator.
*
* @author Marcin Grzejszczak
* @since 2.0.0
* @deprecated {@link Slf4jScopeDecorator} will be used
*/
@Deprecated
public final class Slf4jCurrentTraceContext extends CurrentTraceContext {
// Backward compatibility for all logging patterns
private static final String LEGACY_EXPORTABLE_NAME = "X-Span-Export";
private static final String LEGACY_PARENT_ID_NAME = "X-B3-ParentSpanId";
private static final String LEGACY_TRACE_ID_NAME = "X-B3-TraceId";
private static final String LEGACY_SPAN_ID_NAME = "X-B3-SpanId";
private static final Logger log = LoggerFactory
.getLogger(Slf4jCurrentTraceContext.class);
final CurrentTraceContext delegate;
Slf4jCurrentTraceContext(CurrentTraceContext delegate) {
if (delegate == null) {
throw new NullPointerException("delegate == null");
}
this.delegate = delegate;
}
public static Slf4jCurrentTraceContext create() {
return create(CurrentTraceContext.Default.inheritable());
}
public static Slf4jCurrentTraceContext create(CurrentTraceContext delegate) {
return new Slf4jCurrentTraceContext(delegate);
}
static void replace(String key, @Nullable String value) {
if (value != null) {
MDC.put(key, value);
}
else {
MDC.remove(key);
}
}
@Override
public TraceContext get() {
return this.delegate.get();
}
@Override
public Scope newScope(@Nullable TraceContext currentSpan) {
final String previousTraceId = MDC.get("traceId");
final String previousParentId = MDC.get("parentId");
final String previousSpanId = MDC.get("spanId");
final String spanExportable = MDC.get("spanExportable");
final String legacyPreviousTraceId = MDC.get(LEGACY_TRACE_ID_NAME);
final String legacyPreviousParentId = MDC.get(LEGACY_PARENT_ID_NAME);
final String legacyPreviousSpanId = MDC.get(LEGACY_SPAN_ID_NAME);
final String legacySpanExportable = MDC.get(LEGACY_EXPORTABLE_NAME);
if (currentSpan != null) {
String traceIdString = currentSpan.traceIdString();
MDC.put("traceId", traceIdString);
MDC.put(LEGACY_TRACE_ID_NAME, traceIdString);
String parentId = currentSpan.parentId() != null
? HexCodec.toLowerHex(currentSpan.parentId()) : null;
replace("parentId", parentId);
replace(LEGACY_PARENT_ID_NAME, parentId);
String spanId = HexCodec.toLowerHex(currentSpan.spanId());
MDC.put("spanId", spanId);
MDC.put(LEGACY_SPAN_ID_NAME, spanId);
String sampled = String.valueOf(currentSpan.sampled());
MDC.put("spanExportable", sampled);
MDC.put(LEGACY_EXPORTABLE_NAME, sampled);
log("Starting scope for span: {}", currentSpan);
if (currentSpan.parentId() != null) {
if (log.isTraceEnabled()) {
log.trace("With parent: {}", currentSpan.parentId());
}
}
}
else {
MDC.remove("traceId");
MDC.remove("parentId");
MDC.remove("spanId");
MDC.remove("spanExportable");
MDC.remove(LEGACY_TRACE_ID_NAME);
MDC.remove(LEGACY_PARENT_ID_NAME);
MDC.remove(LEGACY_SPAN_ID_NAME);
MDC.remove(LEGACY_EXPORTABLE_NAME);
}
Scope scope = this.delegate.newScope(currentSpan);
/**
* Thread context scope.
*
* @author Adrian Cole
*/
class ThreadContextCurrentTraceContextScope implements Scope {
@Override
public void close() {
log("Closing scope for span: {}", currentSpan);
scope.close();
replace("traceId", previousTraceId);
replace("parentId", previousParentId);
replace("spanId", previousSpanId);
replace("spanExportable", spanExportable);
replace(LEGACY_TRACE_ID_NAME, legacyPreviousTraceId);
replace(LEGACY_PARENT_ID_NAME, legacyPreviousParentId);
replace(LEGACY_SPAN_ID_NAME, legacyPreviousSpanId);
replace(LEGACY_EXPORTABLE_NAME, legacySpanExportable);
}
}
return new ThreadContextCurrentTraceContextScope();
}
private void log(String text, TraceContext span) {
if (span == null) {
return;
}
if (log.isTraceEnabled()) {
log.trace(text, span);
}
}
}

View File

@@ -1,88 +0,0 @@
/*
* Copyright 2013-2019 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
*
* https://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;
import brave.Span;
import brave.Tracer;
import brave.sampler.Sampler;
import org.assertj.core.api.BDDAssertions;
import org.junit.Test;
import org.junit.runner.RunWith;
import zipkin2.reporter.Reporter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.integration.IntegrationAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.sleuth.util.ArrayListSpanReporter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.junit4.SpringRunner;
/**
* @author Marcin Grzejszczak
*/
@RunWith(SpringRunner.class)
@SpringBootTest(classes = SpanAdjusterTests.SpanAdjusterAspectTestsConfig.class,
webEnvironment = SpringBootTest.WebEnvironment.NONE)
public class SpanAdjusterTests {
@Autowired
ArrayListSpanReporter reporter;
@Autowired
Tracer tracer;
@Test
public void should_adjust_span_twice_before_reporting() {
Span hello = this.tracer.nextSpan().name("hello").start();
hello.finish();
BDDAssertions.then(this.reporter.getSpans()).hasSize(1);
BDDAssertions.then(this.reporter.getSpans().get(0).name()).isEqualTo("foo bar");
}
@Configuration
@EnableAutoConfiguration(exclude = IntegrationAutoConfiguration.class)
static class SpanAdjusterAspectTestsConfig {
@Bean
Sampler sampler() {
return Sampler.ALWAYS_SAMPLE;
}
@Bean
Reporter<zipkin2.Span> reporter() {
return new ArrayListSpanReporter();
}
// tag::adjuster[]
@Bean
SpanAdjuster adjusterOne() {
return span -> span.toBuilder().name("foo").build();
}
@Bean
SpanAdjuster adjusterTwo() {
return span -> span.toBuilder().name(span.name() + " bar").build();
}
// end::adjuster[]
}
}

View File

@@ -54,8 +54,8 @@ import static org.awaitility.Awaitility.await;
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
@RunWith(SpringJUnit4ClassRunner.class)
@TestPropertySource(properties = { "spring.application.name=multiplehopsintegrationtests",
"spring.sleuth.http.legacy.enabled=true" })
@TestPropertySource(
properties = { "spring.application.name=multiplehopsintegrationtests" })
@SpringBootTest(classes = MultipleHopsIntegrationTests.Config.class,
webEnvironment = RANDOM_PORT)
@ActiveProfiles("baggage")
@@ -90,7 +90,7 @@ public class MultipleHopsIntegrationTests {
then(this.reporter.getSpans()).hasSize(14);
});
then(this.reporter.getSpans().stream().map(zipkin2.Span::name).collect(toList()))
.containsAll(asList("http:/greeting", "send"));
.containsAll(asList("get /greeting", "send"));
then(this.reporter.getSpans().stream().map(zipkin2.Span::kind)
// no server kind due to test constraints
.collect(toList()))

View File

@@ -44,7 +44,6 @@ import static org.assertj.core.api.BDDAssertions.then;
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
properties = { "management.endpoints.web.exposure.include:*",
"server.servlet.context-path:/context-path",
"spring.sleuth.http.legacy.enabled:true",
"spring.sleuth.web.ignoreAutoConfiguredSkipPatterns:true" })
public class IgnoreAutoConfiguredSkipPatternsIntegrationTests {

View File

@@ -44,8 +44,7 @@ import static org.assertj.core.api.BDDAssertions.then;
classes = SkipEndPointsIntegrationTestsWithContextPathWithBasePath.Config.class,
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
properties = { "management.endpoints.web.exposure.include:*",
"server.servlet.context-path:/context-path",
"spring.sleuth.http.legacy.enabled:true" })
"server.servlet.context-path:/context-path" })
public class SkipEndPointsIntegrationTestsWithContextPathWithBasePath {
@Autowired

View File

@@ -45,7 +45,6 @@ import static org.assertj.core.api.BDDAssertions.then;
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
properties = { "management.endpoints.web.exposure.include:*",
"server.servlet.context-path:/context-path",
"spring.sleuth.http.legacy.enabled:true",
"management.endpoints.web.base-path:/" })
public class SkipEndPointsIntegrationTestsWithContextPathWithoutBasePath {

View File

@@ -43,8 +43,7 @@ import static org.assertj.core.api.BDDAssertions.then;
@SpringBootTest(
classes = SkipEndPointsIntegrationTestsWithoutContextPathWithBasePath.Config.class,
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
properties = { "management.endpoints.web.exposure.include:*",
"spring.sleuth.http.legacy.enabled:true" })
properties = { "management.endpoints.web.exposure.include:*" })
public class SkipEndPointsIntegrationTestsWithoutContextPathWithBasePath {
@LocalServerPort

View File

@@ -44,7 +44,6 @@ import static org.assertj.core.api.BDDAssertions.then;
classes = SkipEndPointsIntegrationTestsWithoutContextPathWithoutBasePath.Config.class,
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
properties = { "management.endpoints.web.exposure.include:*",
"spring.sleuth.http.legacy.enabled:true",
"management.endpoints.web.base-path:/" })
public class SkipEndPointsIntegrationTestsWithoutContextPathWithoutBasePath {

View File

@@ -1,105 +0,0 @@
/*
* Copyright 2013-2019 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
*
* https://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.instrument.web;
import java.net.URL;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import brave.SpanCustomizer;
import brave.http.HttpClientAdapter;
import org.junit.Test;
import static org.assertj.core.api.BDDAssertions.then;
/**
* Test case for HttpTraceKeysInjector.
*
* @author Sven Zethelius
*/
public class SleuthHttpClientParserTests {
private TraceKeys traceKeys = new TraceKeys();
private TestSpanCustomizer customizer = new TestSpanCustomizer();
private SleuthHttpClientParser parser = new SleuthHttpClientParser(this.traceKeys);
@Test
public void should_set_tags_on_span_with_proper_header_values() throws Exception {
this.traceKeys.getHttp()
.setHeaders(Arrays.asList("Accept", "User-Agent", "Content-Type"));
this.parser.request(new HttpClientAdapter<Object, Object>() {
private final URL url = new URL("http://localhost:8080/");
@Override
public String method(Object request) {
return "GET";
}
@Override
public String url(Object request) {
return this.url.toString();
}
@Override
public String requestHeader(Object request, String name) {
if (name.equals("Accept")) {
return "'text/plain','text/xml'";
}
else if (name.equals("User-Agent")) {
return "Test";
}
return null;
}
@Override
public Integer statusCode(Object response) {
return 200;
}
}, null, this.customizer);
then(this.customizer.tags).containsEntry("http.user-agent", "Test")
.containsEntry("http.accept", "'text/plain','text/xml'")
.doesNotContainKey("http.content-type");
}
}
class TestSpanCustomizer implements SpanCustomizer {
Map<String, String> tags = new HashMap<>();
@Override
public SpanCustomizer name(String name) {
return this;
}
@Override
public SpanCustomizer tag(String key, String value) {
this.tags.put(key, value);
return this;
}
@Override
public SpanCustomizer annotate(String value) {
return this;
}
}

View File

@@ -1,41 +0,0 @@
/*
* Copyright 2013-2019 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
*
* https://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.instrument.web;
import brave.ErrorParser;
import brave.http.HttpClientParser;
import brave.http.HttpServerParser;
/**
* @author Marcin Grzejszczak
* @since
*/
public final class SleuthHttpParserAccessor {
private SleuthHttpParserAccessor() {
throw new IllegalStateException("Can't instantiate a utility class");
}
public static HttpClientParser getClient() {
return new SleuthHttpClientParser(new TraceKeys());
}
public static HttpServerParser getServer(ErrorParser errorParser) {
return new SleuthHttpServerParser(new TraceKeys(), errorParser);
}
}

View File

@@ -21,10 +21,11 @@ import java.util.regex.Pattern;
import javax.servlet.Filter;
import brave.ErrorParser;
import brave.Span;
import brave.Tracer;
import brave.Tracing;
import brave.http.HttpClientParser;
import brave.http.HttpServerParser;
import brave.http.HttpTracing;
import brave.propagation.StrictScopeDecorator;
import brave.propagation.ThreadLocalCurrentTraceContext;
@@ -70,11 +71,8 @@ public class TraceFilterTests {
Tracer tracer = this.tracing.tracer();
TraceKeys traceKeys = new TraceKeys();
HttpTracing httpTracing = HttpTracing.newBuilder(this.tracing)
.clientParser(new SleuthHttpClientParser(this.traceKeys))
.serverParser(new SleuthHttpServerParser(this.traceKeys, new ErrorParser()))
.clientParser(new HttpClientParser()).serverParser(new HttpServerParser())
.serverSampler(new SkipPatternHttpServerSampler(() -> Pattern.compile("")))
.build();
@@ -122,9 +120,7 @@ public class TraceFilterTests {
.spanReporter(this.reporter).sampler(Sampler.NEVER_SAMPLE)
.supportsJoin(false).build();
HttpTracing httpTracing = HttpTracing.newBuilder(tracing)
.clientParser(new SleuthHttpClientParser(this.traceKeys))
.serverParser(
new SleuthHttpServerParser(this.traceKeys, new ErrorParser()))
.clientParser(new HttpClientParser()).serverParser(new HttpServerParser())
.serverSampler(
new SkipPatternHttpServerSampler(() -> Pattern.compile("")))
.build();
@@ -136,9 +132,7 @@ public class TraceFilterTests {
this.filter.doFilter(this.request, this.response, this.filterChain);
then(this.reporter.getSpans()).hasSize(1);
then(this.reporter.getSpans().get(0).tags())
.containsEntry("http.url", "http://localhost/?foo=bar")
.containsEntry("http.host", "localhost").containsEntry("http.path", "/")
then(this.reporter.getSpans().get(0).tags()).containsEntry("http.path", "/")
.containsEntry("http.method", HttpMethod.GET.toString());
// we don't check for status_code anymore cause Brave doesn't support it oob
// .containsEntry("http.status_code", "200")
@@ -168,9 +162,7 @@ public class TraceFilterTests {
then(Tracing.current().tracer().currentSpan()).isNull();
then(this.reporter.getSpans()).hasSize(1);
then(this.reporter.getSpans().get(0).id()).isEqualTo(PARENT_ID);
then(this.reporter.getSpans().get(0).tags())
.containsEntry("http.url", "http://localhost/?foo=bar")
.containsEntry("http.host", "localhost").containsEntry("http.path", "/")
then(this.reporter.getSpans().get(0).tags()).containsEntry("http.path", "/")
.containsEntry("http.method", HttpMethod.GET.toString());
}
@@ -252,37 +244,6 @@ public class TraceFilterTests {
then(this.reporter.getSpans().get(0).parentId()).isEqualTo(PARENT_ID);
}
@Test
public void addsAdditionalHeaders() throws Exception {
this.request = builder().header(SPAN_ID_NAME, PARENT_ID)
.header(TRACE_ID_NAME, SpanUtil.idToHex(20L))
.buildRequest(new MockServletContext());
this.traceKeys.getHttp().getHeaders().add("x-foo");
this.request.addHeader("X-Foo", "bar");
this.filter.doFilter(this.request, this.response, this.filterChain);
then(Tracing.current().tracer().currentSpan()).isNull();
then(this.reporter.getSpans()).hasSize(1);
then(this.reporter.getSpans().get(0).tags()).containsEntry("http.x-foo", "bar");
}
@Test
public void additionalMultiValuedHeader() throws Exception {
this.request = builder().header(SPAN_ID_NAME, PARENT_ID)
.header(TRACE_ID_NAME, SpanUtil.idToHex(20L))
.buildRequest(new MockServletContext());
this.traceKeys.getHttp().getHeaders().add("x-foo");
this.request.addHeader("X-Foo", "bar");
this.request.addHeader("X-Foo", "spam");
this.filter.doFilter(this.request, this.response, this.filterChain);
then(Tracing.current().tracer().currentSpan()).isNull();
then(this.reporter.getSpans()).hasSize(1);
// We no longer support multi value headers
then(this.reporter.getSpans().get(0).tags()).containsEntry("http.x-foo", "bar");
}
@Test
public void shouldAnnotateSpanWithErrorWhenExceptionIsThrown() throws Exception {
this.request = builder().header(SPAN_ID_NAME, PARENT_ID)
@@ -305,7 +266,7 @@ public class TraceFilterTests {
}
then(Tracing.current().tracer().currentSpan()).isNull();
verifyParentSpanHttpTags(HttpStatus.INTERNAL_SERVER_ERROR);
verifyParentSpanHttpTags();
then(this.reporter.getSpans()).hasSize(1);
then(this.reporter.getSpans().get(0).tags()).containsEntry("error", "Planned");
}
@@ -438,9 +399,7 @@ public class TraceFilterTests {
then(Tracing.current().tracer().currentSpan()).isNull();
then(this.reporter.getSpans()).hasSize(1);
then(this.reporter.getSpans().get(0).tags())
.containsEntry("http.url", "http://localhost/?foo=bar")
.containsEntry("http.host", "localhost").containsEntry("http.path", "/")
then(this.reporter.getSpans().get(0).tags()).containsEntry("http.path", "/")
.containsEntry("http.method", HttpMethod.GET.toString());
// we don't check for status_code anymore cause Brave doesn't support it oob
// .containsEntry("http.status_code", "295")
@@ -455,41 +414,13 @@ public class TraceFilterTests {
then(Tracing.current().tracer().currentSpan()).isNull();
then(this.reporter.getSpans()).hasSize(1);
then(this.reporter.getSpans().get(0).name()).isEqualTo("http:/");
then(this.reporter.getSpans().get(0).name()).isEqualTo("get");
}
public void verifyParentSpanHttpTags() {
verifyParentSpanHttpTags(HttpStatus.OK);
}
/**
* Shows the expansion of {@link import
* org.springframework.cloud.sleuth.instrument.TraceKeys}.
* @param status http status
*/
public void verifyParentSpanHttpTags(HttpStatus status) {
then(this.reporter.getSpans().size()).isGreaterThan(0);
then(this.reporter.getSpans().get(0).tags())
.containsEntry("http.url", "http://localhost/?foo=bar")
.containsEntry("http.host", "localhost").containsEntry("http.path", "/")
then(this.reporter.getSpans().get(0).tags()).containsEntry("http.path", "/")
.containsEntry("http.method", HttpMethod.GET.toString());
verifyCurrentSpanStatusCodeForAContinuedSpan(status);
}
private void verifyCurrentSpanStatusCodeForAContinuedSpan(HttpStatus status) {
// Status is only interesting in non-success case. Omitting it saves at least
// 20bytes per span.
if (status.is2xxSuccessful()) {
then(this.reporter.getSpans()).hasSize(1);
then(this.reporter.getSpans().get(0).tags())
.doesNotContainKey("http.status_code");
}
else {
then(this.reporter.getSpans()).hasSize(1);
then(this.reporter.getSpans().get(0).tags()).containsEntry("http.status_code",
"500");
}
}
}

View File

@@ -16,9 +16,7 @@
package org.springframework.cloud.sleuth.instrument.web;
import brave.http.HttpAdapter;
import brave.http.HttpRequest;
import brave.http.HttpSampler;
import brave.http.HttpTracing;
import brave.sampler.SamplerFunction;
import org.junit.Test;
@@ -45,17 +43,6 @@ public class TraceHttpAutoConfigurationTests {
});
}
@Test
public void configuresUserProvidedDeprecatedClientSampler() {
contextRunner().withUserConfiguration(DeprecatedClientSamplerConfig.class)
.run((context) -> {
SamplerFunction<HttpRequest> clientSampler = context
.getBean(HttpTracing.class).clientRequestSampler();
then(clientSampler).isSameAs(DeprecatedClientSamplerConfig.INSTANCE);
});
}
@Test
public void configuresUserProvidedHttpClientSampler() {
contextRunner().withUserConfiguration(HttpClientSamplerConfig.class)
@@ -67,17 +54,6 @@ public class TraceHttpAutoConfigurationTests {
});
}
@Test
public void prefersUserProvidedHttpClientSampler() {
contextRunner().withUserConfiguration(DeprecatedClientSamplerConfig.class)
.withUserConfiguration(HttpClientSamplerConfig.class).run((context) -> {
SamplerFunction<HttpRequest> clientSampler = context
.getBean(HttpTracing.class).clientRequestSampler();
then(clientSampler).isSameAs(HttpClientSamplerConfig.INSTANCE);
});
}
@Test
public void defaultsToSkipPatternHttpServerSampler() {
contextRunner().run((context) -> {
@@ -88,25 +64,12 @@ public class TraceHttpAutoConfigurationTests {
});
}
@Test
public void wrapsUserProvidedDeprecatedServerSampler() {
contextRunner().withUserConfiguration(DeprecatedServerSamplerConfig.class).run(
thenCompositeHttpServerSamplerOf(DeprecatedServerSamplerConfig.INSTANCE));
}
@Test
public void wrapsUserProvidedHttpServerSampler() {
contextRunner().withUserConfiguration(HttpServerSamplerConfig.class)
.run(thenCompositeHttpServerSamplerOf(HttpServerSamplerConfig.INSTANCE));
}
@Test
public void prefersUserProvidedUserProvidedHttpServerSampler() {
contextRunner().withUserConfiguration(HttpServerSamplerConfig.class)
.withUserConfiguration(DeprecatedServerSamplerConfig.class)
.run(thenCompositeHttpServerSamplerOf(HttpServerSamplerConfig.INSTANCE));
}
private ContextConsumer<AssertableApplicationContext> thenCompositeHttpServerSamplerOf(
SamplerFunction<HttpRequest> instance) {
return (context) -> {
@@ -143,23 +106,6 @@ class HttpClientSamplerConfig {
}
@Configuration
class DeprecatedClientSamplerConfig {
static final HttpSampler INSTANCE = new HttpSampler() {
@Override
public <Req> Boolean trySample(HttpAdapter<Req, ?> httpAdapter, Req req) {
return null;
}
};
@Bean(ClientSampler.NAME)
HttpSampler sleuthClientSampler() {
return INSTANCE;
}
}
@Configuration
class HttpServerSamplerConfig {
@@ -171,20 +117,3 @@ class HttpServerSamplerConfig {
}
}
@Configuration
class DeprecatedServerSamplerConfig {
static final HttpSampler INSTANCE = new HttpSampler() {
@Override
public <Req> Boolean trySample(HttpAdapter<Req, ?> httpAdapter, Req req) {
return null;
}
};
@Bean(ServerSampler.NAME)
HttpSampler sleuthServerSampler() {
return INSTANCE;
}
}

View File

@@ -24,6 +24,7 @@ import java.util.Map;
import brave.Span;
import brave.Tracer;
import brave.Tracing;
import brave.http.HttpClientParser;
import brave.http.HttpTracing;
import brave.propagation.StrictScopeDecorator;
import brave.propagation.ThreadLocalCurrentTraceContext;
@@ -63,8 +64,6 @@ public class TraceRestTemplateInterceptorTests {
Tracer tracer = this.tracing.tracer();
TraceKeys traceKeys = new TraceKeys();
private TestController testController = new TestController();
private MockMvc mockMvc = MockMvcBuilders.standaloneSetup(this.testController)
@@ -122,7 +121,7 @@ public class TraceRestTemplateInterceptorTests {
@Test
public void requestHeadersAddedWhenTracing() {
setInterceptors(HttpTracing.newBuilder(this.tracing)
.clientParser(new SleuthHttpClientParser(this.traceKeys)).build());
.clientParser(new HttpClientParser()).build());
Span span = this.tracer.nextSpan().name("new trace");
try (Tracer.SpanInScope ws = this.tracer.withSpanInScope(span.start())) {
@@ -134,8 +133,8 @@ public class TraceRestTemplateInterceptorTests {
List<zipkin2.Span> spans = this.reporter.getSpans();
then(spans).isNotEmpty();
then(spans.get(0).tags()).containsEntry("http.url", "/foo?a=b")
.containsEntry("http.path", "/foo").containsEntry("http.method", "GET");
then(spans.get(0).tags()).containsEntry("http.path", "/foo")
.containsEntry("http.method", "GET");
}
@Test
@@ -182,7 +181,7 @@ public class TraceRestTemplateInterceptorTests {
@Test
public void createdSpanNameHasOnlyPrintableAsciiCharactersForNonEncodedURIWithNonAsciiChars() {
setInterceptors(HttpTracing.newBuilder(this.tracing)
.clientParser(new SleuthHttpClientParser(this.traceKeys)).build());
.clientParser(new HttpClientParser()).build());
Span span = this.tracer.nextSpan().name("new trace");
try (Tracer.SpanInScope ws = this.tracer.withSpanInScope(span.start())) {
@@ -197,57 +196,6 @@ public class TraceRestTemplateInterceptorTests {
List<zipkin2.Span> spans = this.reporter.getSpans();
then(spans).hasSize(2);
String spanName = spans.get(0).name();
then(spanName).isEqualTo("http:/cas~fs~%c3%a5%cb%86%e2%80%99");
then(isAsciiPrintable(spanName));
}
@Test
public void willShortenTheNameOfTheSpan() {
setInterceptors(HttpTracing.newBuilder(this.tracing)
.clientParser(new SleuthHttpClientParser(this.traceKeys)).build());
Span span = this.tracer.nextSpan().name("new trace");
try (Tracer.SpanInScope ws = this.tracer.withSpanInScope(span.start())) {
this.template.getForEntity("/" + bigName(), Map.class).getBody();
}
catch (Exception e) {
}
finally {
span.finish();
}
List<zipkin2.Span> spans = this.reporter.getSpans();
then(spans).isNotEmpty();
String spanName = spans.get(0).name();
then(spanName).hasSize(50);
then(isAsciiPrintable(spanName));
}
private String bigName() {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 60; i++) {
sb.append("a");
}
return sb.toString();
}
private static boolean isAsciiPrintable(String str) {
if (str == null) {
return false;
}
int sz = str.length();
for (int i = 0; i < sz; i++) {
if (!isAsciiPrintable(str.charAt(i))) {
return false;
}
}
return true;
}
private static boolean isAsciiPrintable(char ch) {
return ch >= 32 && ch < 127;
}
@RestController

View File

@@ -61,8 +61,7 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = { WebClientDiscoveryExceptionTests.TestConfiguration.class },
webEnvironment = RANDOM_PORT)
@TestPropertySource(properties = { "spring.application.name=exceptionservice",
"spring.sleuth.http.legacy.enabled=true" })
@TestPropertySource(properties = { "spring.application.name=exceptionservice" })
@DirtiesContext
public class WebClientDiscoveryExceptionTests {

View File

@@ -22,6 +22,7 @@ import java.util.HashMap;
import java.util.concurrent.atomic.AtomicInteger;
import brave.Tracing;
import brave.http.HttpClientParser;
import brave.http.HttpTracing;
import brave.propagation.StrictScopeDecorator;
import brave.propagation.ThreadLocalCurrentTraceContext;
@@ -44,7 +45,6 @@ import org.mockito.junit.MockitoJUnitRunner;
import zipkin2.Span;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.cloud.sleuth.instrument.web.SleuthHttpParserAccessor;
import org.springframework.cloud.sleuth.util.ArrayListSpanReporter;
import static org.assertj.core.api.Assertions.failBecauseExceptionWasNotThrown;
@@ -70,7 +70,7 @@ public class FeignRetriesTests {
.spanReporter(this.reporter).build();
HttpTracing httpTracing = HttpTracing.newBuilder(this.tracing)
.clientParser(SleuthHttpParserAccessor.getClient()).build();
.clientParser(new HttpClientParser()).build();
@Before
@After

View File

@@ -19,6 +19,7 @@ package org.springframework.cloud.sleuth.instrument.web.client.feign;
import java.io.IOException;
import brave.Tracing;
import brave.http.HttpClientParser;
import brave.http.HttpTracing;
import brave.propagation.StrictScopeDecorator;
import brave.propagation.ThreadLocalCurrentTraceContext;
@@ -31,7 +32,6 @@ import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.cloud.sleuth.instrument.web.SleuthHttpParserAccessor;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.never;
@@ -58,7 +58,7 @@ public class TraceFeignAspectTests {
.build();
HttpTracing httpTracing = HttpTracing.newBuilder(this.tracing)
.clientParser(SleuthHttpParserAccessor.getClient()).build();
.clientParser(new HttpClientParser()).build();
TraceFeignAspect traceFeignAspect;

View File

@@ -24,6 +24,7 @@ import java.util.List;
import brave.Span;
import brave.Tracer;
import brave.Tracing;
import brave.http.HttpClientParser;
import brave.http.HttpTracing;
import brave.propagation.StrictScopeDecorator;
import brave.propagation.ThreadLocalCurrentTraceContext;
@@ -37,8 +38,6 @@ import org.mockito.BDDMockito;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.cloud.sleuth.instrument.web.SleuthHttpParserAccessor;
import static org.assertj.core.api.BDDAssertions.then;
/**
@@ -61,7 +60,7 @@ public class TracingFeignClientTests {
Tracer tracer = this.tracing.tracer();
HttpTracing httpTracing = HttpTracing.newBuilder(this.tracing)
.clientParser(SleuthHttpParserAccessor.getClient()).build();
.clientParser(new HttpClientParser()).build();
@Mock
Client client;
@@ -109,20 +108,4 @@ public class TracingFeignClientTests {
then(this.spans.get(0).tags()).containsEntry("error", "exception has occurred");
}
@Test
public void should_shorten_the_span_name() throws IOException {
this.traceFeignClient.execute(Request.create("GET", "https://foo/" + bigName(),
new HashMap<>(), null, null), this.options);
then(this.spans.get(0).name()).hasSize(50);
}
private String bigName() {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 60; i++) {
sb.append("a");
}
return sb.toString();
}
}

View File

@@ -100,9 +100,8 @@ import static org.assertj.core.api.BDDAssertions.then;
@RunWith(JUnitParamsRunner.class)
@SpringBootTest(classes = WebClientTests.TestConfiguration.class,
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@TestPropertySource(properties = { "spring.sleuth.http.legacy.enabled=true",
"spring.application.name=fooservice", "feign.hystrix.enabled=false",
"spring.sleuth.web.client.skip-pattern=/skip.*" })
@TestPropertySource(properties = { "spring.application.name=fooservice",
"feign.hystrix.enabled=false", "spring.sleuth.web.client.skip-pattern=/skip.*" })
@DirtiesContext
public class WebClientTests {
@@ -179,8 +178,7 @@ public class WebClientTests {
List<zipkin2.Span> spans = this.reporter.getSpans();
then(spans).isNotEmpty();
Optional<zipkin2.Span> noTraceSpan = new ArrayList<>(spans).stream()
.filter(span -> "http:/notrace".equals(span.name())
&& !span.tags().isEmpty()
.filter(span -> "get".equals(span.name()) && !span.tags().isEmpty()
&& span.tags().containsKey("http.path"))
.findFirst();
then(noTraceSpan.isPresent()).isTrue();
@@ -188,7 +186,7 @@ public class WebClientTests {
.containsEntry("http.method", "GET");
// TODO: matches cause there is an issue with Feign not providing the full URL
// at the interceptor level
then(noTraceSpan.get().tags().get("http.url")).matches(".*/notrace");
then(noTraceSpan.get().tags().get("http.path")).matches(".*/notrace");
});
then(this.tracer.currentSpan()).isNull();
}

View File

@@ -48,8 +48,7 @@ import static org.assertj.core.api.BDDAssertions.then;
classes = { IntegrationSpanCollectorConfig.class,
SampleMessagingApplication.class },
webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
@TestPropertySource(properties = { "sample.zipkin.enabled=true",
"spring.sleuth.http.legacy.enabled=true" })
@TestPropertySource(properties = { "sample.zipkin.enabled=true" })
@DirtiesContext
public class MessagingApplicationTests extends AbstractIntegrationTest {
@@ -149,7 +148,7 @@ public class MessagingApplicationTests extends AbstractIntegrationTest {
private Optional<Span> findLastHttpSpansParent() {
return this.integrationTestSpanCollector.hashedSpans.stream()
.filter(span -> "http:/".equals(span.name()) && span.kind() != null)
.filter(span -> "get /".equals(span.name()) && span.kind() != null)
.findFirst();
}

View File

@@ -31,17 +31,6 @@ import org.springframework.web.client.RestTemplate;
*/
public interface ZipkinRestTemplateCustomizer {
/**
* Customizes the {@link RestTemplate}.
* @deprecated use
* {@link ZipkinRestTemplateCustomizer#customizeTemplate(RestTemplate)}
* @param restTemplate object to customize
*/
@Deprecated
default void customize(RestTemplate restTemplate) {
customizeTemplate(restTemplate);
};
/**
* Customizes the {@link RestTemplate} instance. Might return a new one if necessary.
* @param restTemplate default object to customize

View File

@@ -84,7 +84,7 @@ public class ZipkinAutoConfigurationTests {
this.server.url("/").toString());
this.context.register(ZipkinAutoConfiguration.class,
PropertyPlaceholderAutoConfiguration.class, TraceAutoConfiguration.class,
Config.class, ZipkinBackwardsCompatibilityAutoConfiguration.class);
Config.class);
this.context.refresh();
Span span = this.context.getBean(Tracing.class).tracer().nextSpan().name("foo")
.tag("foo", "bar").start();
@@ -114,7 +114,7 @@ public class ZipkinAutoConfigurationTests {
environment().setProperty("spring.zipkin.encoder", "JSON_V1");
this.context.register(ZipkinAutoConfiguration.class,
PropertyPlaceholderAutoConfiguration.class, TraceAutoConfiguration.class,
Config.class, ZipkinBackwardsCompatibilityAutoConfiguration.class);
Config.class);
this.context.refresh();
Span span = this.context.getBean(Tracing.class).tracer().nextSpan().name("foo")
.tag("foo", "bar").start();
@@ -138,8 +138,7 @@ public class ZipkinAutoConfigurationTests {
environment().setProperty("spring.zipkin.sender.type", "rabbit");
this.context.register(PropertyPlaceholderAutoConfiguration.class,
RabbitAutoConfiguration.class, ZipkinAutoConfiguration.class,
TraceAutoConfiguration.class,
ZipkinBackwardsCompatibilityAutoConfiguration.class);
TraceAutoConfiguration.class);
this.context.refresh();
then(this.context.getBean(Sender.class)).isInstanceOf(RabbitMQSender.class);
@@ -154,8 +153,7 @@ public class ZipkinAutoConfigurationTests {
environment().setProperty("spring.zipkin.sender.type", "kafka");
this.context.register(PropertyPlaceholderAutoConfiguration.class,
KafkaAutoConfiguration.class, ZipkinAutoConfiguration.class,
TraceAutoConfiguration.class,
ZipkinBackwardsCompatibilityAutoConfiguration.class);
TraceAutoConfiguration.class);
this.context.refresh();
then(this.context.getBean(Sender.class)).isInstanceOf(KafkaSender.class);
@@ -172,8 +170,7 @@ public class ZipkinAutoConfigurationTests {
environment().setProperty("spring.zipkin.sender.type", "activemq");
this.context.register(PropertyPlaceholderAutoConfiguration.class,
ActiveMQAutoConfiguration.class, ZipkinAutoConfiguration.class,
TraceAutoConfiguration.class,
ZipkinBackwardsCompatibilityAutoConfiguration.class);
TraceAutoConfiguration.class);
this.context.refresh();
then(this.context.getBean(Sender.class)).isInstanceOf(ActiveMQSender.class);
@@ -187,8 +184,7 @@ public class ZipkinAutoConfigurationTests {
environment().setProperty("spring.zipkin.sender.type", "web");
this.context.register(PropertyPlaceholderAutoConfiguration.class,
RabbitAutoConfiguration.class, KafkaAutoConfiguration.class,
ZipkinAutoConfiguration.class, TraceAutoConfiguration.class,
ZipkinBackwardsCompatibilityAutoConfiguration.class);
ZipkinAutoConfiguration.class, TraceAutoConfiguration.class);
this.context.refresh();
then(this.context.getBean(Sender.class).getClass().getName())
@@ -203,8 +199,7 @@ public class ZipkinAutoConfigurationTests {
environment().setProperty("spring.zipkin.sender.type", "WEB");
this.context.register(PropertyPlaceholderAutoConfiguration.class,
RabbitAutoConfiguration.class, KafkaAutoConfiguration.class,
ZipkinAutoConfiguration.class, TraceAutoConfiguration.class,
ZipkinBackwardsCompatibilityAutoConfiguration.class);
ZipkinAutoConfiguration.class, TraceAutoConfiguration.class);
this.context.refresh();
then(this.context.getBean(Sender.class).getClass().getName())
@@ -219,8 +214,7 @@ public class ZipkinAutoConfigurationTests {
environment().setProperty("spring.zipkin.sender.type", "rabbit");
this.context.register(PropertyPlaceholderAutoConfiguration.class,
RabbitAutoConfiguration.class, KafkaAutoConfiguration.class,
ZipkinAutoConfiguration.class, TraceAutoConfiguration.class,
ZipkinBackwardsCompatibilityAutoConfiguration.class);
ZipkinAutoConfiguration.class, TraceAutoConfiguration.class);
this.context.refresh();
then(this.context.getBean(Sender.class)).isInstanceOf(RabbitMQSender.class);
@@ -235,8 +229,7 @@ public class ZipkinAutoConfigurationTests {
this.server.url("/").toString());
this.context.register(ZipkinAutoConfiguration.class,
PropertyPlaceholderAutoConfiguration.class, TraceAutoConfiguration.class,
Config.class, MultipleReportersConfig.class,
ZipkinBackwardsCompatibilityAutoConfiguration.class);
Config.class, MultipleReportersConfig.class);
this.context.refresh();
then(this.context.getBeansOfType(Sender.class)).hasSize(2);
@@ -266,33 +259,12 @@ public class ZipkinAutoConfigurationTests {
Awaitility.await().untilAsserted(() -> then(sender.isSpanSent()).isTrue());
}
@Test
public void supportsMultipleReportersWithBackwardsCompatibilty() throws Exception {
this.context = new AnnotationConfigApplicationContext();
environment().setProperty("spring.zipkin.base-url",
this.server.url("/").toString());
this.context.register(BackwardsCompatibilityConfig.class,
ZipkinBackwardsCompatibilityAutoConfiguration.class,
ZipkinAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class,
TraceAutoConfiguration.class, Config.class);
this.context.refresh();
then(this.context.getBeansOfType(Sender.class)).hasSize(2);
then(this.context.getBeansOfType(Sender.class))
.containsKeys(ZipkinAutoConfiguration.SENDER_BEAN_NAME, "rabbitSender");
then(this.context.getBeansOfType(Reporter.class)).hasSize(2);
then(this.context.getBeansOfType(Reporter.class))
.containsKeys(ZipkinAutoConfiguration.REPORTER_BEAN_NAME, "reporter");
}
@Test
public void shouldOverrideDefaultBeans() {
this.context = new AnnotationConfigApplicationContext();
this.context.register(ZipkinAutoConfiguration.class,
PropertyPlaceholderAutoConfiguration.class, TraceAutoConfiguration.class,
Config.class, MyConfig.class,
ZipkinBackwardsCompatibilityAutoConfiguration.class);
Config.class, MyConfig.class);
this.context.refresh();
then(this.context.getBeansOfType(Sender.class)).hasSize(1);
@@ -398,16 +370,6 @@ public class ZipkinAutoConfigurationTests {
}
@Configuration
protected static class BackwardsCompatibilityConfig {
@Bean
Sender rabbitSender() {
return RabbitMQSender.create("localhost");
}
}
// tag::override_default_beans[]
@Configuration

View File

@@ -45,8 +45,7 @@ import static org.assertj.core.api.BDDAssertions.then;
@RunWith(SpringRunner.class)
@SpringBootTest(
classes = { TraceAsyncIntegrationTests.TraceAsyncITestConfiguration.class },
properties = "spring.sleuth.http.legacy.enabled=true")
classes = { TraceAsyncIntegrationTests.TraceAsyncITestConfiguration.class })
public class TraceAsyncIntegrationTests {
@Autowired

View File

@@ -69,8 +69,7 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilder
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = TraceFilterIntegrationTests.Config.class,
properties = "spring.sleuth.http.legacy.enabled=true")
@SpringBootTest(classes = TraceFilterIntegrationTests.Config.class)
public class TraceFilterIntegrationTests extends AbstractMvcIntegrationTest {
static final String TRACE_ID_NAME = "X-B3-TraceId";

View File

@@ -56,8 +56,7 @@ import static org.assertj.core.api.BDDAssertions.then;
*/
@RunWith(SpringRunner.class)
@SpringBootTest(classes = { TraceFilterWebIntegrationMultipleFiltersTests.Config.class },
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
properties = "spring.sleuth.http.legacy.enabled=true")
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class TraceFilterWebIntegrationMultipleFiltersTests {
@Autowired

View File

@@ -60,8 +60,7 @@ import static org.assertj.core.api.BDDAssertions.then;
*/
@RunWith(SpringRunner.class)
@SpringBootTest(classes = TraceFilterWebIntegrationTests.Config.class,
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
properties = "spring.sleuth.http.legacy.enabled=true")
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class TraceFilterWebIntegrationTests {
@Rule
@@ -99,8 +98,7 @@ public class TraceFilterWebIntegrationTests {
then(Tracing.current().tracer().currentSpan()).isNull();
then(this.accumulator.getSpans()).hasSize(1);
Span fromFirstTraceFilterFlow = this.accumulator.getSpans().get(0);
then(fromFirstTraceFilterFlow.tags()).containsEntry("http.status_code", "500")
.containsEntry("http.method", "GET")
then(fromFirstTraceFilterFlow.tags()).containsEntry("http.method", "GET")
.containsEntry("mvc.controller.class", "ExceptionThrowingController")
.containsEntry("error",
"Request processing failed; nested exception is java.lang.RuntimeException: Throwing exception");