This library is a Java bridge between the Brave/Zipkin Api and OpenTracing. It allows its users to write portable (in the OpenTracing sense) instrumentation that's translated into Brave instrumentation transparently.
In order to understand OpenTracing Api, one must first be familiar with the OpenTracing project and terminology more generally.
To understand how Zipkin and Brave work, you can look at Zipkin Architecture and Brave Api documentation.
Firstly, you need a Tracer, configured to report to Zipkin.
// Configure a reporter, which controls how often spans are sent
// (the dependency is io.zipkin.reporter:zipkin-sender-okhttp3)
sender = OkHttpSender.create("http://127.0.0.1:9411/api/v1/spans");
reporter = AsyncReporter.builder(sender).build();
// Now, create a Brave tracing component with the service name you want to see in Zipkin.
// (the dependency is io.zipkin.brave:brave)
braveTracing = Tracing.newBuilder()
.localServiceName("my-service")
.reporter(reporter)
.build();
// use this to create an OpenTracing Tracer
tracer = BraveTracer.create(braveTracing);
// You can later unwrap the underlying Brave Api as needed
braveTracer = tracer.unwrap();
Some example code demonstrating how the OpenTracing Api is to be used.
Code in the first process…
// start a span
try ( Span span0 = tracer.buildSpan("span-0")
.withTag("description", "top level initial span in the original process")
.start() ) {
// do something
// start another span
try ( Span span1 = tracer.buildSpan("span-1")
.asChildOf(span0)
.withTag("description", "the first inner span in the original process")
.start() ) {
// do something
// start another span
try ( Span span2 = tracer.buildSpan("span-2")
.asChildOf(span1)
.withTag("description", "the second inner span in the original process")
.start() ) {
// do something
// cross process boundary
Map<String,String> map = new HashMap<>();
tracer.inject(span2.context(), Format.Builtin.HTTP_HEADERS, new TextMapInjectAdapter(map));
// request.addHeaders(map);
// request.doGet();
}
}
}
Code in the second process
// Map<String,String> map = request.getHeaders();
try ( Span span3 = tracer.buildSpan("span-3")
.asChildOf(tracer.extract(Format.Builtin.HTTP_HEADERS, new TextMapExtractAdapter(map)))
.withTag("description", "the third inner span in the second process")
.start() ) {
// do something
// start another span
try ( Span span4 = tracer.buildSpan("span-4")
.asChildOf(span3)
.withTag("description", "the fourth inner span in the second process")
.start() ) {
// do something
// cross process boundary
map = new HashMap<>();
tracer.inject(span4.context(), Format.Builtin.HTTP_HEADERS, new TextMapInjectAdapter(map));
// request.addHeaders(map);
// request.doGet();
}
}
This code repeats from process to process, as far through the stack as required.