Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement Sleuth Tracing With Feign.Builder?

I'm trying to integrate Sleuth into our system. If I use interfaces annotated with @FeignClient, everything works fine. These interfaces get instrumented automatically, and Sleuth headers get propagated with REST calls.

But, we have some existing code that uses Feign.Builder directly with Feign annotated interfaces (just not annotated with @FeignClient). This code adds some custom request interceptors, encoder, proxy, etc.

For example:

// Feign REST interface
public interface MyService {

    @RequestMapping(method = RequestMethod.GET, value = "/version")
    String getVersion();
}

// Creating the builder
Feign.Builder builder = Feign.builder();
builder.requestInterceptor(new MyCustomInterceptor());
// + adding proxy, encoder, decoder, etc

// Using the builder
MyService myService = builder.target(MyService.class, "http://localhost:8080/myservice");
myService.getVersion();

I would like this older code to propagate Sleuth headers. Is there some easy way to wire this up?

(I suppose one option is to rework our Feign interfaces to have @FeignClient and rework how all of the custom interceptors, encoders, etc get applied, but ultimately that might be a lot of work with a lot of risk.)

Do I need to do a special request interceptor to inject these manually (e.g. from an autowired Tracer)? Is there a clean way (or existing class) to do that?

like image 333
yngwietiger Avatar asked Jan 11 '18 16:01

yngwietiger


People also ask

How would you implement feign client in microservices?

Let's implement the Feign in our project and invoke other microservices using Feign. Step 1: Select currency-conversion-service project. Step 2: Open the pom. xml and add the Feign dependency.

How do I get TraceId on sleuth?

Inject the Tracer bean and call tracer. currentSpan() to get the current span. From there you can get the trace id.

How do you use FeignClient?

The Feign client uses a declarative approach for accessing the API. To use it, we must first enable the Spring Cloud support for it on our Spring Boot Application with the @EnableFeignClients annotation at the class level on a @Configuration class. Next step is to declare an interface for accessing our API.

What is TraceId SpanId?

TraceId – This is an id that is assigned to a single request, job, or action. Something like each unique user initiated web request will have its own traceId. SpanId – Tracks a unit of work. Think of a request that consists of multiple steps. Each step could have its own spanId and be tracked individually.


1 Answers

I finally figured it out.

The answer was pretty much here: https://github.com/spring-cloud/spring-cloud-sleuth/issues/594

When using Feign.Builder, its Client needs to be wrapped by a "Trace" implementation.

To accomplish this, we can just declare a Client bean, then spring/sleuth will automatically take care of wrapping it (since sleuth is in the dependency list).

The declaration will be something like:

@Bean
public OkHttpClient okHttpClient() {
    return new OkHttpClient();
}

Then we can just pass that Client bean to the builder when building the client implementation.

For example:

// autowiring the Client bean
@Autowired
private Client client;

// using the Client bean to build the Feign client
DemoClient demoClient = Feign.builder()
        .client(client)
        .target(DemoClient.class, "http://localhost:8200/demo");

After doing that, everything seemed to work. I could see the Trace Id getting propagated to the remote REST service.

like image 175
yngwietiger Avatar answered Oct 12 '22 11:10

yngwietiger