使用 java.util.logging 的好例子 [关闭]

Posted

技术标签:

【中文标题】使用 java.util.logging 的好例子 [关闭]【英文标题】:Good examples using java.util.logging [closed] 【发布时间】:2011-08-22 11:24:09 【问题描述】:

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

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

【问题讨论】:

你可以从这里开始:slf4j.org/manual.html 我建议您使用 Apache 的公共日志记录实用程序。它具有高度可扩展性,并支持不同记录器的单独日志文件。 See here. SLF4J 是比 Apache Commons Logging (ACL) 更好的日志记录外观。它具有与其他日志框架的桥梁,直接调用 ACL、Log4J 或 Java Util Logging 通过 SLF4J,因此您可以根据需要将所有输出定向到一个日志文件,只需一个日志配置文件。为什么您的应用程序会使用多个日志框架?因为您使用的第三方库,尤其是较旧的库,可能会这样做。 SLF4J 支持各种日志记录实现。它可以将所有内容输出到标准输出,使用 Log4J 或 Logback(推荐使用 Log4J)。 slf4j.orglogback.qos.c 我个人会使用minlog。这非常简单,因为日志记录类只有几百行代码。 【参考方案1】:

有很多例子,也有不同类型的日志记录。看看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");
  

无需对class name 进行硬编码:

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");
  

【讨论】:

为什么不将日志名称设置为Main.class.getSimpleName()?这样,重构工具会在需要时对其进行适当的更改,但它不像您的第二个解决方案那样笨拙。 为一个记录器名称做一个堆栈跟踪是 hack、缓慢和非正统的。它还会破坏并为 AOP 代理或其他非凡的字节编码提供奇怪的名称。 -1 用于堆栈跟踪业务。它很慢,可能会阻止编译器优化。 为什么初始化记录器时“慢”会很重要?提到缓慢是大多数人所说的过早优化(是的,代码看起来确实有点骇人听闻)。 @AndrewMcKinlay 在什么情况下它会破坏任何东西?如果 logger 标记应该与类名相同,那么这样做似乎很好。重构工具会自动重命名它,而如果它是一个硬编码的字符串,重构工具可能会跳过它或者说“你也想重命名它吗?”。【参考方案2】:

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 必须跟上这些垃圾。上面的Object[] 很便宜,通常在堆栈分配上。


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

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

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

【讨论】:

这是否写入某种文件。我还不能让它在我的程序中工作。我有你的初始行,但到目前为止没有任何工作。 您如何查看日志?我正在使用的库初始化 Logger 对象并使用.fine() 方法进行记录,但我似乎无法让消息显示... 自 1998 年以来我一直在使用 Java 进行编程。我一直发现使用 Java 登录比实际需要的更令人头疼。这是迄今为止我读过的关于如何登录 Java 的最直接的解释。也很简洁。 有趣的是没有人提到,在哪里可以找到日志文件。 如果您想知道日志的去向,请确保您已为 Logger 设置了处理程序。要简单地将日志输出到控制台,请使用新的 ConsoleHandler,然后使用 addHandler 方法将其添加到您的记录器中。确保在记录器和处理程序上都调用 setLevel。【参考方案3】:

应该像这样声明记录器:

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

所以如果你重构你的类名,它会遵循。

我用examples here写了一篇关于java logger的文章。

【讨论】:

以上是关于使用 java.util.logging 的好例子 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

Undertow java.util.logging:如何使用 java util logging 在运行时更改 undertow 服务器的日志记录级别

Java日志介绍-java.util.logging.Logger

java.util.logging.Logger使用详解 (转)

使用 java.util.logging 处理程序记录到 syslog 的最现代方式是啥?

如何为 java.util.logging.FileHandler 使用 try-with-resources?

java.util.logging.Logger 使用中关于时间格式的问题