Removed deprecated apis; fixes gh-1564
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
@@ -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> {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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";
|
||||
|
||||
}
|
||||
@@ -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";
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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[]
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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()))
|
||||
|
||||
@@ -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 {
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user