Instrumentation with OpenTracing integrations is very simple. For Spring Boot there is
an auto-configuration which instruments all REST controllers and RestTemplate
beans. Just add the following
dependency to the classpath:
<dependency>
<groupId>io.opentracing.contrib</groupId>
<artifactId>opentracing-spring-web-autoconfigure</artifactId>
</dependency>
This dependency requires only one thing and that is a tracer bean which will be used to report data to the chosen
tracing system. If we don’t specify this bean auto-configuration will choose NoopTracer
.
Because we are using OpenTracing instrumentation we are not bound to any specific tracing system.
We will now show how to first use Jaeger and then switch to Zipkin. We will see that changing the tracing system is just
a matter of configuration.
As we mentioned the only tracing configuration needed here is to provide a tracer bean.
Jaeger
To create a Jaeger tracer is very simple. It just requires a sampler configuration and because it is a demo we are going
to sample all requests. Note that we are not specifying the URL to Jaeger server. By default it will assume that it
runs on localhost.
@Bean
public io.opentracing.Tracer jaegerTracer() {
return new Configuration("spring-boot", new Configuration.SamplerConfiguration(ProbabilisticSampler.TYPE, 1),
new Configuration.ReporterConfiguration())
.getTracer();
Now we can start the Jaeger server using docker run --rm -it --network=host jaegertracing/all-in-one
, compile and
run our app. When everything is up and running generate some requests to URL’s defined in the previous section.
Figure 1: Jaeger showing reported traces.
On the picture we can see traces for the request to the /chaining
endpoint. There are three spans: one representing
server processing of /chaining
, the second a client request to /hello
and the third server processing of /hello
endpoint.
Zipkin
Now let’s benefit from OpenTracing and switch tracing system with O(1) effort. To do that we just need to
provide an instance of Zipkin tracer bean. Do not forget to comment out the Jaeger tracer bean, otherwise instrumentation
would not know which tracer to use.
Zipkin configuration is very similar it just requires to know Zipkin URL:
@Bean
public io.opentracing.Tracer zipkinTracer() {
OkHttpSender okHttpSender = OkHttpSender.create("http://localhost:9411/api/v1/spans");
AsyncReporter<Span> reporter = AsyncReporter.builder(okHttpSender).build();
Tracing braveTracer = Tracing.newBuilder().localServiceName("spring-boot").reporter(reporter).build();
return BraveTracer.create(braveTracer);
}
Zipkin server can be started with docker run --rm -it -p 9411:9411 openzipkin/zipkin
. Now we have to rebuild and
start our demo app and generate requests.
Figure 1: Zipkin showing reported traces.
This screenshot also show traces for invocation of /chaining
endpoint. In this case it shows only two spans because Zipkin
uses a shared span model which means that client and server invocation of /hello
uses the same span.
This is a great example that shows how different OpenTracing providers might model and show things differently.