你发现java.util.logging足够吗?

时间:2009-03-03 19:51:37

标签: java logging frameworks

根据标题,您是否找到了足以满足您需求的默认Java日志框架?

您是否使用其他日志记录服务,例如log4j或其他?如果是这样,为什么? 我想听听您对不同类型项目中的日志记录要求的任何建议,以及何时集成框架实际上是必要和/或有用的。

17 个答案:

答案 0 :(得分:46)

从一开始就没有必要使用java.util.logging(jul)。只是忽略它。

jul本身有以下缺点:

  • 当jul在Java 1.4中引入时,已经有一个广泛使用的日志框架:LOG4J
  • 预定义的日志级别为:SEVERE,WARNING,INFO,CONFIG,FINE,FINER,FINEST。我不会告诉你我个人对这些预定义级别的看法,以保持这个答案的半目标。
  • 可以定义其他级别。 jul支持多达4G不同的日志级别,这有点矫枉过正,恕我直言。有时更少。
  • 最重要的一点:如果您敢于定义自己的日志级别,则可能会遇到内存泄漏问题!
    请在这里阅读有关此效果的信息:

    这是一个非常有趣的阅读,即使你不打算使用自定义级别,顺便说一句,因为问题是一个广泛的问题,根本不适用于jul。

  • 它驻留在java。*名称空间中,因此无法在运行时交换实现。这有效地防止它以与commons.logging和LOG4J相同的方式桥接到SLF4J。为jul完成桥接的方式会对性能产生影响。这使得jul成为最不灵活的日志框架。
  • 通过引入jul,Sun隐含地将其定义为“标准java日志框架”。这导致了一个普遍的误解,即“优秀的Java公民”应该在他们的图书馆或应用程序中使用jul 情况恰恰相反。
    如果您使用commons.logging或LOG4j,您将能够通过桥接到SLF4J来交换实际使用的日志框架(如果您需要)。这意味着使用commons.logging,LOG4J或SLF4J的库都可以记录到同一个记录目标,例如文件。

我个人建议使用SLF4J + Logback组合进行所有日志记录。这两个项目都是由LOG4J背后的人CekiGülcü协调 SLF4J是一个值得(但非官方,因为它不是来自同一组)commons.logging的继承者。它比CL更少问题,因为它静态地解析了实际使用的日志记录后端。此外,它具有比CL更丰富的API 另一方面,Logback是LOG4J的(非)官方继承者。它本地实现了SLF4J,因此任何包装器都不会产生任何开销。

现在 如果你仍然认为我应得的话,你可能会贬低我。 ;)

答案 1 :(得分:23)

使用第三方库记录依赖关系

在大多数情况下,Java JDK日志记录本身并不足够。但是,如果您有一个使用多个开源第三方库的大型项目,您将很快发现它们中的许多都具有不同的日志记录依赖项。

在这些情况下,需要从日志记录实现中抽象日志API变得非常重要。我建议使用slf4jlogback(使用slf4j API)作为您的API,如果您想坚持使用Java JDK日志记录,您仍然可以! Slf4j可以毫无问题地输出到许多不同的记录器实现。

在最近的一个项目中发生了它的实用性的一个具体例子:我们需要使用需要log4j的第三方库,但是我们不想并行运行两个日志框架,所以我们使用了slf4j log4j api包装器库问题解决了。

总之,Java JDK日志记录很好,但是我的第三方库中使用的标准化API将为您节省时间。试着想象一下每个日志声明的重构!

答案 2 :(得分:16)

SLF4J是新生儿。我已经完成了一些工作,它非常好。它的主要优点是parametrized logging,这意味着你这样做:

logger.debug("The new entry is {}. It replaces {}.", entry, oldEntry);

而不是:

logger.debug("The new entry is " + entry + ". It replaces " + oldEntry + ".");

只有在实际记录语句时才进行所有字符串操作。看起来也更干净。

应该注意的是,SLF4J是一个类似于commons-logging的包装器,尽管它声称不太容易出现commons-logging的类加载器问题。

答案 3 :(得分:11)

我们始终使用java.util.logging。也适用于大型项目。您应该调整一些内容(例如默认格式),但这不是真正的要点。 我发现Java中的日志记录框架的数量和它们实现的功能蠕变相当烦人,并且对Java社区有点尴尬。关于伐木的宗教辩论水平是一个严重错误的明确迹象。

JUL为您提供的是一个简单但足够的API和一个单独的位置来配置您想要查看的日志输出(logging.properties或JMX ...)。它始终存在且稳定。

所有想要记录的代码都应该遵守标准约定(默认级别为INFO),否则不要再使用有意义名称的记录器(例如包或类名),你会没事的。

答案 4 :(得分:8)

除非有令人信服的理由使用JDK之外的东西,否则我更喜欢使用Sun提供的东西。

许多使用Log4J日志记录的项目都是在“标准”日志记录API存在之前使用它。

答案 5 :(得分:7)

JDK日志记录工具始终完成了我需要他们做的事情 - 从来没有遇到过问题。

对我而言,第三方日志记录工具既不必要也不可取。

答案 6 :(得分:5)

我无法弄清楚如何在java.util.logging框架中控制各个类的日志记录级别,这在log4j中是可能的。如果我在诊断错误时遇到问题,或者有一个记录重要信息的高流量类,我可以更改单个类的级别以记录更多,并使其余的类保持相对安静。

N.B。可能是我无法弄清楚如何做到这一点,或者java.util.logging可能已经改变,因为我尝试过。

答案 7 :(得分:2)

java.util.logging很不错,但没有默认从类路径中获取的配置。这对我们来说是一个痛点,因为我们有许多部署不共享日志配置,而且在j.u.l中执行此操作相当混乱。

Log4j目前还没有开发得太多,所以如果需要在后端部分进行开发,那么logback目前是我认为最具活力的选项。

(警告:涉及slf4j和logback的一些模糊开发,但这是由于并且没有导致我在上面做出的陈述:))

答案 8 :(得分:1)

我们将log4jcommons logging一起使用。 我想我们只是使用它们,因为其他人都这样做。 那和我们在jdk支持的日志记录之前使用log4j。

编辑:只是因为其他人都是个笑话,但可能是我开始使用log4j和commons登录的原因。

Here are some reasons to use commons logging.

答案 9 :(得分:1)

编写j.u.l LogManager类非常容易,它会将所有日志记录推迟到使用Log4J的定制实现。这意味着你可以使用log4j,但仍然有一个很好的功能,即使用j.u.l记录的库可以被控制为 - 如果他们使用了Log4J。

使用了两个(和公共日志记录),我不得不说真的,真的真的让我烦恼的是:

log4j.error("An Exception", e);

jul.severe("An Exception", e); // GRRR! no such method

jul.log(Level.SEVERE, "An Exception", e); //Must use this method

他们为什么选择这种设计?为什么?另一件事是PatternFormatter附带了j.u.l - 你必须自己动手。

那就是说,我从现在开始使用j.u.l,因为它减少了外部依赖,并且使用起来并不复杂。

答案 10 :(得分:1)

在我工作的项目中,我们倾向于使用来自雅加达的公共记录。这不是一个日志系统本身,而是能够包装一些最常见的记录器 - log4j,java.util.logging或其他。

通过这种方式,可以相对轻松地根据部署应用程序的环境切换日志记录(开发人员可能希望在他的机器上使用simplelog或java.util.logging,因为易于维护,而在SIT上系统,可以部署所有应用程序的通用配置的log4j等。)

答案 11 :(得分:1)

我以为我会使用log4j - 正如@ ScArcher2所提到的,只是因为每个人都这么做。但是在处理了这两个选项之后,我发现java.util.logging足以满足我的大部分需求 - 而且我所说的是一个庞大的系统,其中包含许多扩散组件。

因此,在我看来,没有必要使用替代服务。 Java.util.logging对于大多数情况来说足够强大。

答案 12 :(得分:1)

这一切都取决于您的日志记录要求。它不仅仅是应用程序开发人员使用的API,而且坦率地说这是问题中最小的问题,因为无论您做出哪种选择,大多数情况下的日志记录API都很容易适应。

重要的部分是操作所需的日志记录配置类型,它们应该告诉您它们需要什么。

  1. 它可以像滚动的文本文件一样简单。
  2. 像登录JMS或数据库一样可能更复杂。
  3. 可能需要单独的日志来进行性能,审核等。
  4. 日志事件发生时可能需要电子邮件详细信息。
  5. 他们的var包中的Log4J已经支持这些以及更多,并使用他们的API进行测试。现在使用java.util.logging你可以下载它们,但它们不像Log4J那样常识,可能更难找到信息。

    要考虑的另一件事是您正在使用的供应商API。大多数供应商都会“强制”为您提供日志记录API。 Spring是其中之一,需要进行公共记录。

    作为一名开发人员,我会尝试使用java.util.logging,如果我可以使用自己的东西,但在现实世界的场景中,你必须动摇他们在操作中需要的东西并让它驱动你的选择,因为他们是那些在应用程序上线时必须使用这些日志的人。它既不是应用程序架构师也不是应该做出选择的开发人员,尽管他们应该提出建议。

答案 13 :(得分:1)

这个帖子中没有人提到的一件事 - java.util.logging不支持开箱即用的syslog。这对我来说是一个交易破坏者(并且让我有点惊愕,不得不重构java.util.logging的东西来代替更多的东西。

这就是我今天遇到的情况:

答案 14 :(得分:0)

我个人使用Simple Logger,但在工作中我使用JDK记录器的公司包装器。我使用Simple Logger,因为它易于设置,并且它支持在Fatal和Ludicrous之间记录7个级别。

答案 15 :(得分:0)

我对所有日志记录框架的一个问题是,除非团队中的每个人花时间熟练掌握如何设置和控制它,否则你永远不知道给定的调试语句是否会打印出来

您可能已关闭关卡(调试),或者您可能关闭了一个包。

我浪费了太多时间假设调试语句会打印而不会打印。现在我主要依赖System.out.println(),并在调试完成后直接删除或转换它们。

我知道这不能回答你的问题 - 我只是说你可能想在增加复杂性之前考虑你有多少理由。

记录并不复杂,在大多数大型项目中肯定是合理的。

答案 16 :(得分:-4)

如果您需要登录您的应用程序,那么您可能确实做错了。我认为报告偶然的问题是可以的,但是在许多具有逻辑的类中使用debug,info等语句是完全错误的。任何在大多数逻辑填充类中都有日志记录语句的大型应用程序,即使只选择正确的记录器,也会导致信息过载。大多数情况下,信息不完整,噪音很大,或者您需要的实际信息很少丢失。

我基本上说你应该只需编写调试语句来告知用户程序对外部因素的反应

  • 在基于文本的配置文件中形成问题。
  • 打开或找到所需文件的问题。