在部署我的Spring / Hibernate应用程序时,我收到与日志记录相关的以下警告:
log4j:WARN No appenders could be found for logger (org.springframework.web.context.ContextLoader).
log4j:WARN Please initialize the log4j system properly.
令我惊讶的是Google / SO搜索缺少信息。唯一相关的是这篇SO Problem with Commons Logging / Log4j setup in spring webapp with tomcat 6
但是,这甚至超出了我的范围。有人可以在这里澄清游戏中的日志记录系统,或者指向我关于这个问题的最新资源(有一些古老的谷歌搜索结果并不真正适用)。具体来说,我正在努力解决的问题是:
commons-logging,log4j,slf4j和JCL之间的区别。我的理解是slf4j是一个包装器,而commons-logging和log4j是实际的实现。我不知道JCL适合哪里。
如何配置Spring的日志记录。在web.xml文件中,我需要log4j.properties文件还是log4j.xml文件?它在哪里,在WEB-INF?我的applicationContext.xml文件中有什么内容吗? (对不起,我需要从零开始)。
我在我的项目中使用Hibernate,包括通过Maven。似乎Hibernate使用slf4j-simple。我看到警告说我不能在类路径上有slf4j-simple和slf4j-log4j。我没有将slf4j-log4j作为依赖项包含在内,但Hibernate必须包含它。我该如何解决这个问题?我可以强制Hibernate使用log4j吗?
非常感谢任何帮助。谢谢。
<小时/> 编辑:
感谢目前为止的所有答案。我试试这些建议。具体来说,春季网络应用程序呢?我已经看到了侦听器和参数的示例以及诸如未放入web.xml文件的内容。这还需要吗?
答案 0 :(得分:12)
java.util.logging
的缩写)是JRE附带的(通常很糟糕的)日志记录实现。另一个日志实现是logback,它正在慢慢获得牵引力,但还没有普及。log4j.properties
和log4j.xml
是配置log4j的不同方式,两者都同样有效。您使用哪一个取决于您,尽管某些应用程序服务器会指示其中一个。阅读log4j manual以了解如何配置此功能。是的,这一切都让人感到困惑。如果有一个开放的选择,SLF4J和Logback是最有能力的组合,但你通常不会有一个开放的选择。不同的框架(如Hibernate和Spring)可能会使用不同的日志API,通常是commons-logging或SLF4J,但是你可以让所有这些API最终登录到相同的底层实现(通常是log4j)。
答案 1 :(得分:4)
对于各种日志记录框架,Jakarta Commons Logging(JCL)和Simple Logging Facade for Java SLF4J都是抽象,例如java.util.logging,log4j和logback,允许最终用户在部署时插入所需的日志记录框架。众所周知,Commons Logging会遇到类加载器问题,这是SLF4J试图解决的问题(已知SLF4J是一个更清晰的库)。
- commons-logging,log4j,slf4j和JCL之间的区别。我的理解是slf4j是一个包装器,而commons-logging和log4j是实际的实现。我不知道JCL在哪里。
话虽如此,事实是Spring使用Jakarta Commons Logging API(参见Logging Dependencies in Spring):Spring是针对JCL编译的,Spring使JCL Log
对象可用于扩展Spring的类。实际上它是Spring中唯一的强制外部依赖项。这个选择has been made 因为许多其他框架也在使用它(例如Struts)。这个想法是为了避免在构建应用程序时在类路径上有多个Facade库(Spring的“A”,Struts的“B”等)。但是,如果你愿意,可以用SLF4J代替JCL(强可能)(SFL4J提供了对日志框架的绑定,还提供了“JCL到SLF4J”桥接)。有关所有详细信息,请参阅上述帖子Logging Dependencies in Spring。
- 如何配置Spring的日志记录。在web.xml文件中,我需要log4j.properties文件还是log4j.xml文件?它在哪里,在WEB-INF?我的applicationContext.xml文件中有什么内容吗? (对不起,但我需要从零开始)。
要进行日志记录,您需要1.确定要使用的实现(java.util.logging,log4j或logback),2。如果需要,将选定的实现放在类路径上(java.util.logging在Java SE所以它不需要额外的库)和3.配置它(通过在类路径上放置一个配置文件)。如果你选择使用log4j,只需将它的jar和log4j.properties
或更多花哨(但更详细)log4j.xml
(这只是配置的另一种格式)添加到类路径中。
- 我在我的项目中使用Hibernate,包括通过Maven。似乎Hibernate使用slf4j-simple。我看到警告说我不能在类路径上有slf4j-simple和slf4j-log4j。我没有将slf4j-log4j作为依赖项包含在内,但Hibernate必须包含它。我该如何解决这个问题?我可以强制Hibernate使用log4j吗?
Hibernate utilizes Simple Logging Facade for Java (SLF4J)实际上,您不能同时在类路径上拥有多个bindings(例如slf4j-simple.jar
和slf4j-logj12.jar
)。在这里,您很可能从另一个依赖项传递slf4j-simple.jar
。要解决此问题,请运行mvn dependency:tree
以确定其来源,并在需要时将其排除。
顺便说一句,在你的情况下,我会将Spring配置为使用SLF4J,因为Hibernate正在使用它。请按照第一段中提到的链接中的步骤进行操作。我会使用logback作为日志框架(log4j的后续版本),这就是现在发生的事情。
答案 2 :(得分:2)
您的类路径中需要一个log4j.properties文件。这是我昨天碰巧创建的最小属性文件:
log4j.logger.BillReview=INFO,BillReviewLog
log4j.appender.BillReviewLog=org.apache.log4j.RollingFileAppender
log4j.appender.BillReviewLog.File=BillReview.log
log4j.appender.BillReviewLog.Append=true
log4j.appender.BillReviewLog.MaxFileSize=5000KB
log4j.appender.BillReviewLog.MaxBackupIndex=5
log4j.appender.BillReviewLog.layout=org.apache.log4j.PatternLayout
log4j.appender.BillReviewLog.layout.ConversionPattern=%c %p %-10.10X{server} %-4.4X{user} %d{ISO8601} %m%n
将其放入log4j.properties文件中,将对“BillReview”的所有引用更改为更类似于项目的内容,并将其记录到文件并停止这些消息。
您对哪种日志框架主要是个人选择的疑问。 Log4j是旧标准,它工作正常,Commons日志和slf4j是更新的API,并允许一些更复杂的用例。
答案 3 :(得分:1)
我会让一些更有经验的大师而不是我回答第一颗子弹。
回答你的第二颗子弹......
您可以使用log4j.properties或log4j.xml文件(无关紧要)。无论你选择什么,你都应该将它添加到你的类路径中(通常它应该与你的源代码放在同一个目录中)。如果您使用的是Spring,那么将src目录分解为逻辑部分的好方法是使用以下目录结构...
src / main / java - 把主要来源放在这里
src / main / resources - 把你主要来源使用的资源放在这里
src / test / java - 将测试源放在这里(用于测试)
src / test / resources - 在这里放置测试资源
因此,您可以将log4j.properties放在src / test / resources目录中。
回答你的第三颗子弹......
您可以通过执行以下操作来排除pom.xml文件中依赖项中的依赖项...
<dependency>
<groupId>org.apache.xbean</groupId>
<artifactId>xbean-spring</artifactId>
<version>${xbean.version}</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
答案 4 :(得分:0)
我在运行测试时遇到了同一区域的问题。我最终注意到除了我想要的slf4j-nop
之外,junit还引入了slf4j-log4j12
作为依赖项。我排除slf4j-nop
后,就开始工作了。