如何使用 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");
}
}
}
我正在使用 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");
}
}
}