Wingtips is a distributed tracing solution for Java based on the Google Dapper paper.
This module is a plugin extension module of the core Wingtips library and contains support for distributed tracing in a Spring environment.
NOTE: This module does not include Spring WebFlux support. If you're looking for Wingtips + Spring WebFlux
support (both serverside and clientside), see the wingtips-spring-webflux module instead.
This module mainly revolves around supporting the old Spring HTTP clients (RestTemplate
and AsyncRestTemplate
).
And if you're looking for serverside support for a Spring Web MVC (not WebFlux) project, you'll want
RequestTracingFilter
from the wingtips-servlet-api module.
This module contains the following features/classes:
WingtipsClientHttpRequestInterceptor
- An interceptor for Spring's synchronousRestTemplate
HTTP client that automatically propagates Wingtips tracing information on the downstream call's request headers, with an option to surround the downstream call in a subspan. This interceptor uses theZipkinHttpTagStrategy
by default to name and tag any created subspans. See the Default HTTP Tags section in the main readme for details on what tags you get. You can use a different tag and naming strategy (and/or tag adapter) if desired by passing it in when constructing the interceptor.WingtipsAsyncClientHttpRequestInterceptor
- An interceptor for Spring's asynchronousAsyncRestTemplate
HTTP client that automatically propagates Wingtips tracing information on the downstream call's request headers, with an option to surround the downstream call in a subspan. This interceptor usesZipkinHttpTagStrategy
by default just like the other interceptor.ListenableFutureCallbackWithTracing
,SuccessCallbackWithTracing
, andFailureCallbackWithTracing
- These classes wrap their associated class or functional interface from Spring'sorg.springframework.util.concurrent
package. They can be used to add callbacks toAsyncRestTemplate
requests (or anywhere else that Spring requires them) so that the correct tracing info is attached when the callback runs regardless of which thread it executes on. Note that each of these classes has static factory methods namedwithTracing(...)
so you can do static method imports to keep your code as clean and readable as possible. TheWingtipsSpringUtil
class contains disambiguated versions of these factory methods in case you need multiple in the same class, e.g.successCallbackWithTracing(...)
andfailureCallbackWithTracing(...)
.HttpRequestWrapperWithModifiableHeaders
- An extension of Spring'sHttpRequestWrapper
that guarantees the headers are mutable. Used mainly as a helper for the interceptors which need to be able to modify headers, but available for public use if you have the same need.WingtipsSpringUtil
- A class with static helper methods to facilitate some of the features provided by this module.
For general Wingtips information please see the base project README.md.
NOTES:
- The Wingtips Spring sample project shows these features in action.
- More details can be found in the javadocs for the various classes found in this
wingtips-spring
module.
RestTemplate wingtipsEnabledRestTemplate = WingtipsSpringUtil.createTracingEnabledRestTemplate();
// ... later, when ready to execute your request
ResponseEntity<Foo> response = wingtipsEnabledRestTemplate.exchange(...);
// ... process response
Note that you don't have to use the WingtipsSpringUtil.createTracingEnabledRestTemplate()
helper method to create a
Wingtips-enabled RestTemplate
. If you have a RestTemplate
already you can call restTemplate.setInterceptors(...)
or restTemplate.getInterceptors().add(...)
to ensure a WingtipsClientHttpRequestInterceptor
is present when the
RestTemplate
executes your requests.
Also, anything that executes a request will work, including restTemplate.get*(...)
, restTemplate.post*(...)
,
restTemplate.put(...)
, etc. We use restTemplate.exchange(...)
above just as an example.
AsyncRestTemplate
utilizing WingtipsAsyncClientHttpRequestInterceptor
and *WithTracing
callbacks for automatic tracing propagation
import static com.nike.wingtips.spring.util.WingtipsSpringUtil.failureCallbackWithTracing;
import static com.nike.wingtips.spring.util.WingtipsSpringUtil.successCallbackWithTracing;
// ...
AsyncRestTemplate wingtipsEnabledAsyncRestTemplate = WingtipsSpringUtil.createTracingEnabledAsyncRestTemplate();
// ... later, when ready to execute your request
ListenableFuture<ResponseEntity<Foo>> responseFuture = wingtipsEnabledAsyncRestTemplate.exchange(...);
responseFuture.addCallback(
successCallbackWithTracing(result -> {
// ... process successful response
}),
failureCallbackWithTracing(error -> {
// ... process failure
})
);
Note that you don't have to use the WingtipsSpringUtil.createTracingEnabledAsyncRestTemplate()
helper method to
create a Wingtips-enabled AsyncRestTemplate
. If you have a AsyncRestTemplate
already you can call
asyncRestTemplate.setInterceptors(...)
or asyncRestTemplate.getInterceptors().add(...)
to ensure a
WingtipsAsyncClientHttpRequestInterceptor
is present when the AsyncRestTemplate
executes your requests.
Also, anything that executes a request will work, including asyncRestTemplate.get*(...)
, asyncRestTemplate.post*(...)
,
asyncRestTemplate.put(...)
, etc. We use asyncRestTemplate.exchange(...)
above just as an example.
This module does not export any transitive Spring dependencies to prevent version conflicts with whatever Spring environment you're running in.
This should not affect most users since this library is likely to be used in a Spring environment where the spring-web
dependency is already on the classpath at runtime, however if you receive class-not-found errors related to Spring
classes found in spring-web
then you'll need to pull the org.springframework:spring-web
dependency into your
project. Library authors who wish to build on functionality in this module might need to do this.
This module was built using version 4.3.7.RELEASE
of spring-web
, but many other versions of Spring should work fine,
both older and newer.