我们有一个使用线程的系统,以便它可以并行地同时处理不同的功能。我们希望找到一种方法将特定“事务”的所有日志条目绑定在一起。通常,可以使用'threadName'将这些收集在一起,但显然在多线程情况下会失败。
如果没有通过每个方法调用传递'事务键',我就看不到将这些方法绑定在一起的方法。将密钥传递给每一种方法都很难看。
此外,我们与Java日志记录有关,因为我们的系统是基于它的修改版本构建的。因此,我会对其他平台感兴趣,以获取我们可能尝试的示例,但切换平台的可能性很小。
有没有人有任何建议?
谢谢,
彼得
编辑:不幸的是,我无法控制线程的创建,因为这些都是由工作流程包处理的。否则,为每个线程缓存一次ID的想法(在ThreadLocal上可能?)然后在创建它们时在新线程上设置它是一个好主意。无论如何,我可能会尝试。
答案 0 :(得分:1)
您可以考虑创建一个全局可访问的Map
,将Thread
的名称映射到其当前的交易ID。在开始新任务时,为该事务生成GUID并使线程在Map
中注册。为生成执行相同任务的任何Thread
执行相同的操作。然后,当您需要记录某些内容时,您只需根据当前Map
的名称从全局Thread
查找交易ID即可。 (有点kludgy,但应该工作)
答案 1 :(得分:1)
这是AspectJ横切的完美示例。如果你知道被调用的方法,你可以在它们上面设置拦截器并动态绑定。
本文将为您提供多个选项http://www.ibm.com/developerworks/java/library/j-logging/
答案 2 :(得分:1)
但是,您提到您的事务跨越多个线程,请查看log4j
如何处理将附加信息绑定到具有MDC
和NDC
类的当前线程的方法。它使用之前建议的ThreadLocal
,但有趣的是log4j如何将数据注入日志消息。
//In the code:
MDC.put("RemoteAddress", req.getRemoteAddr());
//In the configuration file, add the following:
%X{RemoteAddress}
详细说明:
答案 3 :(得分:0)
如何命名您的线程以包含事务ID?诚然,快速和肮脏,但它应该工作(直到你需要其他东西的线程名称或你开始重用线程池中的线程)。
答案 4 :(得分:0)
如果您正在记录,那么您必须拥有某种记录器对象。你应该在每个线程中都有一个特殊的实例。
答案 5 :(得分:0)
有几个人建议使用新生成的线程以某种方式知道事务ID是什么的答案。除非我遗漏了某些东西,为了将这个ID放到新生成的线程中,我必须将它一直传递到生成线程的方法中,我宁愿不这样做。
我认为你不需要传递它,而是负责将工作交给这些线程的代码需要传递transactionID。工作分配器不会有这个吗?