【问题标题】:Sharing a single log4j jar file in Tomcat5 between multiple webapps with separate property files在具有单独属性文件的多个 web 应用程序之间共享 Tomcat5 中的单个 log4j jar 文件
【发布时间】:2010-08-23 15:46:46
【问题描述】:

是否可以在 tomcat 5.5 设置中使用单个 log4j jar 文件,它可以被多个 web 应用程序使用并为每个 web 应用程序单独记录?

我编写了大约 8 个不同的 webapp,其中 log4j 属性文件之间唯一真正的区别是日志文件名。但是,如果我尝试将 log4j 从 webapp WEB-INF/lib 目录移动到 tomcat5 shared/lib 目录,我会遇到问题。

所有的属性文件基本上和下面的一样,我只是在代码中使用 System.setProperty("file.name", ) 设置了 file.name。真的没有必要,但我在玩弄为所有组件使用单个属性文件的想法。

log4j.rootLogger=DEBUG, LogFile
# stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d [%t] %-5p %c - %m%n

# LogFile
log4j.appender.LogFile=org.apache.log4j.RollingFileAppender
log4j.appender.LogFile.File=${file.name}
log4j.appender.LogFile.layout=org.apache.log4j.PatternLayout
log4j.appender.LogFile.MaxFileSize=500KB
log4j.appender.LogFile.MaxBackupIndex=5
log4j.appender.LogFile.layout.ConversionPattern=%d [%t] %-5p %c - %m%n

基本上对于每个我想记录到单独文件的组件,但问题是如果我在 shared/lib 目录下包含 log4j,无论哪个 webapp 先被访问,都会有效地定义日志文件被所有 webapps 使用。即我不能使用单独的配置。

我知道的替代方案: 将 log4j 放入每个 war 文件的 WEB-INF/lib 目录中,这样我将获得每个 webapp 的单独配置。

将上面的“LogFile”引用更改为特定于每个 web 应用程序,以便每个属性文件有效地定义单独的配置。这似乎避免了以下错误“log4j:ERROR A “org.apache.log4j.RollingFileAppender”对象不可分配给“org.apache.log4j.Appender”变量。”

即使用类似下面的东西:

对于 WebApp1

log4j.rootLogger=DEBUG, LogFileWebapp1
# stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d [%t] %-5p %c - %m%n

# LogFile
log4j.appender.LogFileWebapp1=org.apache.log4j.RollingFileAppender
log4j.appender.LogFileWebapp1.File=${file.name}
log4j.appender.LogFileWebapp1.layout=org.apache.log4j.PatternLayout
log4j.appender.LogFileWebapp1.MaxFileSize=500KB
log4j.appender.LogFileWebapp1.MaxBackupIndex=5
log4j.appender.LogFileWebapp1.layout.ConversionPattern=%d [%t] %-5p %c - %m%n

对于 WebApp2

log4j.rootLogger=DEBUG, LogFileWebapp2
# stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d [%t] %-5p %c - %m%n

# LogFile
log4j.appender.LogFileWebapp2=org.apache.log4j.RollingFileAppender
log4j.appender.LogFileWebapp2.File=${file.name}
log4j.appender.LogFileWebapp2.layout=org.apache.log4j.PatternLayout
log4j.appender.LogFileWebapp2.MaxFileSize=500KB
log4j.appender.LogFileWebapp2.MaxBackupIndex=5
log4j.appender.LogFileWebapp2.layout.ConversionPattern=%d [%t] %-5p %c - %m%n

我更愿意坚持第一个属性文件的布局,并使其在 webapps 之间尽可能相似,并且还希望不必在每个 webapps 中包含单独的 log4j 副本。理想情况下,我希望只使用从 tomcat 共享 lib 目录到 log4j 系统副本的符号链接。

还有其他选择吗?

【问题讨论】:

    标签: log4j tomcat5.5 web-applications


    【解决方案1】:

    我不会这样做。让每个 webapp 都有自己的 log4j.jar 和自己的 log4j.properties 文件。即使您在所有其他方面都可以正常工作,您也永远无法仅在一个 web 应用上升级 log4j,并且您将很难修改一个应用程序的日志记录而不影响其他应用程序。

    除了维护的痛苦和痛苦之外,如果 log4j 持有类引用,则有可能导致巨大的内存泄漏。每次重新部署 Tomcat 都会创建一个新的应用程序类加载器,其中包含所有类的新版本,因为 log4j 不知道放开它们,所以无法摆脱旧引用,回收内存的唯一方法是重新启动Tomcat 实例。

    Here's an interesting article on using container-level logging. 它描述了您遇到的问题:

    当您在容器的 lib 路径中部署 log4j 时, 不是“log4j-aware”并且您没有设置“上下文存储库” 选择器”为 log4j 你失去了一个主要功能 - 日志配置 在容器中的所有组件中变得完全全局。仅有的 读取一个日志配置文件(从容器的 classpath) 并且容器中的每个组件都看到相同的日志记录 配置。这根本无法与公共日志记录相提并论。 在大多数情况下,这是不可接受的行为;然而 commons-logging 可能会提供以这种方式运行的功能,如果 任何人都认为这很有用。

    当您在容器的 lib 路径中部署 log4j 并使用“上下文 存储库选择器”行为以获取每个组件的日志记录 配置 AND log4j 也在你获得类的组件路径中 强制转换异常(commons-logging 目前也有同样的问题 问题)。这确实是一个单独的问题。

    当您在容器的 lib 路径中部署 log4j 并使用“上下文 存储库选择器”行为以获取每个组件的日志记录 配置和 log4j 不在组件的路径中,那么您将 以与发生的完全相同的方式获取内存泄漏 公共日志记录,并且出于完全相同的原因。

    最简单的解决方案是通过将 log4j 保存在每个应用的 WEB-INF/lib 中来避免该问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多