我在一个项目中需要管理数十个 Web 应用程序。每个应用程序的日志记录略有不同,管理起来非常痛苦。我使用了类似于您所描述的策略来标准化 log4j,并且效果很好。
基本上,我创建了一个包含共享代码的 common.jar。此 jar 包含一个 log4j.xml,它将日志级别设置为 INFO,并将默认 appender 设置为 common.jar 的 stdout。此 log4j 配置用作所有其他应用程序的基线。
对于这个例子,假设这个类在 common.jar 中:
public class ThirdPartyLib
{
protected static final Logger log = LogManager.getLogger("third-party-lib");
public void doSomething()
{
log.debug("Third Party App is about to Do something!");
log.info("Third Party App just did something");
}
}
现在,所有其他 Web 应用程序都可以简单地依赖 common.jar。例如,假设这个类在 myapp.war 中:
public class MyApp
{
public void CallThirdParty()
{
ThirdPartyLib lib = new ThirdPartyLib();
lib.doSomething();
}
}
由于 log4j.xml 在 common.jar 中,此代码将记录类似这样的内容。换句话说,没有必要将 log4j.xml 放在 myapp.war 中:
2011-01-03 15:49:22,451 [main] INFO third-party-lib - Third Party App just did something
现在,如果您想/需要控制 myapp.war 中的日志记录,只需在 myapp.war 中放置一个 log4j.xml 并覆盖 common.jar 中的设置。例如,您可以将级别设置为 DEBUG,然后您会看到:
2011-01-03 16:03:22,928 [main] DEBUG third-party-lib - Third Party App is about to Do something!
2011-01-03 16:03:22,928 [main] INFO third-party-lib - Third Party App just did something
更新 - 是否可以将每个 webapp 配置为记录到单独的文件?
是的,当然。例如,您可以将日志定向到 RollingFileAppender,而不是 myapp.war 的 log4j.xml 中的 stdout。这很方便,因为您可以将每个单独的 webapp 记录到它自己的单独文件中。
此外,我编写了一个 servlet 过滤器(类似于 gigadot 建议的),它配置 log4j 以检查外部路径(每个 webapp 的战争之外)是否存在 log4j.xml。这样,log4j.xml 文件可以在战争之外访问,并且我们能够在不重新启动 servlet 容器(在本例中为 tomcat)的情况下设置日志级别。如果外部 log4j.xml 不存在,则默认在每个应用程序类路径上使用 log4j.xml。