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

Dar*_*ley 3 log4j web-applications tomcat5.5

是否可以在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
Run Code Online (Sandbox Code Playgroud)

基本上对于我想要记录到单独文件的每个组件,但问题是如果我在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
Run Code Online (Sandbox Code Playgroud)

对于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
Run Code Online (Sandbox Code Playgroud)

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

还有其他选择吗?

Nat*_*hes 6

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

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

这是一篇关于使用容器级日志记录的有趣文章.它描述了您所看到的问题:

当您在容器的lib路径中为不是"log4j-aware"的容器部署log4j而您没有为log4j设置"Context Repository Selector"时,您将丢失一个主要功能 - 日志记录配置在所有组件中变得完全全局容器.只读取一个日志记录配置文件(来自容器的类路径),并且容器中的每个组件都看到相同的日志记录配置.这根本不能与公共记录相比.在大多数情况下,这是不可接受的行为; 然而,如果任何人真正认为这是有用的,那么commons-logging可能会提供一种以这种方式运行的功能.

当您在容器的lib路径中部署log4j并使用"Context Repository Selector"行为来获取每个组件的日志记录配置时,log4j也会在组件的路径中获得类转换异常(commons-logging当前遇到同样的问题).这实际上是一个单独的问题.

当您在容器的lib路径中部署log4j并使用"Context Repository Selector"行为来获取每个组件的日志记录配置并且log4j不在组件的路径中时,您将获得内存泄漏,其方式与commons-logging完全相同,出于完全相同的原因.

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