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


84

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

现在,我想为一些缓存需求将ehcache添加到此应用程序。先前版本的ehcache使用commons-logging,在这种情况下本来可以很好地工作,但是从1.6-beta1版本开始,他们已经删除了commons-logging的依赖关系,并改为使用java.util.logging。

并不是很熟悉java.util.logging可用的内置JDK日志记录,是否有一种简单的方法来针对log4j记录发送到JUL的任何日志消息,因此我可以使用现有配置并为即将到来的任何日志记录进行设置从ehcache?

查看JUL的javadocs,看来我可以设置一堆环境变量来更改LogManager所使用的实现,并可能使用它来将log4j封装Logger在JULLogger类中。这是正确的方法吗?

具有讽刺意味的是,当世界上大多数(大多数)使用第三方库时,库使用内置的JDK日志记录会引起如此麻烦。

Answers:


37

我成功使用的一种方法是使用slf4j作为我的主要日志记录API。然后,我将slf4j绑定到log4j。使用其他框架(如JUL)的第三方依赖性可以接到slf4j。


2
良好的联系,但我认为你的意思#七月到SLF4J
araqnid

这听起来像是一种好方法,除了我似乎无法使其起作用:(
matt b

2
另外,我无法相信,一个图书馆一样受欢迎的Ehcache会让切换到类似的java.util.logging -看起来很愚蠢的
亚光b

1
@matt b,JUL始终存在于Java运行时中,因此它需要最少的外部依赖关系。但是,在我眼中,这是由没有使用该代码经验的人编写的代码的真实示例。配置系统相当不方便。
托尔比约恩Ravn的安德森

1
您遇到的问题是,如果将SLF4J桥接到JUL,则日志记录性能令人震惊。具体来说,您创建的每个日志行都会引发异常,从而确定要使用的记录器上下文。这会产生大量开销,并
拖慢

19

我们在当前项目中使用SLF4J,对我们来说效果很好。SLF4J由Log4J的创建者CekiGülcü编写,他做得非常出色。在我们的代码中,我们直接使用SLF4J日志记录API,并配置SLF4J,以便来自Jakarta Commons Logging(JCL),java.util.logging(JUL)和Log4J API的调用都桥接到SLF4J API。我们需要这样做,因为像您一样,我们使用选择了不同日志API的第三方(开源)库。

在SLF4J的底部,将其配置为使用特定的记录器实现。它带有一个内部或“简单”记录器,您可以使用Log4J,JUL或Logback覆盖它。只需在类路径中放入不同的jar文件即可完成配置。

最初,我们使用了同样由CekiGülcü编写的Logback实现。这是非常强大的。但是,我们随后决定将我们的应用程序部署到Glassfish Java EE应用程序服务器,该服务器的日志查看器需要JUL格式的消息。因此,今天我从Logback切换到JUL,在短短的几分钟内,我用一个SLF4J jar替换了两个Logback jar,并将其连接到JUL实现。

因此,像@overthink一样,我衷心推荐在您的设置中使用SLF4J。


8
Ceki需要多少次重新创建日志记录框架/ fascade?
mP。

@mP:日志记录可能并不漂亮,但这是对大型商业级软件的关键需求。SLF4J解决了集成使用不同日志记录框架的代码的问题(Sun选择开发java.utils.logging而不是采用Log4J变得更加紧急)。
Jim Ferrans 2010年

3
@ mP,slf4j是必需的,因为Sun对JUL所做的工作很糟糕。Logback是log4j的分支,而不是新项目。
托尔比约恩Ravn的安德森

3
我发现有必要进行logback,如果没有其他要求,它不是Apache,而是实际记录在案。
斯潘塞·科莫斯

13

有比SLF4J更简单的替代方法,可以将JUL与log4j桥接,请参阅http://people.apache.org/~psmith/logging.apache.org/sandbox/jul-log4j-bridge/examples.html

您只需要将jul-log4j-bridge放在类路径上并添加系统属性:

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

jul-log4j-bridge不在Maven Central中,可以从此存储库中获取:

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

然后用于:

<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>

还可以通过以下步骤从源中重建它:

  1. svn co http://svn.apache.org/repos/asf/logging/sandbox/jul-to-log4j-bridge/
  2. 编辑pom.xml,将对log4j:log4j:1.2.15的依赖替换为log4j:apache-log4j-extras:1.2.17并删除对apache-log4j-component的依赖
  3. mvn包

4
我认为它更简单,因为它可以在不更改代码的情况下完成,只需添加系统属性即可。SLF4J还没有提出类似的机制,您可以更改代码或logging.properties文件。
Emmanuel Bourg

1
不幸的是,这在log4j2中不存在:(
BeepDog 2013年

JulLog4jBridge.assimilate();o_0
Bastian Voigt

2
警告!jul-log4j-bridge使用永不发布的apache-log4j-companions捆绑包(来自被弃用的反向端口log4j 1.3)。您将很难构建它。当然,该桥本身也被放弃了。
ivan_pozdeev 2015年

@ivan_pozdeev好,谢谢。我已经添加了构建说明。
伊曼纽尔·布尔格

9

2014年10月

由于log4j的版本2.1存在组件log4j-jul,因此完全可以做到这一点。不过,如果您使用的是log4j 1,则必须升级到log4j2才能使用此方法。

JDK记录适配器

类LogManager

从log4j 1.x迁移到log4j 2


2
截至目前(2018年中),这应该是公认的答案
rmuller

对于未来的读者:我确认这是可行的。因此,基本上(1)将其添加到pom mvnrepository.com/artifact/org.apache.logging.log4j/log4j-jul中,以及(2)在第一个链接中添加系统属性(例如,在JVM参数中添加-Djava。 util.logging.manager = org.apache.logging.log4j.jul.LogManager)
Hossam El-Deen

3

我相信slf4j站点有一个桥梁,可以通过slf4j传递java.util.logging事件(从而传递到log4j)。

是的,SLF4J下载包含jul-to-slf4j,我相信这样做就可以了。它包含一个JUL处理程序,以将记录传递到SLF4J。



By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.