The 5.182 release of Payara Server & Payara Micro (Payara Platform) brings in MicroProfile (MP) 1.3. This introduces a couple of updates to some existing MP specifications, and three new ones: OpenTracing, OpenAPI, and Type-safe REST Client. In this blog I’ll be covering our implementation of OpenTracing.
Much like the MP OpenAPI spec, the MP OpenTracing spec actually heavily leans on a specification external to MP: This external spec is designed to give a consistent API to users of distributed tracing systems, such as Jaeger and Zipkin, and defines the structure of what these traces should look like. The MP spec builds on this by specifying that each implementation must provide a way of using an OpenTracing compliant tracer, as well as providing a new @Traced annotation for tracing methods.
The MicroProfile OpenTracing API
The MP OpenTracing spec provides two additions to the original OpenTracing API: an @Traced annotation and the ability to inject an OpenTracing Tracer instance into your applications.
The @Traced Annotation
The @Traced Annotation allows you to specify that a method should be traced, providing a nice shortcut to manually instrumenting your code by injecting the Tracer instance, starting a trace (called a Span), and then ending the trace.
The annotation provides just two options: whether the method should be traced (the default value option of the annotation), and what the created Span should be called (operationName):
@Traced(operationName = “traceMe”)
By default, MP OpenTracing traces , even without being instrumented with this annotation, so the main use of this annotation is to either disable tracing of JAX-RS methods, or to trace additional non-JAX-RS methods.
MicroProfile OpenTracing also allows you to inject a Tracer instance into your application. This is just a pure, magical convenience – let the implementation deal with the shenanigans of finding and creating a Tracer!
What You Can Do with the OpenTracing API
With an OpenTracing Tracer instance injected into your code, it probably makes sense to give a quick overview of what you can actually do with it.
The two main use cases are:
- Starting and stopping traces manually:
- Adding information to Spans created using the @Traced annotation:
Those of you unfamiliar with distributed tracing are probably wondering what a Span is: in simple terms, a Span is a trace. In the OpenTracing world, a Trace is typically used to refer to a collection of one or more Spans, but in non-tech jargon it’s just a Trace with sub-traces.
Tags are simply used to attach information to the Span, in a key:value format. Logs are very much like tags, but also have a timestamp, so they are used for recording notable events.
Using MicroProfile OpenTracing with the Payara Platform
For our implementation in the Payara Platform, we elected to tie this into the existing Request Tracing Service. Tying into the existing Request Tracing Service eliminates the need to supply a third-party OpenTracing implementation as an extra dependency or library, as everything is built-in. While using MP OpenTracing requires you to enable the Request Tracing Service (disabled by default), it also means you can quickly turn it off by disabling the service with an asadmin command (or with the Admin Console).
Integrating MP OpenTracing into the Request Tracing Service also allows you to use the other configuration options available to this service, such as the notification service and the sampling mechanisms, to create configurations such as only logging 10% of traces that take over 3 seconds to a HipChat room.
A Quick Example Using MP OpenTracing on a Payara Micro Instance
The following is a simple example, demonstrating how to enable Request Tracing on a Payara Micro instance, and how MP OpenTracing automatically traces JAX-RS requests.
So to start off, let’s create a web app with some JAX-RS endpoints:
The example is a little arbitrary, but I’m just trying to demonstrate the new feature – I’m not writing a well-constructed program!
As you can see though, I’ve got three JAX-RS endpoints: one which creates a JAX-RS client to call another endpoint, one which I’ve edited the name of using the @Traced annotation and added some extra information using an injected Tracer, and one which disables the automatic JAX-RS tracing whilst calling another non-JAX-RS method which has tracing enabled.
As mentioned briefly earlier, we’ll need to create a post boot command file to enable the Request Tracing Service in Payara Micro, and configure it to our liking:
Now whenever we start Payara Micro with the --postbootcommandfile option, all of the asadmin commands above will be run shortly after it boots, enabling the Request Tracing Service and configuring it to print out any trace that takes longer than 25 microseconds to the log file (which will be pretty much everything).
So, with all of this, we can start a Payara Micro instance and deploy the application:
java -jar payara-micro.jar –autobindhttp --postbootcommandfile ./postboot.txt --deploy opentracing-demo-1.0-SNAPSHOT.war
Now, if we hit the three endpoints with a browser, we should see something akin to the following in the logs (I’ve prettified them to actually make them legible):
Hopefully this has given you enough of an overview to get started, but if you want to keep playing, I’d recommend looking at the MicroProfile OpenTracing repo to see how things are changing in MP OpenTracing 1.1 and beyond. And as always, feel free to raise enhancement requests or issues on our GitHub Issues page or forum.