对 Spring 和 Hibernate 的 Java 日志系统感到困惑

发布于 2024-08-18 21:58:42 字数 1209 浏览 3 评论 0原文

当部署我的 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帖子 在带有 tomcat 6 的 spring webapp 中设置 Commons Logging / Log4j 的问题

然而,这甚至超出了我的范围。有人可以澄清这里使用的日志系统,或者向我指出有关此事的最新资源(有一些古老的谷歌搜索结果并不真正适用)。具体来说,我正在努力解决的问题是:

  • 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 吗?

任何帮助将不胜感激。谢谢。


edit:

感谢到目前为止所有的答案。我正在尝试这些建议。 spring web-app 具体怎么样?我已经看到了侦听器和参数以及放入 web.xml 文件中的内容的示例。这也需要吗?

WHen deploying my Spring / Hibernate application, I get the following warning related to logging:

log4j:WARN No appenders could be found for logger (org.springframework.web.context.ContextLoader).
log4j:WARN Please initialize the log4j system properly.

Surprising to me was the lack of information from a Google / SO search. The only thing relevant was this SO post Problem with Commons Logging / Log4j setup in spring webapp with tomcat 6

However, this is even beyond me. Can somebody clarify the logging systems in play here, or point me to a RECENT resource on the matter (there are some ancient google search results that don't really apply). Specifically, the issues I'm wrestling with are:

  • The distinction among commons-logging, log4j, slf4j and JCL. My understanding is that slf4j is a wrapper, while commons-logging and log4j are actual implementations. I don't know where JCL fits in.

  • How to configure logging for Spring. What does in the web.xml file, do i need a log4j.properties file or a log4j.xml file? Where does it go, in WEB-INF? Does anything go in my applicationContext.xml file? (sorry but I need to start from zero here).

  • I am using Hibernate in my project and including via Maven. It seems that Hibernate uses slf4j-simple. I have seen warnings saying that I can't have slf4j-simple and slf4j-log4j both on the classpath. I have not included slf4j-log4j as a dependency, but Hibernate must be including it. How do i solve this problem? Can I force Hibernate to use log4j instead?

Any help would be greatly appreciated. Thanks.


edit:

Thanks for all the answers so far. I am giving these suggestions a try. What about spring web-app specifically? I've seen examples of listeners and parameters and whatnot put into the web.xml file. Is this also required?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

丿*梦醉红颜 2024-08-25 21:58:43
  • commons-loggingSLF4J 都是其他日志记录实现的 API 包装器。 SLF4J 是两者中更现代的一个,而且功能也更强大。 Log4j 是一种日志记录实现,几乎是事实上的标准。 JULjava. util.logging)是 JRE 附带的(通常很糟糕)日志记录实现。另一个日志实现是 logback,它正在慢慢获得关注,但尚未广泛普及。
  • log4j.propertieslog4j.xml 是配置 log4j 的不同方式,两者同样有效。尽管某些应用程序服务器规定了其中之一,但您使用哪一种取决于您。阅读log4j 手册了解如何配置它。
  • 如果 Hibernate 使用 SLF4J 作为其 API,那是 Hibernate 开发人员的选择。但是,您可以选择 SLF4J 将委托给哪个日志记录实现。再次阅读 slf4j 手册,了解如何选择您选择的实现。

是的,这一切都相当令人困惑。如果有一个开放的选择,SLF4J 和 Logback 是最有能力的组合,但你通常不会得到一个开放的选择。不同的框架(如 Hibernate 和 Spring)可能会使用不同的日志记录 API,通常是 commons-logging 或 SLF4J,但您可以让所有这些 API 最终记录到相同的底层实现(通常是 log4j)。

  • commons-logging and SLF4J are both API wrappers around other logging implementations. SLF4J is the more modern of the two, and rather more capable. Log4j is a logging implementation, and pretty much the defacto standard. JUL (short for java.util.logging) is the (generally awful) logging implementation that comes with the JRE. Another log implementation is logback, which is slowly gaining traction, but not at all widespread yet.
  • log4j.properties and log4j.xml are different ways of configuring log4j, both are equally valid. Which one you use is up to you, although some application servers dictate one or the other. Read the log4j manual to find out how to configure this.
  • If Hibernate uses SLF4J as its API, that's the choice of the Hibernate developers. However, you can choose which logging implementation SLF4J will delegate to. Again, read the slf4j manual to find out how to select your chosen implementation.

Yes, it's all rather confusing. Given an open choice, SLF4J and Logback is the most capable combination, but you usually don't get an open choice. Different frameworks (like Hibernate and Spring) will potentially use different logging APIs, usually commons-logging or SLF4J, but you can get all those APIs to eventually log to the same underlying implementation (usually log4j).

深空失忆 2024-08-25 21:58:43
  • commons-logging、log4j、slf4j 和 JCL 之间的区别。我的理解是 slf4j 是一个包装器,而 commons-logging 和 log4j 是实际的实现。我不知道 JCL 适合什么位置。

Commons Logging (JCL) 和 Simple Logging Facade Java SLF4J 都是各种日志框架抽象例如 java.util.logging、log4j 和 logback,允许最终用户在部署时插入所需的日志框架。众所周知,Commons Logging 存在类加载器问题,这正是 SLF4J 试图解决的问题(众所周知,SLF4J 是一个更干净的库)。

话虽如此,事实上 Spring 使用 Jakarta Commons Logging API(请参阅 在 Spring 中记录依赖项):Spring 是针对 JCL 进行编译的,并且 Spring 使 JCL Log 对象可用于扩展 Spring 的类。实际上是 Spring 中唯一的强制外部依赖。这个选择已经做出,因为许多其他框架也在使用它(例如Struts) )。这个想法是为了避免在构建应用程序时在类路径上必须有多个外观库(“A”代表 Spring,“B”代表 Struts 等)。不过,如果您愿意的话,可以用 SLF4J 替换 JCL(SFL4J 提供了对日志记录框架的绑定,同时也是“JCL 到 SLF4J”的桥梁)。请参阅提到的帖子 在 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(这只是 log4j.xml 的另一种格式)配置)到类路径。

  • 我在我的项目中使用 Hibernate,包括通过 Maven。看来Hibernate使用的是slf4j-simple。我看到警告说我不能在类路径上同时存在 slf4j-simple 和 slf4j-log4j 。我没有将 slf4j-log4j 作为依赖项包含在内,但 Hibernate 必须包含它。我该如何解决这个问题?我可以强制 Hibernate 使用 log4j 吗?

Hibernate 利用简单日志外观Java (SLF4J),事实上,你不能有多个绑定 (例如slf4j-simple.jarslf4j-logj12.jar)同时位于类路径上。在这里,您很可能从另一个依赖项传递地获取 slf4j-simple.jar。要解决此问题,请运行 mvn dependency:tree 来找出它的来源,并在需要时将其排除。

顺便说一句,在您的情况下,我将配置 Spring 使用 SLF4J,因为 Hibernate 正在使用它。请按照第一段中提到的链接中的步骤进行操作。我会使用 logback 作为日志框架(log4j 的后继者),这就是现在发生的事情。

  • The distinction among commons-logging, log4j, slf4j and JCL. My understanding is that slf4j is a wrapper, while commons-logging and log4j are actual implementations. I don't know where JCL fits in.

Jakarta Commons Logging (JCL) and Simple Logging Facade for Java SLF4J are both abstractions for various logging frameworks e.g. java.util.logging, log4j and logback, allowing the end user to plug in the desired logging framework at deployment time. Commons Logging is known to suffers from class loader problems which is what SLF4J tries to solve (SLF4J is known to be a cleaner library).

Having that said, the fact is that Spring uses Jakarta Commons Logging API (see Logging Dependencies in Spring): Spring is compiled against JCL and Spring makes JCL Log objects available for classes that extend Spring. The is actually the only mandatory external dependency in Spring. This choice has been made because many other frameworks where also using it (e.g. Struts). The idea was to avoid having to have multiple facade libraries on the class path when building applications ("A" for Spring, "B" for Struts, etc). It is however possible to replace JCL by SLF4J if you want to (SFL4J provides bindings to logging frameworks but also a "JCL to SLF4J" bridge). See the mentioned post Logging Dependencies in Spring for all the details.

  • How to configure logging for Spring. What does in the web.xml file, do i need a log4j.properties file or a log4j.xml file? Where does it go, in WEB-INF? Does anything go in my applicationContext.xml file? (sorry but I need to start from zero here).

To log, you have 1. to decide which implementation you want to use (java.util.logging, log4j or logback), 2. to put the chosen one on the classpath if required (java.util.logging is in Java SE so it doesn't require extra libraries) and 3. to configure it (by putting a config file on the classpath). If you choose to use log4j, just add its jar and a log4j.properties or a more fancy (but more verbose) log4j.xml (this is just another format for the configuration) to the classpath.

  • I am using Hibernate in my project and including via Maven. It seems that Hibernate uses slf4j-simple. I have seen warnings saying that I can't have slf4j-simple and slf4j-log4j both on the classpath. I have not included slf4j-log4j as a dependency, but Hibernate must be including it. How do i solve this problem? Can I force Hibernate to use log4j instead?

Hibernate utilizes Simple Logging Facade for Java (SLF4J) and, indeed, you can't have several bindings (e.g. slf4j-simple.jar and slf4j-logj12.jar) on the classpath at the same time. Here, you are very likely getting slf4j-simple.jar transitively from another dependency. To solve this problem, run mvn dependency:tree to figure out from where it's coming from and exclude it if required.

And by the way, in your case, I would configure Spring to use SLF4J as Hibernate is using it. Follow the steps in the link mentioned in the first paragraph for that. And I would use logback as logging framework (which the successor of log4j), this is where things happen now.

画▽骨i 2024-08-25 21:58:43

您的类路径中需要一个 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,允许一些更复杂的用例。

You need a log4j.properties file in your classpath. Here is a minimal properties file I happened to have created yesterday:

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

Put that into a log4j.properties file, change all the references to 'BillReview' to something more like your project and that'll log to a file and stop those messages.

Your questions about which logging framework are largely personal choice. Log4j is the old standard and it works fine, Commons logging and slf4j are newer APIs and allow some more complicated use cases.

挽袖吟 2024-08-25 21:58:43

我会让一些比我更有经验的大师来回答第一个问题。

回答你的第二个要点...

您可以使用 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>

I'll let some more experienced Gurus than I answer the first bullet.

Answering your second bullet...

You can use either a log4j.properties or log4j.xml file (it doesn't matter which). Whatever you choose you should add it to your classpath (typically it should go in the same directory as your source code). If you are using Spring, a nice way to break your src directory up into logical portions is by using the following directory structure...

src/main/java -- put main source here
src/main/resources -- put resources used by you main source here
src/test/java -- put test source here (for tests)
src/test/resources -- put resources for tests here

You would therefore put your log4j.properties in the src/test/resources directory.

Answering your third bullet...

You can exclude a dependency within a dependency in you pom.xml file by doing the following...

<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>
绝對不後悔。 2024-08-25 21:58:43

我在运行测试时在同一区域遇到了问题。我最终注意到,除了我想要的 slf4j-log4j12 之外,junit 还引入了 slf4j-nop 作为依赖项。一旦我排除了 slf4j-nop,它就开始工作了。

I had problems in the same area while running my tests. I eventually noticed that junit was bringing in slf4j-nop as a dependency, in addition to the slf4j-log4j12 that I wanted. Once I excluded slf4j-nop, it started working.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文