Awesome Open Source
Awesome Open Source

Build Status Released Version

OpenTracing JAX-RS Instrumentation

OpenTracing instrumentation for JAX-RS standard. It supports tracing of server and client requests.

Instrumentation by default adds a set of standard HTTP tags and as an operation name it uses a string defined in @Path annotation. Custom tags or operation name can be added via span decorators. This instrumentation also supports tracing of (de)serialization of response and requests bodies.


This implementation is compatible with MicroProfile-OpenTracing (MP-OT). It can be used as a building block of MicroProfile compatible application server. Note that application servers have to add a few things which are not provided by this project: CDI interceptor, automatically register tracing filters into client... SmallRye-OpenTracing uses this library to provide a vendor neutral implementation of MP-OT.

Tracing server requests

Tracing server requests requires two components: JAX-RS dynamic feature and servlet filter. Span is started in JAX-RS filter and finished in servlet filter.

Auto discovery

Tracing can be automatically enabled by adding the following dependency on classpath. This mechanism requires a tracer to be registered in GlobalTracer. This is typically done in ServletContextListener. Note that JAX-RS clients are not automatically instrumented. Client tracing feature has to be explicitly registered to all client instances.


Custom configuration

For custom configuration use the following dependency:


The Custom configuration can be achieved by adding ServerTracingDynamicFeature to Application.singletons or by wrapping the feature with a class annotated with @Provider. This approach does not require adding all classes to singletons set.

Dynamic feature registration via custom provider:

public class TracingInitializer implements DynamicFeature {

  private final ServerTracingDynamicFeature serverTracingDynamicFeature =
      new ServerTracingDynamicFeature.Builder(GlobalTracer.get())

  public void configure(ResourceInfo resourceInfo, FeatureContext context) {
    serverTracingDynamicFeature.configure(resourceInfo, context);

Dynamic feature registration via singletons:

public class JaxRsApp extends {

  public Set<Object> getSingletons() {
    DynamicFeature tracing = new ServerTracingDynamicFeature.Builder(tracer)

    return Collections.singleton(tracing);

Filter registration:

public class OpenTracingContextInitializer implements javax.servlet.ServletContextListener {

  public void contextInitialized(ServletContextEvent servletContextEvent) {
    io.opentracing.tracer tracer = new ....
    GlobalTracer.register(tracer); // or preferably use CDI
    ServletContext servletContext = servletContextEvent.getServletContext();
    Dynamic filterRegistration = servletContext
        .addFilter("tracingFilter", new SpanFinishingFilter());
    filterRegistration.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST, DispatcherType.ASYNC), false, "*");

An example of traced REST endpoint:

@Traced(operationName = "helloRenamed") // optional, see javadoc
public Response hello() { // optional to get server span context

  // this span will be ChildOf of span representing server request processing
  Span childSpan = tracer.buildSpan("businessOperation")

   // business logic

  return Response.status(Response.Status.OK).build();

Tracing client requests

Client client = ClientBuilder.newBuilder()

Response response ="http://localhost/endpoint")
  .property(TracingProperties.CHILD_OF, parentSpanContext) // optional, by default new parent is inferred from span source
  .property(TracingProperties.TRACING_DISABLED, false) // optional, by default everything is traced


Async requests are executed in a different thread than when the client has been invoked, therefore spans representing client requests are not connected to appropriate parent. To fix this JAX-RS client has to use OpenTracing-aware ExecutorService.


public class DelegateExecutorServiceProvider implements ExecutorServiceProvider {

  private final ExecutorService executorService;

  public DelegateExecutorServiceProvider(ExecutorService executorService) {
    this.executorService = executorService;

  public ExecutorService getExecutorService() {
    return executorService;

  public void dispose(ExecutorService executorService) {

Client client = ClientBuilder.newBuilder()
    .register(new DelegateExecutorServiceProvider(
        new TracedExecutorService(Executors.newFixedThreadPool(8), tracer)))


Client client = new ResteasyClientBuilder()
    .executorService(new TracedExecutorService(Executors.newFixedThreadPool(8), tracer))


./mvnw clean install


Follow instructions in RELEASE


Apache 2.0 License.

Alternatives To Java Jaxrs
Select To Compare

Alternative Project Comparisons
Related Awesome Lists
Top Programming Languages

Get A Weekly Email With Trending Projects For These Topics
No Spam. Unsubscribe easily at any time.
Java (412,761
R (62,302
Tracing (3,611
Instrumentation (1,834
Jersey (954
Opentracing (713
Jax Rs (359
Resteasy (34
Apache Cxf (15