opentracing-contrib/java-jaxrs

Using GlobalTracer.register() doesn't enable JAX-RS instrumentation in Spring Boog

rromannissen opened this issue · 2 comments

I've been struggling to integrate the library with Spring Boot the same way I did with Wildfly Swarm on a previous project. My first thought was to declare a Jaeger Bean at application level and inject it when calling to GlobalTracer.register() at application startup on the main() method:

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
	ConfigurableApplicationContext context = SpringApplication.run(Application.class, args);
        GlobalTracer.register(context.getBean(Tracer.class));
    }
    
    @Bean
    public JacksonJsonProvider jsonProvider() {
        return new JacksonJsonProvider();
    }
    
    @Bean
    public Tracer tracer() {
    	return new Configuration("orders", 
				new SamplerConfiguration(ProbabilisticSampler.TYPE, 1),
				new Configuration.ReporterConfiguration()).getTracer();
    }

With this I got the tracer created and usable for any ActiveSpan I may create, but the JAX-RS instrumentation just wasn't there. I changed the approach by using a ServletContextListener and performing there the call to the register method of GlobalTracer to initialize the JAX-RS instrumentation:

@WebListener
public class TracingContextListener implements ServletContextListener {

	@Autowired
	Tracer tracer;

	@Override
	public void contextDestroyed(ServletContextEvent arg0) {

	}

	@Override
	public void contextInitialized(ServletContextEvent servletContextEvent) {
		GlobalTracer.register(context.getBean(Tracer.class));
	}

}

The result was the same. I finally managed to make the instrumentation work by manually declaring the ServerTracingDynamicFeature and the SpanFinishingFilter manually as beans:

@SpringBootApplication
public class Application {
	
    @Autowired
    private Tracer tracer;

    public static void main(String[] args) {
	SpringApplication.run(Application.class, args);
    }
    
    @Bean
    public JacksonJsonProvider jsonProvider() {
        return new JacksonJsonProvider();
    }
    
    @Bean
    public Tracer tracer() {
    	return new Configuration("orders", 
				new SamplerConfiguration(ProbabilisticSampler.TYPE, 1),
				new Configuration.ReporterConfiguration()).getTracer();
    }
    
    @Bean
    public FilterRegistrationBean spanFinishingFilterBean() {
    	final FilterRegistrationBean filterRegBean = new FilterRegistrationBean();
    	filterRegBean.setFilter(new SpanFinishingFilter(tracer));
    	filterRegBean.addUrlPatterns("/*");
    	filterRegBean.setEnabled(Boolean.TRUE);
    	filterRegBean.setName("SpanFinishingFilter");
    	filterRegBean.setAsyncSupported(Boolean.TRUE);
    	return filterRegBean;
    }
    
    @Bean
    public DynamicFeature serverTracingDynamicFeatureBean() {
    	return new ServerTracingDynamicFeature.Builder(tracer)
    	        .build();
    }

}

Is this the way to go in Spring Boot? Is there any way to perform this configuration automatically by calling GlobalTracer.register() as in Wildfly Swarm?

I think the problem is related to fact that jaxrs providers (e.g. tracing feature) are not automatically discovered in SB.

The second approach looks good if it works. There might be more configuration variations, e.g. the one from root readme. In this repository there is example folder with SB and jax-rs (and there is a bug because the filter is not registered I will fix it).

@rromannissen were you able to solve it? I will close it as it is related to spring configuration not jax-rs. Feel free to reopen.