如何将 java.util.log 发送到 log4j?

我有一个现有的应用程序,它对 log4j 执行所有的日志记录。我们使用了许多其他库,它们也使用 log4j,或者对 Commons Logging 进行日志记录,最终在我们的环境中使用 log4j。我们的一个依赖项甚至对 slf4j 进行了日志记录,这也可以很好地工作,因为它最终也将委托给 log4j。

现在,我想将 ehcache 添加到这个应用程序中,以满足一些缓存需求。以前版本的 ehcache 使用 commons-log,在这个场景中可以很好地工作,但是从 版本1.6-beta1开始,他们移除了对 commons-log 的依赖,代之以 java.util.log。

对于 java.util.log 中可用的内置 JDK 日志记录并不是很熟悉,是否有一种简单的方法可以将任何发送到 JUL 的日志消息记录在 log4j 中,这样我就可以使用我现有的配置并设置任何来自 ehcache 的日志记录?

查看 JUL 的 javadocs,似乎我可以设置一组环境变量来更改使用哪个 LogManager实现,或许可以使用它来在 JUL Logger类中包装 log4j Logger。这是正确的方法吗?

具有讽刺意味的是,当世界其他地方(大多数地方)正在使用第三方库时,库对内置 JDK 日志记录的使用会造成如此大的麻烦。

68378 次浏览

One approach I have used successfully is to use slf4j as my primary logging API. I then have slf4j bind to log4j. 3rd party dependencies using other frameworks (like JUL) can be bridged to slf4j.

The slf4j site I believe has a bridge for passing java.util.logging events via slf4j (and hence to log4j).

Yes, the SLF4J download contains jul-to-slf4j which I believe does just that. It contains a JUL handler to pass records to SLF4J.

We use SLF4J on our current project and it's worked very well for us. SLF4J is written by Ceki Gülcü, the creator of Log4J, and he's done a really great job. In our code we use the SLF4J logging APIs directly, and we configure SLF4J so that calls from the Jakarta Commons Logging (JCL), java.util.logging (JUL), and Log4J APIs are all bridged to the SLF4J APIs. We need to do that because like you we use third party (open source) libraries that have chosen different logging APIs.

On the bottom of SLF4J, you configure it to use a particular logger implementation. It comes with an internal, or "simple" logger, and you can override this with Log4J, JUL, or Logback. Configuration is all done simply by dropping in different jar files in your classpath.

Originally, we used the Logback implementation, also written by Ceki Gülcü. This is very powerful. However, we then decided to deploy our application to the Glassfish Java EE application server, whose log viewer expects JUL-formatted messages. So today I switched from Logback to JUL, and in just a few minutes I replaced two Logback jars with an SLF4J jar that connects it to the JUL implementation.

So like @overthink, I would heartily recommend using SLF4J in your setup.

@Yishai - Thanks for posting the link to my wiki. The example there redirects JUL to Log4J and I've had it running in a production system for a few years. JBoss 5.x already redirects JUL to Log4J, so I took it out when we upgraded. I have a newer one that redirects to SLF4J, which I use on a few things now. I'll post that when I get a chance.

However, SLF4J already has it:

http://mvnrepository.com/artifact/org.slf4j/jul-to-slf4j

There is a simpler alternative than SLF4J to bridge JUL with log4j, see http://people.apache.org/~psmith/logging.apache.org/sandbox/jul-log4j-bridge/examples.html

You just have to put the jul-log4j-bridge on the classpath and add a system property:

-Djava.util.logging.manager=org.apache.logging.julbridge.JULBridgeLogManager

jul-log4j-bridge is not in Maven Central and can be fetched from this repository:

<repository>
<id>psmith</id>
<url>http://people.apache.org/~psmith/logging.apache.org/repo</url>
<releases>
<enabled>false</enabled>
</releases>
</repository>

and then used with:

<dependency>
<groupId>org.apache.logging</groupId>
<artifactId>apache-jul-log4j-bridge</artifactId>
<version>1.0.0-SNAPSHOT</version>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>log4j</groupId>
<artifactId>apache-log4j-component</artifactId>
</exclusion>
</exclusions>
</dependency>

It's also possible to rebuild it from sources with the following steps:

  1. svn co http://svn.apache.org/repos/asf/logging/sandbox/jul-to-log4j-bridge/
  2. edit pom.xml, replace the dependency on log4j:log4j:1.2.15 with log4j:apache-log4j-extras:1.2.17 and remove the dependency on apache-log4j-component
  3. mvn package

OCTOBER 2014

Since version 2.1 of log4j exists the component log4j-jul, which allows exactly this. Still, in case you are using log4j 1, it has to be possible to upgrade to log4j2 in order to use this approach.

JDK Logging Adapter

Class LogManager

Migrate from log4j 1.x to log4j 2

you should manually add blew at startup

SLF4JBridgeHandler.removeHandlersForRootLogger()
SLF4JBridgeHandler.install()

demo -> https://gist.github.com/jiahut/654ecc75a13b0a1d8f3b4d5d2d69dc6d