how to exclude some calls with the Feign from tracing with the cloud sleuth - spring-boot

there's a microservice with spring-boot 1.5 which uses the Feign to communicate with others services, also there's spring-cloud-starter-zipkin which wrapped all calls through the Feign and sends tracing to zipkin server.
The thing is i don't wanna wrap all calls and trace them, there're only several most important to do that.
How can i exclude some calls(methods) with Feign from tracing or exlude some whole Feign client(interface)?

In Sleuth 1.3.x you can create a custom SpanReporter that, before sending a span to Zipkin, would analyze the URL and would not report that span. In Sleuth 2.0.x you can create a custom HttpSampler for the client side (with name sleuthClientSampler)

Related

Do we need to use Sleuth with Zipkin

In order to trace service invocation across microservices , we can use Zipkin.
From the below URLs ,we understand the time taken for calls across micro services can be captured in zipkin
https://tanzu.vmware.com/developer/guides/spring/spring-zipkin/
https://springhow.com/spring-boot-zipkin-distributed-tracing/
Do we still need to use spring sleuth along with zipkin ? Does the span id and trace id generated by Sletuh provide any additional information apart from what Zipkin can capture on its own ?
Since brave is a zipkin library I presume there is no need to have dependency on sleuth in order to trace service calls across microservices.
One probable benefit of Sleuth is that it adds the span id and trace id in the application logs ( using logback MDC concept ) . These logs can be pushed into elastic search using Logstash
If you want to use only Spring Cloud Sleuth without the Zipkin integration, add the spring-cloud-starter-sleuth module to your project
Check this for reference

Sending Zipkin Spans for #FeignClient

I'm running a Spring Boot app using:
Spring Boot 2.3.8
Spring Cloud Hoxton.SR10
I've declared the spring-cloud-starter-zipkin and spring-cloud-starter-openfeign dependencies, and have configured my app to point to a Zipkin server. Its a pretty vanilla setup and configuration (I also declare the spring-cloud-starter-netflix-ribbon and spring-cloud-starter-kubernetes-all dependencies o allow Spring Feign to use k8s service discovery).
My app declares a #SpringFeign annotated interface with a method to call to a remote service S.
So generally zipkin is getting spans from my app (for e.g. incoming REST calls) and B3 headers are being propagated via HTTP to the service S being called through feign.
But zipkin does not report a span from my app representing the Feign call to S.
Is that something that should "just happen", or am I missing a piece of the puzzle?
I can e.g. add #NewSpan to the feign interface method, but that doesn't give me HTTP details for the request/response as span tags. And I rather not do that if this is supposed to work out of the box.
This should be done out of the box: https://docs.spring.io/spring-cloud-sleuth/docs/2.2.7.RELEASE/reference/html/#feign
You can take a look at the feign sample (you need to go back in the history, currently it is for 3.x): https://github.com/spring-cloud/spring-cloud-sleuth/tree/master/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-feign
In order to see if propagation works, look into the outgoing request, it should contain the tracing-related headers.

Is it possible to disable Spring Cloud Sleuth header propagation based on destination URL?

We're using Brave's ExtraFieldPropagation feature to propagate custom fields (e.g. an internal-only request identifier) between services as HTTP headers.
Some of our services make requests to external services using a RestTemplate or Feign client in the course of processing a request. Since Sleuth enhances all RestTemplate beans and Feign clients with the propagation feature, this means that external services receive the internal-only headers, which I'd like to avoid.
I know of two workarounds that allow me to avoid this behavior, both of which are flawed:
Instantiate a client object manually as opposed to using a #Bean so that Sleuth does not add an interceptor. The downside I see here is that developers have to remember to follow this pattern to avoid leaking information, and this is difficult to enforce.
Add an interceptor that removes these headers from outgoing requests. The downsides here are that a) I need separate interceptors for RestTemplate and Feign clients (not a huge deal); b) it looks like Feign client interceptors do not have a way to influence order of execution (see javadoc here), so I can't guarantee that the new interceptor will run last / after the Sleuth one.
Is there a way to customize Sleuth (e.g. via some kind of injector bean) such that, prior to injecting headers in an outgoing HTTP request, I can reason about the destination of the request? I saw documentation regarding custom injector beans, but it appears those no longer exist in spring boot >= 2. I can't seem to find an equivalent construct in Brave.
You can unsample a given URL which means that the headers will be propagated but not sent to Zipkin. You can't disable instrumentation for only some of the URLs cause we're instrumenting all of the components that are registered as beans.

Baggage Propagation in Jms using Spring Cloud Sleuth

I'm trying to use the baggage propagation offered by Spring Cloud Sleuth. In the calls that use the Feign client I don't have any kind of problem, I can propagate custom fields, while while using JmsTemplate of Spring JMS I can't propagate the same fields.
My application is a Spring Boot application, version 2.1.5, with Spring Cloud version Greenwich.SR1.
In order to put the custom fields, I use
ExtraFieldPropagation.set("communicationId", "123456");
while, inside my application.properties, I put
spring.sleuth.baggage-keys= communicationId
I expect that the same functionality present for the Feign client, is also present for the producer JMS. Where am I wrong?

Camel Rest api consumer using SpringOAuthResttemplate

I have to invoke a couple of rest web service from my spring boot application. I am planning to use the Camel to configure the flow and other EIP use cases. Some of the endpoints are using oAuth2 authentication. I am planning to use the Spring oAuthResttempalte. All the examples on the internet are either using restlet, CXF or camel-http.
Camel Rest Consmer
I am not able to find a single example with just spring resttemplate. Did anyone implement Camel Rest consumer using Spring Resttemplate?
Some of the Examples on the internet use a jetty server to consume a rest endpoint. Why do you need a jetty server for simple rest consumer?
Did anyone implement Camel Rest consumer using Spring Resttemplate?
I'm not aware of that and it's unlikely to found something in that direction because Camel already have bult-in components to consume rest endpoints.
Some of the Examples on the internet use a jetty server to consume a rest endpoint. Why do you need a jetty server for simple rest consumer?
I believe that jetty was used as a consumer not a producer endpoint. So you won't need the "server". Or maybe you saw an example using jetty acting as a server to serve an OAuth endpoint?
If you excuse my approach, I'd suggest to remain with Camel HTTP/Rest capabilities to consume REST APIs using OAuth. I've found this example on Gist:
from("direct:authService").tracing()
.setHeader(Exchange.HTTP_PATH)
.simple("<auth service context>/oauth2/token")
.setHeader("CamelHttpMethod")
.simple("POST")
.setHeader("Content-Type")
.simple("application/x-www-form-urlencoded")
.setHeader("Accept")
.simple("application/json")
.setBody()
.constant("grant_type=client_credentials&client_id=<client id>&client_secret=<client sec>")
.to("https4://<remote auth service url>")
.convertBodyTo(String.class)
.log("response from API: " + body())
.choice()
.when().simple("${header.CamelHttpResponseCode} == 200")
.unmarshal().json(JsonLibrary.Jackson, AccessResponseToken.class)
.setHeader("jwt").simple("${body.access_token}")
.to("direct:<some direct route>")
.otherwise()
.log("Not Authenticated!!!");
If you want to stick into OAuthRestTemplate you may implement a Processor or a bean to wrap those calls and return to your route the authorization token.

Resources