如何使用 logback 和 slf4j 为每个事务分配唯一 ID

How to assign a unique id for every transaction using logback and slf4j

我正在使用 spring 框架 jersey 框架开发电子商务企业 j2ee 应用程序。目前我们正在记录所有事务(通过使用来自 queue/through 网络服务请求的消息创建的事务)。

比方说,我有一条消息在我的组件中处理时失败了。我想获取该事务的所有日志(所有日志级别信息、调试、错误...)。目前我正在查看线程名称以确定该事务的所有日志。我不想长期依赖它,因为线程名称在某个时间点后可能会相同。

2016-07-14 02:45:50,716 [DefaultMessageListenerContainer-3] DEBUG SomeClass – someMethod1() - Method Entry

2016-07-14 02:45:50,724 [DefaultMessageListenerContainer-3] SomeClass1 – someMethod2() number of rows inserted: [1]

2016-07-14 02:45:50,724 [DefaultMessageListenerContainer-3] DEBUG SomeClass - someMethod1() - Method Exit

我能不能有这样的日志

2016-07-14 02:45:50,716 [sometransactionnbr] [DefaultMessageListenerContainer-3] DEBUG SomeClass – someMethod1() - Method Entry

2016-07-14 02:45:50,724 [sometransactionnbr] [DefaultMessageListenerContainer-3] SomeClass1 – someMethod2() number of rows inserted: [1]

2016-07-14 02:45:50,724 [sometransactionnbr] [DefaultMessageListenerContainer-3] DEBUG SomeClass - someMethod1() - Method Exit

如何在不更改我编写的每个方法的代码的情况下轻松添加此 "sometransactionnbr"?

遗憾的是,没有快速变化...

首先,您需要使用映射诊断上下文 (MDC) 来设置您的 transactionID。此实用程序 class 允许设置与已执行操作相关的上下文信息(您可以设置任何有助于您以更清晰的方式审核日志的信息)。

理想情况下,您的 transansationID 必须在您的操作(业务方法)开始时设置并在结束时删除。配置后,transactionID 可用于任何记录的事件(即使这些事件是由内部方法调用记录的。因此您不需要将此类信息传递给内部方法......记录器将为您管理)。

(非常重要:MDC 将上下文链接到执行 MDC.put() 方法的线程 ... 所以,如果您的应用程序服务器重用线程(大多数他们中的一个)并且您没有正确清理上下文,您将记录具有过时上下文的事件(同一线程先前执行的事件)......此外,上下文将是一个线程的本地,所以如果你是调用在另一个线程执行的另一个方法,这样的上下文信息将不会传递!!!(在这种情况下,您将需要以其他方式传递这些信息)。

其次,您必须修改记录器配置以将此上下文参数包含到您的模式中....示例:

%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] [%X{txID}] (%t) %m%n

其中 %X 从 MDC 检索参数。

希望这对您有所帮助...

更新:示例使用...

public class MyBusinessClass {
    private static TxIDGenerator generator = new TxIDGenerator();
    ...
    public void myBusinessMethod() {
        String txID = generator.nextValue();
        MDC.put("txID", txID);
        try {
            businessStuffA();
            businessStuffB();
            ...
            //some business stuff
        } finally {
            MDC.remove("txID");
        }
    }
}