在具有单独属性文件的多个webapps之间在Tomcat5中共享单个log4j jar文件

时间:2010-08-23 15:46:46

标签: log4j tomcat5.5 web-applications

是否可以在tomcat 5.5安装程序中使用单个log4j jar文件,它可以被多个Web应用程序使用,并且每个webapp都有单独的日志记录?

我写了大约8个不同的webapps,其中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”引用更改为特定于每个webapp,以便有效地为每个属性文件定义单独的配置。这似乎避免了以下错误“ 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的系统副本。

还有其他选择吗?

1 个答案:

答案 0 :(得分:6)

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

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

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

  

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

     

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

     

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

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