跨多个线程的Java日志记录

时间:2010-06-04 18:30:43

标签: java multithreading logging

我们有一个使用线程的系统,以便它可以并行地同时处理不同的功能。我们希望找到一种方法将特定“事务”的所有日志条目绑定在一起。通常,可以使用'threadName'将这些收集在一起,但显然在多线程情况下会失败。

如果没有通过每个方法调用传递'事务键',我就看不到将这些方法绑定在一起的方法。将密钥传递给每一种方法都很难看。

此外,我们与Java日志记录有关,因为我们的系统是基于它的修改版本构建的。因此,我会对其他平台感兴趣,以获取我们可能尝试的示例,但切换平台的可能性很小。

有没有人有任何建议?
谢谢,
彼得

编辑:不幸的是,我无法控制线程的创建,因为这些都是由工作流程包处理的。否则,为每个线程缓存一次ID的想法(在ThreadLocal上可能?)然后在创建它们时在新线程上设置它是一个好主意。无论如何,我可能会尝试。

6 个答案:

答案 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如何处理将附加信息绑定到具有MDCNDC类的当前线程的方法。它使用之前建议的ThreadLocal,但有趣的是log4j如何将数据注入日志消息。

//In the code:

MDC.put("RemoteAddress", req.getRemoteAddr());

//In the configuration file, add the following:

%X{RemoteAddress}

详细说明:

http://onjava.com/pub/a/onjava/2002/08/07/log4j.html?page=3

http://wiki.apache.org/logging-log4j/NDCvsMDC

答案 3 :(得分:0)

如何命名您的线程以包含事务ID?诚然,快速和肮脏,但它应该工作(直到你需要其他东西的线程名称或你开始重用线程池中的线程)。

答案 4 :(得分:0)

如果您正在记录,那么您必须拥有某种记录器对象。你应该在每个线程中都有一个特殊的实例。

  • 为其添加一个名为setID(String id)的方法。
  • 在线程中初始化时,使用该方法设置唯一ID。
  • 将set iD添加到每个日志条目。

答案 5 :(得分:0)

  

有几个人建议使用新生成的线程以某种方式知道事务ID是什么的答案。除非我遗漏了某些东西,为了将这个ID放到新生成的线程中,我必须将它一直传递到生成线程的方法中,我宁愿不这样做。

我认为你不需要传递它,而是负责将工作交给这些线程的代码需要传递transactionID。工作分配器不会有这个吗?