根据线程将日志记录到不同的文件

5
我有一个包含多个“控制器”的应用程序,我希望每个控制器都记录到自己的文件中。对于他们自己的代码来说,这很容易实现,但我还使用了一些使用commons logging 的库代码。我能否让该代码也记录到特定于控制器的文件中?
我想通过线程来实现这种方式:
class Controller {

 public void action() {
  setCurrentThreadLogFile(myLogFile);
  try {
   Library.stuff();
  } finally {
   restoreCurrentThreadLogFile();
  }
 }

}

目前我也在使用commons-logging进行日志记录,使用log4j作为后端。但如果需要的话,我可以更改这个设置或者混合使用(如果在commons logging框架内是可行的)。

我可以通过编写自己的commons logging实现(可能是一个log4j的包装器)来实现这一点,但是否存在现有的解决方案呢?


面向切面编程对你来说是否是一个选项?我认为这可以优雅地解决你的问题。 - Vincent Mimoun-Prat
2个回答

2
您可能想要查看映射诊断上下文(MDC)。Commons logging不支持这些,但是Log4J支持,因此您需要直接使用Log4J来设置。您可能需要编写自己的过滤器来使用MDC进行过滤并应用于附加器。
如果您愿意更改日志记录实现,则可以使用SL4J作为日志记录门面,Logback作为日志记录实现。让控制器或某种过滤器/拦截器向MDC添加一个区分控制器的键的鉴别器值。使用SiftingAppender将日志事件分离到单独的文件中。

我可能会更改自己的库类型代码以使用SLF4J,但是对于不在我的控制范围内且使用commons logging的代码怎么办? - Bart van Heukelom
SLF4J支持遗留API,提供了一个使用其API实现的commons logging。您只需要用jcl-over-slf4j.jar替换commons logging jar即可。请参见链接:http://www.slf4j.org/legacy.html#jcl-over-slf4j。 - Will
我不是很清楚。我知道SLF4J有一个commons logging适配器,但它是否支持MDCs呢?我的意思是,如果我在上下文中使用库代码,日志输出是否会出现在正确的文件中?(虽然我不需要能够在库代码内部编辑MDC)。 - Bart van Heukelom
啊,我明白了。这是一个存储在线程局部变量中的映射表,所以我认为它应该可以正常工作。 - Will
我已经实现了它。运行得非常完美,而且设置起来也很轻松。唯一笨拙的事情就是需要在所有东西周围编写MDC设置包装器代码。 - Bart van Heukelom

1
每个线程一个记录器?将记录器放在ThreadLocal中。如果您正在使用java.util.logging,则Handler可以使调用者透明。

如果我必须编写自己的实现,那么ThreadLocal确实是我会使用的工具。然而,我不使用java.util.logging,因为我无法在Tomcat中正确配置它。 - Bart van Heukelom

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接