EJB3相关ID

时间:2012-02-19 21:43:35

标签: java logging ejb-3.0 correlation mdc

现在,我的同事正在研究日志记录子系统,他们希望绑定从某些业务方法启动的单独操作。例如,如果来自bean A的方法调用bean B中的某个方法,然后在bean C中调用bean,那么知道比bean B中的业务方法更好,并且bean C为Bean A中的方法做了一些工作。特别是它会很棒知道B和C的方法完成了一些工作单元的具体调用bean。

那么,问题是如何将这些工作单元整合到一起?显然,使用方法参数进行绑定并不漂亮!

而且我认为现在是时候提出另一个问题,这个问题与前一个问题相近。如果我想将一些上下文信息从bean A传播到另一个从A调用的bean,该怎么办?安全凭证和安全主体之类的东西?我能做什么? 可能是我问的问题是某种不良做法?

2 个答案:

答案 0 :(得分:3)

看起来是的一个很好的用例,LogbackLog4J都可用。基本上,您将一些自定义值附加到一个线程,并且来自该线程的所有日志消息都可以将该值附加到该消息。

我认为在EJB中实现它的最佳方法是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");
        }
    }
}

现在你需要做的就是添加:

%X{user}

到您的记录模式(logback.xmllog4j.xml)。

另见

答案 1 :(得分:0)

对于通用上下文信息,您可以使用TransactionSynchronizationRegistry。它可能看起来像这样:

@Stateless
public class MyBean {

    @Resource
    TransactionSynchronizationRegistry registry;

    @AroundInvoke
    public Object setEntryName(InvocationContext ic) throws Exception {
        registry.putResource(NAME, "MyBean");
        return ic.proceed();
    }
}

@Stateless
public class MyBean2 {

    @Resource
    TransactionSynchronizationRegistry registry;

    public void doJob() {
        String entryName = (String)registry.getResource(NAME);
        ...
    }
}

我相信它通常使用ThreadLocal变量实现,因为通常每个事务都映射到应用程序服务器中的sigle线程。因此,如果您的AS中没有实现TransactionSynchronizationRegistry(例如在JBoss 4.2.3中),或者您需要较低级别的工具,则可以直接使用ThreadLocal变量。

BTW我想MDC实用程序使用相同的东西。