使用tomcat 6在spring webapp中设置Commons Logging / Log4j的问题
Posted
技术标签:
【中文标题】使用tomcat 6在spring webapp中设置Commons Logging / Log4j的问题【英文标题】:Problem with Commons Logging / Log4j setup in spring webapp with tomcat 6 【发布时间】:2010-09-18 02:10:46 【问题描述】:我在部署在 tomcat 6 下的 apring webapp 中的日志记录设置有问题。
webapp 使用 commons-logging api,在运行时应该使用 log4j。日志文件已创建但仍为空 - 不会出现日志条目。
设置如下:
WEB-INF/web.xml:
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>/WEB-INF/log4j.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
WEB-INF/classes/commons-logging.properties:
org.apache.commons.logging.Log=org.apache.commons.logging.impl.Log4JLogger
WEB-INF/log4j.xml:
<log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/'>
<appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
...
</appender>
<appender name="FILE" class="org.apache.log4j.RollingFileAppender">
<param name="File" value="$catalina.home/logs/my.log"/>
...
</appender>
<logger name="my.package">
<level value="INFO"/>
</logger>
<root>
<level value="ERROR"/>
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE"/>
</root>
</log4j:configuration>
文件logs/my.log 已创建,但没有出现日志。是tomcat控制台上的信息日志,但没有配置布局模式。
commons-logging-1.1.1.jar 和 log4j-1.2.14.jar 包含在 WEB-INF/lib 中。知道这里有什么问题吗?
【问题讨论】:
【参考方案1】:网络上有许多记录在案的实例,警告人们使用公共日志记录。如此之多,SLF4J 越来越受欢迎。
考虑到您对将 Tomcat 与 Log4j 一起使用不感兴趣,您应该直接在应用程序中使用 Log4j。特别是如果您将来没有机会切换日志记录框架。它将降低您的应用程序的复杂性,并消除您在使用 commons-logging 时遇到的任何类加载器问题。
这在您的文本中应该是一个相对容易的搜索和替换,因为 commons-logging 和 log4j 都对它们的日志记录方法使用类似的调用结构。
【讨论】:
我认为 commons-logging(从 1.1 开始,之前存在导致内存泄漏的错误)是可以的。但也许直接使用 log4j 是最好的解决方案 - 让使用 commons-logging 的库不记录。 这一切都在 Tomcat 5.5 中有效——有时情况会变得更糟 不,commons-logging 仍然是垃圾(2010),使用 slf4j。 articles.qos.ch/thinkAgain.html【参考方案2】:要特别小心,您没有将 log4j.jar 放在 Tomcat commons/lib 目录中。如果根类加载器加载 log4j 库,当您的 web 应用程序也尝试使用 log4j 时,您将遇到冲突和初始化问题。
如果您需要将 log4j 用于常见的 Tomcat 日志记录,则需要注意您的 web 应用程序不要尝试加载 log4j。如果您在服务器上有多个 webapps,那么您需要遵守规则,每个 webapp 的日志初始化不会影响其他 webapps 的初始化。每个 webapp 都需要使用唯一的 Logger ID,这可以通过唯一的包名称来完成。
在 Tomcat 中使用一个通用的 log4j 和多个 webapps 会导致严重的冲突,如果你有共享的库,比如 Hibernate 或 Spring,都想进行日志记录。下一个尝试初始化 log4j 的 webapp 可能会关闭前一个的记录器。这可能是一团糟。
【讨论】:
【参考方案3】:我遇到了类似的问题,现在找到了解决方法。 用附加参数启动tomcat:
-Dorg.apache.commons.logging.LogFactory=org.apache.commons.logging.impl.LogFactoryImpl
【讨论】:
为我工作!!谢谢 !坚持了1周:P【参考方案4】:您需要编译额外的组件以实现完整的公共日志记录。默认情况下,Tomcat 6 使用一个硬编码的 commons-logging 实现,它总是委托给 java.util.logging。
这里的构建说明http://tomcat.apache.org/tomcat-6.0-doc/building.html
然后替换Tomcat的/bin目录下的tomcat-juli.jar,将tomcat-juli-adapters.jar连同log4j和config一起放到/lib目录下。
【讨论】:
我不会让tomcat本身使用log4j登录,只是我的webapp。或者是否存在不允许提供我自己的公共日志记录的 tomcat 类加载器错误? 如果 Tomcat 的 lib 路径中有 Commons Logging 类,那么它将在加载 WEB-INF/lib 中的任何 JAR 之前加载。 问题是tomcat 6中的类加载器设计(Common不应该有System作为父级)。【参考方案5】:如果你使用 log4j +common logging,你可以避免上面的大部分配置。 common logging LogFactory 具有类似于 JAXP 的发现功能,按照以下优先级,搜索 Log 实现, 1.配置属性org.apache.commons.logging.Log里面的文件commons-logging.properties 2.系统属性org.apache.commons.logging.Log 3. 如果 Log4J 在类路径中可用,则使用相应的包装类(Log4JLogger)。 4. Jdk14Logger 5. 简单日志
只需确保类路径中的 common-logging.jar 和 common-logging-api.jar 和 log4j.jar 都有。
【讨论】:
【参考方案6】:可能是我错了。请尝试以下方法:
A) 将 appender 添加到 my.package 为: 或 B) 将root的日志级别降低到INFO
【讨论】:
没那么简单,我知道配置log4j。以上是关于使用tomcat 6在spring webapp中设置Commons Logging / Log4j的问题的主要内容,如果未能解决你的问题,请参考以下文章
Spring Boot嵌入式Tomcat能否访问定义的spring.tomcat.basedir的webapps文件夹
如何在传统的 tomcat webapps 文件夹中部署 Spring Boot MVC 应用程序?
在不同 Tomcat 中具有 2 个 Spring 应用程序的 SSO