你觉得 java.util.logging 足够了吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/607863/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Do you find java.util.logging sufficient?
提问by Yuval Adam
Per the title, do you find the default Java logging framework sufficient for your needs?
根据标题,您是否发现默认的 Java 日志框架足以满足您的需求?
Do you use alternative logging services such as log4jor others? If so, why? I'd like to hear any advice you have regarding logging requirements in different types of projects, and when integrating frameworks is actually necessary and/or useful.
您是否使用替代日志记录服务,例如log4j或其他?如果是这样,为什么?我想听听您对不同类型项目中的日志记录要求的任何建议,以及何时集成框架实际上是必要和/或有用的。
采纳答案by Elijah
Logging Dependencies with Third Party Libraries
使用第三方库记录依赖关系
Java JDK logging in most cases is not insufficient by itself. However, if you have a large project that uses multiple open-source third party libraries, you will quickly discover that many of them have disparate logging dependencies.
在大多数情况下,Java JDK 日志记录本身并不足够。但是,如果您有一个使用多个开源第三方库的大型项目,您会很快发现其中许多具有不同的日志依赖项。
It is in these cases where the need to abstract your logging API from your logging implementation become important. I recommend using slf4jor logback(uses the slf4j API) as your API and if you want to stick with Java JDK logging, you still can! Slf4j can output to many different logger implementations with no problems.
在这些情况下,需要从日志实现中抽象出日志 API 变得很重要。我建议使用slf4j或logback(使用 slf4j API)作为您的 API,如果您想坚持使用 Java JDK 日志记录,您仍然可以!Slf4j 可以毫无问题地输出到许多不同的记录器实现。
A concrete example of its usefulness happened during a recent project: we needed to use third-party libs that needed log4j, but we did not want to run two logging frameworks side by side, so we used the slf4j log4j api wrapper libs and the problem was solved.
在最近的一个项目中发生了一个关于它的用处的具体例子:我们需要使用需要 log4j 的第三方库,但我们不想并排运行两个日志框架,所以我们使用了 slf4j log4j api 包装库和问题解决了。
In summary, Java JDK logging is fine, but a standardized API that is used in my third party libraries will save you time in the long run. Just try to imagine refactoring every logging statement!
总之,Java JDK 日志记录很好,但从长远来看,我的第三方库中使用的标准化 API 将为您节省时间。试着想象重构每个日志语句!
回答by Huxi
java.util.logging (jul) was unnecessary from the beginning. Just ignore it.
java.util.logging (jul) 从一开始就没有必要。忽略它。
jul in itself has the following downsides:
jul 本身有以下缺点:
- At the time that jul was introduced in Java 1.4 there was already a well established logging framework in wide use: LOG4J
- the predefined log levels are: SEVERE, WARNING, INFO, CONFIG, FINE, FINER, FINEST. I won't tell you what I personally think about those predefined levels to keep this answer semi-objective.
- Additional levels can be defined. jul supports up to 4G different log levels which is slightly overkill, IMHO. Less is sometimes more.
The most important point: if you dare to define your own log level you are likely to run into a memory leak issue!
Feel free to read about this effect here:- Classloader leaks: the dreaded "java.lang.OutOfMemoryError: PermGen space" exception
- How to fix the dreaded "java.lang.OutOfMemoryError: PermGen space" exception (classloader leaks)
It's a pretty interesting read even if you are not planning to use custom levels, btw, since the problem is a wide-spread one that doesn't just apply to jul at all.
- it resides in the java.* namespace so the implementation can't be exchanged at runtime. This effectively prevents bridging it to SLF4J the same way its possible in case of commons.logging and LOG4J. The way bridging is done for jul has a performance impact. This makes jul the most inflexible logging framework out there.
- By introducing jul, Sun implicitly defined it to be the "standard java logging framework". This led to the common misconception that a "good Java citizen" should use jul in their libraries or applications.
The opposite is the case.
If you use either commons.logging or LOG4j you'll be able to exchange the actually used logging framework, if you ever need to, by bridging to SLF4J. This means that libraries using either commons.logging, LOG4J or SLF4J can all log to the same logging target, e.g. file.
- 在 Java 1.4 中引入 jul 时,已经有一个广泛使用的完善的日志记录框架:LOG4J
- 预定义的日志级别是:SEVERE、WARNING、INFO、CONFIG、FINE、FINER、FINEST。我不会告诉你我个人对这些预定义级别的看法,以保持这个答案半客观。
- 可以定义其他级别。jul 最多支持 4G 不同的日志级别,恕我直言,这有点矫枉过正。少即是多。
最重要的一点:如果你敢于定义自己的日志级别,你很可能会遇到内存泄漏问题!
请随时在此处阅读有关此效果的信息:- 类加载器泄漏:可怕的“java.lang.OutOfMemoryError: PermGen space”异常
- 如何修复可怕的“java.lang.OutOfMemoryError: PermGen space”异常(类加载器泄漏)
即使您不打算使用自定义级别,这也是一本非常有趣的读物,顺便说一句,因为该问题是一个广泛存在的问题,根本不适用于 jul。
- 它驻留在 java.* 命名空间中,因此无法在运行时交换实现。这有效地防止了将其桥接到 SLF4J,就像在 commons.logging 和 LOG4J 的情况下一样。为 jul 完成桥接的方式会影响性能。这使得 jul 成为最不灵活的日志框架。
- 通过引入 jul,Sun 隐含地将其定义为“标准 Java 日志框架”。这导致了一个普遍的误解,即“优秀的 Java 公民”应该在他们的库或应用程序中使用 jul。
情况正好相反。
如果您使用 commons.logging 或 LOG4j,您将能够交换实际使用的日志框架,如果需要的话,通过桥接到 SLF4J。这意味着使用 commons.logging、LOG4J 或 SLF4J 的库都可以记录到相同的日志记录目标,例如文件。
I'd personally suggest to use the SLF4J+Logbackcombo for all logging purposes. Both projects are coordinated by Ceki Gülcü, the guy behind LOG4J.
SLF4J is a worthy (but unofficial since it's not from the same group) successor of commons.logging. It's less problematic than CL because it statically resolves the actually used logging backend. Additionally, it has a richer API than CL.
Logback, on the other hand, is the (un)official successor of LOG4J. It implements SLF4J natively so there's no overhead caused by any wrapper.
我个人建议将SLF4J+ Logback组合用于所有日志记录目的。这两个项目均由 LOG4J 背后的人 Ceki Gülcü 协调。
SLF4J 是一个值得的(但非官方的,因为它不是来自同一组)commons.logging 的继承者。它比 CL 问题少,因为它静态解析实际使用的日志后端。此外,它具有比 CL 更丰富的 API。
另一方面,Logback 是 LOG4J 的(非)官方继承者。它本机实现了 SLF4J,因此没有任何包装器造成的开销。
Nowyou may downvote me if you still think I deserve it. ;)
现在,如果您仍然认为我应得的,您可以否决我。;)
回答by sblundy
SLF4Jis the new kid. I've done a little work with it and it's pretty nice. It's main advantage is parametrized logging, which means you do this:
SLF4J是新来的。我已经用它做了一些工作,它非常好。它的主要优点是参数化日志记录,这意味着您可以这样做:
logger.debug("The new entry is {}. It replaces {}.", entry, oldEntry);
Rather than this:
而不是这样:
logger.debug("The new entry is " + entry + ". It replaces " + oldEntry + ".");
And all that string manipulation is done only if the statement is actually logged. Looks cleaner too.
并且所有这些字符串操作只有在语句被实际记录时才完成。看起来也更干净。
It should be noted that SLF4J is a wrapper like commons-logging, though it claims to be less prone to commons-logging's classloader problems.
应该注意的是,SLF4J 是一个类似于 commons-logging 的包装器,尽管它声称不太容易出现 commons-logging 的类加载器问题。
回答by gnomie
We use java.util.logging throughout. Also for large projects. There is a few things you should tweak (e.g. the default formatting) but that's off the real point. I find the number of logging frameworks in Java and the feature creep they implemented rather annoying and somewhat embarassing for the Java community. The level of religuous debate about logging is a sure sign that something went seriously wrong.
我们始终使用 java.util.logging。也适用于大型项目。有一些事情你应该调整(例如默认格式),但这不是真正的重点。我发现 Java 中日志框架的数量以及它们实现的功能蠕变对于 Java 社区来说相当烦人且有些尴尬。关于伐木的宗教辩论的程度肯定表明出现了严重错误。
What JUL gives you is a simple but sufficient API and a single place to configure what log output you want to see (logging.properties or JMX...). And its always there and stable.
JUL 为您提供的是一个简单但足够的 API 和一个配置您想要查看的日志输出的单一位置(logging.properties 或 JMX...)。它总是在那里并且稳定。
All code that wants to log should stick to the standard conventions (default level is INFO) and otherwise do no more but use loggers of a meaningful name (e.g. package or class name) and you will be fine.
所有想要记录的代码都应该遵守标准约定(默认级别是 INFO),否则不要做更多的事情,而是使用有意义的名称(例如包或类名)的记录器,你会没事的。
回答by TofuBeer
Unless there is a compelling reason to use something outside of the JDK I prefer to use what is provided by Sun.
除非有令人信服的理由使用 JDK 之外的东西,否则我更喜欢使用 Sun 提供的东西。
Many of the projects that use the Log4J logging were using it before the "standard" logging API existed.
许多使用 Log4J 日志记录的项目在“标准”日志记录 API 存在之前就使用了它。
回答by John O
The JDK logging facilities have alwaysdone what I need them to do - never had a problem with it.
JDK 日志记录工具一直在做我需要它们做的事情——从来没有遇到过问题。
To me, third party logging tools are neither necessary nor desirable.
对我来说,第三方日志工具既不必要也不可取。
回答by Michael Sharek
I was unable to figure out how to control the logging level of individual classes in the java.util.logging framework, something that is possible in log4j. If I'm having trouble diagnosing a bug or there is a high-traffic class that logs important information, I can change the level for a single class to log more and leave the rest of my classes relatively quiet.
我无法弄清楚如何控制 java.util.logging 框架中各个类的日志记录级别,这在 log4j 中是可能的。如果我在诊断错误时遇到问题,或者存在记录重要信息的高流量类,我可以更改单个类的级别以记录更多信息,而让其余类相对安静。
N.B. It could be that I couldn't figure out how to do it, or java.util.logging could have changed since I tried.
注意 可能是我不知道该怎么做,或者 java.util.logging 可能在我尝试后发生了变化。
回答by Thorbj?rn Ravn Andersen
java.util.logging is nice but does not have a configuration which is picked up by default from the classpath. That is rather a pain point for us as we have many deployments which does not share logging configurations and it is rather messy to do this in j.u.l.
java.util.logging 很好,但没有默认从类路径中选取的配置。这对我们来说是一个痛点,因为我们有许多不共享日志配置的部署,并且在 7 月执行此操作相当混乱
Log4j is currently not being developed much so if there is a need for development on the backend part logback is at the moment the most dynamic option in my opinion.
Log4j 目前还没有被开发太多,所以如果需要在后端部分进行开发,logback 是目前我认为最具活力的选择。
(caveat: involved in some obscure development of slf4j and logback but that is due to and not causing the statements I make above :) )
(警告:参与了 slf4j 和 logback 的一些晦涩的开发,但这是由于而不是导致我在上面所做的陈述:))
回答by oxbow_lakes
It's pretty easy to write a j.u.lLogManagerclass which will defer all logging to a bespoke implementation which uses Log4J. This means that you can use log4j but still have the nice feature that libraries which log using j.u.l can be controlled as-if they had used Log4J.
编写一个j.u.lLogManager将所有日志记录推迟到使用 Log4J 的定制实现的类非常容易。这意味着您可以使用 log4j,但仍然具有很好的功能,即可以像使用 Log4J 一样控制使用 jul 记录的库。
Having used both (and commons-logging), I have to say that the thing which really, really, reallyannoys me is this:
使用了两者(和 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
Why did they make this design choice? Why? The other thing is that there's no PatternFormatterwhich ships with j.u.l- you have to roll your own.
他们为什么做出这样的设计选择?为什么?另一件事是,没有PatternFormatter随附的东西j.u.l-您必须自己动手。
That said, I'm erring to use j.u.lfrom now on as it cuts down on external dependencies and isn't any more complicated to use.
也就是说,j.u.l从现在开始我错误地使用它,因为它减少了外部依赖并且使用起来也不再复杂。
回答by david a.
In the projects I work on, we tend to use commons-logging from Jakarta. That is not a logging system itself, instead it is able to wrap some of the most common loggers - log4j, java.util.logging or others.
在我从事的项目中,我们倾向于使用来自 Jakarta 的 commons-logging。这不是日志系统本身,而是能够封装一些最常见的记录器 - log4j、java.util.logging 或其他。
With that, it is relatively easily possible to switch the logging based on environment the application is deployed to (a developer may want to use simplelog or java.util.logging on his machine because of ease of maintenance, while on a SIT system, log4j with a common configuration for all apps may be deployed, etc.)
这样,基于应用程序部署到的环境切换日志记录相对容易(开发人员可能希望在他的机器上使用 simplelog 或 java.util.logging 因为易于维护,而在 SIT 系统上,log4j可以部署所有应用程序的通用配置等)

