你觉得java.util.logging足够了吗?

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

你使用替代日志logging服务,如log4j或其他? 如果是这样,为什么? 我希望听到关于不同types项目中的日志logging要求的任何build议,并且在集成框架实际上是必要的和/或有用的时候。

logging与第三方库的依赖关系

在大多数情况下,Java JDK日志本身并不足够。 但是,如果您有一个使用多个开放源代码第三方库的大型项目,那么您很快就会发现其中许多项目具有不同的日志依赖性。

正是在这种情况下,从日志实现中抽象日志API的需求变得非常重要。 我build议使用slf4j或logback (使用slf4j API)作为您的API,如果您想坚持使用Java JDK日志logging,您仍然可以! Slf4j可以输出到许多不同的logging器实现没有问题。

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

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

java.util.logging(jul)从一开始就是不必要的。 只要忽略它。

朱尔本身有以下缺点:

  • 在Java 1.4中引入jul的时候,已经有一个广泛使用的日志框架:LOG4J
  • 预定义的日志级别是:严重,警告,信息,configuration,精细,精细,最好。 我不会告诉你我个人对这些预定义级别的看法,以保持这个答案是半客观的。
  • 可以定义更多的级别。 JUL支持多达4G不同的日志级别,稍微矫枉过正,恕我直言。 有时候更less。
  • 最重要的一点是: 如果你敢定义你自己的日志级别,你可能会遇到内存泄漏问题!
    随意阅读这里的效果:

    • 类加载器泄漏:可怕的“java.lang.OutOfMemoryError:PermGen空间”exception
    • 如何解决可怕的“java.lang.OutOfMemoryError:PermGen空间”exception(类加载器泄漏)

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

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

我个人build议使用SLF4J + Logback组合来进行所有的日志logging。 这两个项目都是由LOG4J后面的人CekiGülcü负责协调的。
SLF4J是一个值得的(但非官方的,因为它不是来自同一个群体)commons.logging的继任者。 它比CL更不成问题,因为它静态地parsing了实际使用的日志logging后端。 另外,它具有比CL更丰富的API。
另一方面,Logback是LOG4J的(非)正式inheritance者。 它本身实现了SLF4J,所以没有任何包装引起的开销。

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

SLF4J是新的孩子。 我已经做了一些工作,这很好。 它的主要优点是参数化日志 ,这意味着你这样做:

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

而不是:

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

所有的string操作只有在语句被实际logging的时候才能完成。 看起来也干净。

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

我们始终使用java.util.logging。 也适用于大型项目。 有几件事情你应该调整(例如默认的格式),但这不符合实际情况。 我发现Java中的日志框架的数量以及它们实现的function蠕变让Java社区感到烦恼和尴尬。 关于伐木的热烈讨论的水平是一个肯定的迹象,一些严重错误的事情。

JUL给你的是一个简单但足够的API,并且可以configuration一个地方来configuration你想查看的日志输出(logging.properties或JMX …)。 它永远在那里,稳定。

所有想要logging的代码都应该遵循标准的约定(默认级别是INFO),否则就不要再使用有意义名称的logging器(例如包或类名),你就可以。

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

许多使用Log4J日志logging的项目在“标准”日志loggingAPI存在之前使用它。

JDK日志工具一直做我所需要的 – 从来没有遇到过问题。

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

我无法弄清楚如何控制java.util.logging框架中各个类的日志logging级别,这在log4j中是可能的。 如果我在诊断错误方面遇到问题,或者有一个logging重要信息的高stream量类,我可以更改单个类的级别以logging更多信息,而让我的其他课程相对安静。

注意这可能是我不知道如何去做,或者java.util.logging可能已经改变,因为我试过了。

java.util.logging很好,但没有一个默认从类path中获取的configuration。 这对我们来说是一个痛苦的时刻,因为我们有很多不共享日志loggingconfiguration的部署,而且这样做在jul

Log4j目前还没有开发太多,所以如果后端部分需要开发的话,logback在我看来是最有活力的select。

(警告:涉及slf4j和logback的一些模糊的发展,但这是由于,而不是导致我上面的声明:))

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

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

我们使用log4j和commons logging 。 我想我们只是使用它们,因为其他人都这么做。 这和我们在jdk支持日志之前使用log4j。

编辑:只是因为其他人都是一个笑话,但可能是为什么我开始与log4j和公共日志logging。

以下是使用公共日志logging的一些原因。

编写一个jul LogManager类非常简单,它将把所有日志logging推迟到使用Log4J的定制实现。 这意味着你可以使用log4j,但是仍然有很好的function,即使用JULlogging的库可以被控制为 – 如果它们使用了Log4J。

既然使用了(和commons-logging),我不得不说真正令非常恼火的是:

 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 

他们为什么select这个devise? 为什么? 另一件事是没有与PatternFormatter附带的PatternFormatter – 你必须推出自己的。

也就是说,我从现在起就错误地使用了jul ,因为它减less了外部依赖,并且使用起来也不复杂。

在我工作的项目中,我们倾向于使用Jakarta的commons-logging。 这不是一个日志系统本身,而是能够包装一些最常见的日志logging器 – log4j,java.util.logging或其他。

因此,基于部署应用程序的环境,开发人员可能相对容易地进行切换(开发人员可能希望在他的机器上使用simplelog或java.util.logging,因为易于维护,而在SIT系统上,log4j可以部署所有应用程序的通用configuration等)

这一切都取决于你的logging要求是什么。 应用程序开发人员使用的API不仅仅是您所看到的,坦率地说,这是问题最less的问题,因为大多数情况下,无论您select哪种select,大多数日志loggingAPI都很容易适应。

重要的部分是你需要什么样的日志configuration操作 ,他们应该告诉你他们需要什么。

  1. 它可以像滚动的文本文件一样简单。
  2. 像login到JMS或数据库可能更复杂。
  3. 它可能需要单独的日志进行性能,审计等。
  4. 在发生日志事件时,可能需要电子邮件的详细信息。

在他们的VAR包中的Log4J已经支持这些和更多,并用他们的API进行testing。 现在使用java.util.logging,你应该可以下载它们,但是它们不像Log4J那样常见,而且可能很难find信息。

另一个要考虑的是你正在使用的供应商API。 大多数供应商为您“强制”一个日志API。 Spring是其中之一,它需要commons-logging。

作为一名开发人员,如果我可以为自己的东西,我会尝试使用java.util.logging,但在现实世界的情况下,你必须撼动他们将在操作中需要什么,并让它驱动你的select,因为他们是谁在应用程序上线时使用这些日志。 它既不是应用程序架构师,也不是应该做出这个select的开发者,尽pipe他们应该提出build议。

有一件事没有人在这个线程中提到 – java.util.logging不支持开箱即用的syslog。 这对我来说是一个破坏性的事情(并且引起了我一阵惊愕,不得不重构java.util.logging的东西来代替更多的果汁。

以下是我今天遇到的情况:

我在所有日志框架中遇到的一个问题是,除非你的团队中的每个人都花时间精确地设置和控制它,否则你永远不知道给定的debugging语句是否会打印出来。

您可能已closures一个级别(debugging),或者您可能closures了一个程序包。

我浪费了太多的时间,假设一个debugging语句将打印,而不是。 现在我主要依靠System.out.println(),只需要完成debugging,然后删除或转换它们。

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

日志logging不是那么复杂,在大多数大型项目当然是合理的。

我个人使用简单logging器 ,但在工作中,我使用我们的企业包装到JDKlogging器。 我使用简单的logging器,由于易于获得它的设置,并且它支持Fatal和Ludicrous之间的7级logging。

如果你需要login你的应用程序,那么你可能做的东西真的是错的。 我认为,报告偶尔出现的问题是可以的,但是在很多具有逻辑的类中进行debugging,信息等语句显然是错误的。 任何大型应用程序在其大部分逻辑填充类中都有logging语句,即使只select正确的logging器,也会造成信息过载。 大多数情况下,信息将不完整,嘈杂或您需要的实际信息是完全丢失。

我基本上说,你应该只需要编写debugging语句来通知用户程序对外部因素的反应

  • 在基于文本的configuration文件中格式化问题。
  • 打开或查找所需文件时出现问题。