0
votes

I've a filter (OncePerRequestFilter) which basically intercepts incoming request and logs traceId, spanId etc. which works well, this filter lies in a common module which is included in other projects to avoid including spring sleuth dependency in all of my micro-services, the reason why I've created it as a library because any changes to library will be common to all modules. Now I've to add a new propagation key which need to be propagated to all services via http headers like trace and spanId for that I've extracted current span from HttpTracing and added a baggage key to it (as shown below)

 Span span = httpTracing.tracing().tracer().currentSpan();
    String corelationId =
        StringUtils.isEmpty(request.getHeader(CORELATION_ID))
            ? "n/a"
            : request.getHeader(CORELATION_ID);
    ExtraFieldPropagation.set(CUSTOM_TRACE_ID_MDC_KEY_NAME, corelationId);
    span.annotate("baggage_set");
    span.tag(CUSTOM_TRACE_ID_MDC_KEY_NAME, corelationId);

I've added propagation-keys and whitelisted-mdc-keys to my application.yml (with my library) file like below

spring:
  sleuth:
    propagation-keys:
      - x-corelationId
    log:
      slf4j:
        whitelisted-mdc-keys:
          - x-corelationId

After making this change in filter the corelationId is not available when I make a http call to another service with same app, basically keys are not getting propagated.

3

3 Answers

0
votes

I've gone through documentation and seems like I need to add spring.sleuth.propagation-keys and whitelist them by using spring.sleuth.log.slf4j.whitelisted-mdc-keys

Yes you need to do this

is there another way to add these properties in common module so that I do not need to include them in each and every micro services.

Yes, you can use Spring Cloud Config server and a properties file called application.yml / application.properties that would set those properties for all microservices

0
votes

In your library you can implement ApplicationEnvironmentPreparedEvent listener and add the configuration you need there Ex:

@Component
public class CustomApplicationListener implements ApplicationListener<ApplicationEvent> {

    private static final Logger log = LoggerFactory.getLogger(LagortaApplicationListener.class);

    public void onApplicationEvent(ApplicationEvent event) {

        if (event instanceof ApplicationEnvironmentPreparedEvent) {
            log.debug("Custom ApplicationEnvironmentPreparedEvent Listener");
            ApplicationEnvironmentPreparedEvent envEvent = (ApplicationEnvironmentPreparedEvent) event;
            ConfigurableEnvironment env = envEvent.getEnvironment();
            Properties props = new Properties();
            props.put("spring.sleuth.propagation-keys", "x-corelationId");
            props.put("log.slf4j.whitelisted-mdc-keys:", "x-corelationId");

            env.getPropertySources().addFirst(new PropertiesPropertySource("custom", props));
        }
    }

}

Then in your microservice you will register this custom listener

public static void main(String[] args) {
        ConfigurableApplicationContext context = new SpringApplicationBuilder(MyApplication.class)
                .listeners(new CustomApplicationListener()).run();      
    }
0
votes

The answer from Mahmoud works great when you want register the whitelisted-mdc-keys programatically.

An extra tip when you need these properties also in a test, then you can find the anwser in this post: How to register a ApplicationEnvironmentPreparedEvent in Spring Test