我有一个系统,其中包含使用 JMS 和 Spring Integration 连接在一起的多个应用程序。消息沿着一系列应用程序发送。
[应用 A] -> [应用 B] -> [应用 C]
我们在消息头中设置了一个全局 id,这样我们就可以通过系统跟踪每个消息的生命周期。
我希望能够在系统中的任何日志消息之前添加消息全局 ID。
有没有其他人这样做过?有什么方法可以将此变量与 Thread 相关联,以便我可以在以后的方法中访问它?我宁愿不在系统的方法中传递变量。
我有一个系统,其中包含使用 JMS 和 Spring Integration 连接在一起的多个应用程序。消息沿着一系列应用程序发送。
[应用 A] -> [应用 B] -> [应用 C]
我们在消息头中设置了一个全局 id,这样我们就可以通过系统跟踪每个消息的生命周期。
我希望能够在系统中的任何日志消息之前添加消息全局 ID。
有没有其他人这样做过?有什么方法可以将此变量与 Thread 相关联,以便我可以在以后的方法中访问它?我宁愿不在系统的方法中传递变量。
我认为 ThreadLocal 可能是您想要的,尽管有些人可能会发现这种方法滥用 ThreadLocal 的目的或良好的设计。就像是:
public class MyIDManager {
public static final ThreadLocal<Long> myID = new ThreadLocal<Long>();
}
...
// set ID at some point
MyIDManager.myID.set(theNewID);
...
// read it later
long currentID = MyIDManager.get();
这里的神奇之处在于 myID 的值实际上是特定于一个线程的,并且在从不同的线程访问时会有所不同。
然后,您可以使用该 ID 做您喜欢的事情,包括记录它。
Thread t = Thread.currentThread();
t.setName("Your ID Here");
我相信第一篇文章暗示的另一个答案是简单地要求您的日志框架在日志语句中包含线程名称。例如,log4j 允许您在其 PatternLayout 中添加带有“t”的线程名称:http: //logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/PatternLayout.html 我在其他地方看到过这个框架也是。
顺便说一句,这种方法是更广泛的企业日志记录模式的一部分。我试图在这里记录这种模式。总结是:
TL;博士
在“进程”的最早开始创建一个 ID,它是“原始 ID”和“唯一 ID”的组合。这个与业务无关的全局初始 ID (GIID) 应该用于每个日志输出,以提供机器可读性和工具使用。当获得或生成每个新的业务级别或操作 ID 时,都会记录它以提供与此 GIID 的“关联”。这类似于各种现有实践,因此它被呈现为软件设计模式。