Search code examples
javaloggingejb-3.0correlationmdc

EJB3 correlation ID


Now my colleagues work on logging subsystem and they want to bind separate operations, that was initiated from some business method. For example, if method from bean A calls to some method in bean B and then in bean C it will be great to know than business methods in bean B and bean C does some staff for method from bean A. Especially it will be great to know that methods from B and C done some unit of work for concrete call of bean A.

So, the question is how to tie this units of work into something total? Obviously, it is not beautiful to use method arguments for binding!

And also I think that it is time to ask another question, that is close enough to previous one. What if I want to propagate some context information from bean A to another beans, that are called from A? Something like security credentials and security principal? What can I do? May be questions that I asked is some kind of bad practice?


Solution

  • Looks like a good use case for , available in both Logback and Log4J. Essentially you are attaching some custom value to a thread and all logging messages comming from that thread can attach that value to the message.

    I think the best way to implement this in EJB will be an interceptor:

    public class MdcInterceptor {
    
        @AroundInvoke
        public Object addMdcValue(InvocationContext context) throws Exception {
            MDC.put("cid", RandomStringUtils.randomAlphanumeric(16));
            try {
                return context.proceed();
            } finaly {
                MDC.remove("cid");
            }
        }
    }
    

    Now all you have to do is add:

    %X{user}
    

    to your logging pattern (logback.xml or log4j.xml).

    See also