Netflix / Hystrix

Hystrix is a latency and fault tolerance library designed to isolate points of access to remote systems, services and 3rd party libraries, stop cascading failure and enable resilience in complex distributed systems where failure is inevitable.
24.09k stars 4.7k forks source link

How to get MDC after sending it from Tomcat thread to hystrix thread? #2030

Closed aditya3234 closed 2 years ago

aditya3234 commented 2 years ago

I have a class A which runs on tomcat thread. Class B is inside a jar which is a dependency of the project which has class A. Class B is running on hystrix thread. I have implemented a CustomConcurrency strategy and a custom Hystrix hook which puts the MDC from class A in class B.

The logs which are getting printed on class B show the MDC which I put in HystrixHook but when I print MDC.get("id") from Class B, it shows nothing.

I have implemented the concurrency strategy and hystrixhook using this link.

CustomConcurrency.java

public class ThreadLocalUtil {
    private static ThreadLocal<String> idTL = new ThreadLocal<>();

    public static void setId(String id) {
        idTL.set(id);
    }

    public static void getId() {
        return idTL.get();
    }

    public static void clear() {
        idTL.remove();
    }
}

public class ConcurrencyStrategy extends HystrixConcurrencyStrategy {
    @Override
    public <T> Callable<T> wrapCallable(Callable<T> callable) {
        String id = ThreadLocalUtil.getId(); 
        return () -> {
            try{
                ThreadLocalUtil.setId(id); 
                return callable.call();
            } 
            finally { 
                ThreadLocalUtil.clear() 
                } 
        };
    }
}

// Register the concurrency strategy
HystrixPlugins.getInstance().registerConcurrencyStrategy(new ConcurrencyStrategy());

HystrixHook.java

public class HystrixHook extends HystrixCommandExecutionHook {

    private String id;

    @Override
    public <T> void onStart(HystrixInvokable<T> commandInstance) {
        HystrixRequestContext.initializeContext();
        getThreadLocals();
    }

    @Override
    public <T> void onExecutionStart(HystrixInvokable<T> commandInstance) {
        setThreadLocals();
        MDC.put("id",id);
    }

    @Override
    public <T> void onFallbackStart(HystrixInvokable<T> commandInstance) {
        setThreadLocals();
        MDC.put("id",id);
    }

    @Override
    public <T> void onSuccess(HystrixInvokable<T> commandInstance) {
        HystrixRequestContext.getContextForCurrentThread().shutdown();
        super.onSuccess(commandInstance);
    }

    @Override
    public <T> Exception onError(HystrixInvokable<T> commandInstance, HystrixRuntimeException.FailureType failureType, Exception e) {
        HystrixRequestContext.getContextForCurrentThread().shutdown();
        return super.onError(commandInstance, failureType, e);
    }

    private void getThreadLocals() {
        id = ThreadLocalUtil.getId();
    }

    private void setThreadLocals() {
        ThreadLocalUtil.setId(id);
    }
}

// Register hystrix hook plugin
HystrixPlugins.getInstance().registerCommandExecutionHook(new HystrixHook());
aditya3234 commented 2 years ago

Resolved.