使用java.util.logging的好例子


273

我想在程序中使用日志。我听说过java.util.logging,但是我不知道如何开始。

有什么示例可以记录日志?我将如何在自己的程序中使用日志记录?


7
您可以从这里开始:slf4j.org/manual.html
杰里米(Jeremy)

1
我同意史蒂芬·瓦斯切罗(Steven Vascellaro)的观点。我讨厌看到有用的项目因主题警务而没有实际目的而被销毁。此外,OP询问有关java.util.logging的信息时,请与Jeremy表示不同意。我也有兴趣在本地日志记录(感谢您的回答,grwww!)
NOP

要将数据记录在一行中:log.log(Level.INFO,“我的消息{0}”,新的Object [] {m​​yDataId});
米娅·贾斯汀

Answers:


335

java.util.logging 使您不必再为应用程序携带一个jar文件,并且与良好的Formatter一起使用效果很好。

通常,在每个课程的顶部,您应该具有:

private static final Logger LOGGER = Logger.getLogger( ClassName.class.getName() );

然后,您可以使用Logger类的各种功能。


使用Level.FINE任何东西是调试在执行流程的最高级别:

LOGGER.log( Level.FINE, "processing {0} entries in loop", list.size() );

在循环内部以及调试基本流程问题时不一定总是需要看到这么多细节的地方使用Level.FINER/ Level.FINEST

LOGGER.log( Level.FINER, "processing[{0}]: {1}", new Object[]{ i, list.get(i) } );

使用日志记录工具的参数化版本可避免生成大量GC必须跟上的String级联垃圾。Object[]如上便宜,通常在堆栈上分配。


使用异常处理时,请始终记录完整的异常详细信息:

try {
    ...something that can throw an ignorable exception
} catch( Exception ex ) {
    LOGGER.log( Level.SEVERE, ex.toString(), ex );
}

我总是ex.toString()在这里作为消息传递,因为当我在日志文件中grep -n为“ Exception”输入时,我也可以看到该消息。否则,它将位于堆栈转储生成的输出的下一行,并且您还必须具有更高级的RegEx来匹配该行,这通常会使您获得比查看所需更多的输出。


3
这是否写入某种文件。我无法在程序中使用它。我的第一行是您有,但到目前为止没有任何工作。
道格·豪夫

5
您如何查看日志?我正在使用的库会初始化Logger对象并使用该.fine()方法进行记录,但是我似乎无法显示消息...
Anubian Noob 2015年

7
自1998年以来,我一直在使用Java进行编程。我总是发现登录Java比需要的要麻烦得多。到目前为止,这是我所阅读的有关如何登录Java的最直接的解释。也要简洁。
Steve McLeod

30
有趣的是,没有人提到可以在其中找到日志文件的地方。
Ahmedov

4
如果您想知道日志在哪里,请确保已为Logger设置了处理程序。要将日志简单地输出到控制台,请使用新的ConsoleHandler,然后使用addHandler方法将此日志添加到记录器中。确保同时在记录器和处理程序上调用setLevel。
克雷格·布朗

67

应该这样声明记录器:

private final static Logger LOGGER = Logger.getLogger(MyClass.class.getName());

因此,如果您重构类名,它就会随之而来。

在此处撰写了有关Java logger的文章,并提供了示例


53

有许多示例,也有不同类型的日志记录。看一下java.util.logging包。

示例代码:

import java.util.logging.Logger;

public class Main {

  private static Logger LOGGER = Logger.getLogger("InfoLogging");

  public static void main(String[] args) {
    LOGGER.info("Logging an INFO-level message");
  }
}

无需对类名进行硬编码:

import java.util.logging.Logger;

public class Main {
  private static final Logger LOGGER = Logger.getLogger(
    Thread.currentThread().getStackTrace()[0].getClassName() );

  public static void main(String[] args) {
    LOGGER.info("Logging an INFO-level message");
  }
}

15
为什么不将日志名称设置为Main.class.getSimpleName()?这种重构工具可以在需要时适当地对其进行更改,但是它不如第二种解决方案那么笨拙。
Pijusn

3
为记录器名称执行stacktrace是hack,缓慢且不合常规的。它还会中断,并为您提供AOP代理或其他字节编码异常的怪异名称。
亚当·根特

9
-1用于stacktrace业务。它很慢,有可能阻止编译器优化。
phooji

4
初始化记录器时,为什么“慢度”根本不重要?提及缓慢是大多数人所说的过早优化(是的,代码的确看起来有些骇人听闻)。
mikkom 2014年

3
@AndrewMcKinlay在什么情况下会破坏任何东西?如果应该将logger标记与类名相同,那么这样做似乎是完全可以的。重构工具将自动对其重命名,如果它是一个硬编码的字符串,则重构工具可能会跳过它或说“您是否也想对其重命名?”。
Pijusn 2014年

23

与Apache Commons Logging(ACL)相比,SLF4J是更好的日志记录外观。它与其他日志记录框架建立了桥梁,可以通过SLF4J直接调用ACL,Log4J或Java Util日志记录,因此您可以根据需要将所有输出定向到一个日志文件,而只需一个日志配置文件。为什么您的应用程序将使用多个日志记录框架?因为您使用的第三方库(尤其是较旧的第三方库)可能会这样做。

SLF4J支持各种日志记录实现。它可以将所有内容输出到标准输出,使用Log4J或Logback(建议在Log4J上使用)。

http://www.slf4j.org/

http://logback.qos.ch/



0

我建议您使用Apache的commons日志记录实用程序。它具有高度的可扩展性,并为不同的记录器支持单独的日志文件。看这里


11
好建议!不过,请尝试回答他们的要求,否则请发表评论;)
Ordiel 2014年
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.