correlationId propagated to spring sleuth 1.x - spring-cloud

I have the following setup:
Proxy (P) -- HTTP --> Spring Boot 2 app (X) -- HTTP --> Spring Boot 1 app (Y)
The proxy sends the requestId as an HTTP header which I need to include in the logs of both X and Y.
For the X app I could easily do it with the support of Spring Cloud Sleuth 2 using
spring:
sleuth:
propagation-keys: requestId
and creating a CurrentTraceContext implementation with inspiration from Slf4jCurrentTraceContext where I add
MDC.put("requestId", ExtraFieldPropagation.get(currentSpan, "requestId"));
and then I can easily add it to the logs using the following log pattern:
%d{yy-MM-dd E HH:mm:ss.SSS} %5p [component=${springAppName},requestId=%X{requestId:-}] %m%n"
But now I need to propagate the requestId also to Y app.
Unfortunately there I cannot leverage the goodies introduced in Spring Cloud Sleuth 2.0, (like TraceContext from brave library) since that is a Spring Boot 1.x app.
Wondering what are the options?
I was thinking to extend the Slf4jSpanLogger and inject into DefaultTracer but not sure how to get the requestId there is no TraceContext in SpanLogger.

requestId has to be there in the headers. You would have to modify the current logic of parsing the HTTP headers for Boot 1.x and retrieve that value from the headers and put it in the span.
The easiest way however would be to propagate that value as baggage cause baggage works out of the box for Boot 1.x. That way if we see the baggage- prefixed headers, Sleuth 1.3.x will automatically propagate it. Remember to whitelist the baggage in Boot 2.0.

Related

Communication between Microservices: Spring cloud OpenFeign vs WebClient/RestTemplate

Any idea please about the best way to use for back to back communication ?
spring cloud OpenFeign or WebClient/RestTemplate ?
I think Feign client should be used when spring cloud gateway need to
communicate to other microservices, whereas WebClient/RestTemplate should be used for back to back communication.
Am I wrong ?
WebClient (RestTemplate - deprecated to support WebClient)
Supports reactive call
underlying HTTP client libraries such as Reactor Netty
Part of spring framework - WebFlux || Doc will give you more
Comes in 2 flavour - Annotation and functional way
Personally I found it very useful while working with OAuth2 creating bean webClient, before making call it needs to be authenticated with token, ServerOAuth2AuthorizedClientExchangeFilterFunction will ease each call with just one time configuration
OpenFeign
Reactive - need to use 3rd party - com.playtika.reactivefeign
Fits best if you want call in blocking way
Part of Spring cloud
Netflix fully transferred Feign to the open-source community under a new project named OpenFeign

Eureka Server Health Not Running

I updated a eureka server from Camdem.R3 to Flinchley.RC1 lately. There were a lot of changes in the settings.
On Camden.R3, without doing any additional settings the console link to the health check would work. For Flinchley.RC1 the health check would give a 404 response. I am trying to read the latest settings in Flinchley document but it only states how to check the health. Is there a way to find out if the client really ran the health check context?
After several research, I found out that the spring boot actuator specs was changed for 2.0. For Camden.R3 which is compatible with spring boot 1.X, all actuators starts in the base context. While Flinchley.RC1 which is compatible with spring boot 2.0 all context requires a context prefix of "/actuator".
Spring Boot 1.X actuator:
All of the actuator endpoints "sub sites" are turned on by default.
Health actuator would give a more detailed information in its
response
The actuator starts on base context of Eureka Client Site (e.g. localhost:8080/health)
Spring Boot 2.0 actuator:
Only the health and info are turned on by default.
Health actuator would give a simple answer of UP / DOWN. To show others you need to set them in configuration.
All actuator must have the endpoint prefix in URL. The default prefix
is "actuator" (e.g. http://localhost:8080/actuator/health)
See the following sites for more details:
Spring Boot Actuator (very detailed explanation)
Spring Boot Actuator 1.X Official Document
Spring Boot Actuator 2.0 Official Document

Spring Cloud Stream Rabbit Binder Routing Key always '#'

Version: Spring Boot: 1.4.2.RELEASE
Spring Cloud Deps: Brixton.SR7
Here is my application.properties of a processor app.
logging.level.=DEBUG
server.port=0
logging.file=traveller-events-processor.log
server.port=0
spring.cloud.stream.rabbit.bindings.input.consumer.bindingRoutingKey='aa'
spring.cloud.stream.rabbit.bindings.input.consumer.bindingRoutingKey=aa
spring.cloud.stream.rabbit.bindings.input.consumer.bindQueue=true
spring.cloud.stream.rabbit.bindings.input.consumer.routing-key='aa'
spring.cloud.stream.rabbit.bindings.input.consumer.routingKey='aa'
spring.cloud.stream.bindings.input.destination=events-exchange
spring.cloud.stream.bindings.input.group=eventconsumersgroup
spring.cloud.stream.bindings.output.destination=work.out
spring.cloud.stream.bindings.output.contentType=text/plain
spring.cloud.stream.bindings.output.binder=rabbit
spring.cloud.stream.bindings.output.group=traveller-events-output-group
When I start this app, events-exchange is created as expected and bound to a queue named: events-exchange.eventconsumersgroup (which is also ok). But the routingKey is always '#'. I've tried with all the options I have fished from various documentations. Am I missing something here?
I want this app to only subscribe to certain messages (which I want to achieve via the routing key).
I see that Brixton.SR7 uses 1.0.2.RELEASE of Spring Cloud Stream and I don't seem to find the routingKey as a Rabbit consumer property. Do you want to upgrade to Spring Cloud Camden release or the latest one so that you can try using the consumer property: bindingRoutingKey as mentioned here

JBoss Fuse v6.2 - Tracing

What is the way to do message tracing for each request made to the JBoss Fuse 6.2 server? In my case most of the entry points are CXF REST service with the processing delegated to Camel routes in some cases. I would like to do end-to-end tracing with same message id that can correlate the request processing.
In my project, there was a similar requirement. Customer wanted to see all e2e log by executing grep command to system logs with a transaction id.
I used CXF interceptors and MDC logging capability for this as below:
Create a common CXF request and response interceptors. Add them to all your Camel's CXF Server/Client configuration
With your request interceptor, extract transaction id from request (or generte it yourself) then put it into MDC map. MDC is a thread local variable that log4j, slf4j,.. uses.
Print request, it'll have your transaction id as prefix thanks to MDC.
Dont forget to add your MDC key in logging format configuration
All logs you print until the end of operation with this transaction Id until the end.
If you're always using direct-vm, direct for routing then it wont be problem. However as you may know using seda, multi processing, etc. your execution is handled by other threads. Since MDC is thread local variable, you need to manually handle the trouble by transferring it.
With your response interceptor, log response message then clear MDC values.
If you're using CXF as client, you should use same interceptor approach to be able to print client request/reponses with transaction id.
See CXF-RS and MDC links as entry points

Upgrading to Spring cloud 1.0.1 zuul url encoded parameters not working

We use zuul as an gateway to dispatch incoming requests to services.
When we upgraded from 1.0.0, we noticed two issues, one of which we got a workaround to.
The second issue is that in some of the incoming have encoded uris to deal with special characters in the request, e.g. ....rovi//45846 which needs to be changed to rovi%2F%2F45846 in order to pass in.
So for a rest uri like the following POST http://localhost:8902/contentservice/content/subscriptionPackages/624460160/channels/rovi%252F%252F45846
If I make this request directly to the service, it works correctly.
But if I route it through zuul as POST http://localhost:8765/contentservice/content/subscriptionPackages/624460160/channels/rovi%252F%252F45846 then it disappears.
Now if I take the % out it is passed in and treated as an error in the contentservice when I step through the content service front end controller (off course).
What has changed between spring cloud 1.0.0 to 1.0.1 in the zuul functionality to stop this from working. As it definitely was working in 1.0.0.
So the spring cloud team has fixed this in the snapshot releases and you can fixed more detail here
https://github.com/spring-cloud/spring-cloud-netflix/issues/366#issuecomment-106363315