我曾经提到过一个叫做log4j的Java logging API,在那篇文章里,我指出,如果你要使用Java 2 SDK 1.4版本,Java logging将包括在标准配置中。那时,我感到虽然在标准JDK中加入了logging API,但最好还是继续使用log4j,因为他更加成熟并且被应用的更广泛。虽然仍然使用log4j,但我认为对内建logging进行一些了解也不是什么坏事,看看他是如何实现的,找到其与log4j数据包相比的优点。

如果你对log4j数据包还不熟悉,你可以先查阅上一篇文章,在我写这篇文章之时,log4j的最新版本是1.2.4,其中包括两项改动,可使其与JDK logging API的兼容性更强,这些改动涉及了类别类转移到记录器类和优先类转移到级别类。类别类和优先类仍然会得到支持,因此你从旧版本升级时现有的log4j代码仍然可用。现在,让我们来关注在应用软件中加入logging的问题。

在代码中加入记录器
代码与logging API作连接时使用的主要对象就是记录器类,记录器类包含恢复记录器的实例和记录不同级别的信息所必需的方法。你可以使用与下面类似的代码来得到一个记录器的实例:

private static final Logger logger = Logger.getLogger(JavaLoggingExample.class.getName());

这段代码使用当前类名来恢复记录器的实例,代码中,类名为JavaLoggingExample,getLogger()方法允许一个String argument来指定记录器类名,logging API使用一个等级式的名称空间以使设置可以被较低的级别所继承。例如,如果类的全名为com.versatilesolutions.builder.JavaLoggingExample,则记录器的设置可以从com.versatilesolutions来继承,因为它是类中的父级。所有记录器都从LogManager做继承,因此新创建的记录器将拥有在LogManager中所声明的设置。

记录内容
记录是建立在由整数所代表的级别之上的,在java.util.logging数据包中的级别类包含预置级别的区域。级别包括SEVERE, WARNING, INFO, CONFIG, FINE, FINER, and FINEST。在一个级别中记录一条信息,你可以根据所需要的级别和信息调用记录方法:

logger.log(Level.SEVERE, “This is a severe level message!”);

这里记录了一个SEVERE级别信息。有几种记录方法可以通过直接记录到一个特定级别上从而节省时间:

logger.severe(“This is another severe level message!”);

当你运行这些记录方法时,输出是这样:

Jun 25, 2002 4:40:34 PM JavaLoggingExample <init>
SEVERE: This is a severe level message!

第一行在日期和时间之后是类的名称和logging API对于实现调用程序的最佳推测。这里<init>代表类的建造者,logging API不能保证追踪信息的准确性,这是由于准确性会被许多种优化运行环境所影响。

配置logging
你可以使用处理器和格式化工具来定制logging。处理器可以让你控制记录声明的目的地。格式化工具,就想你想象的那样,控制着实际的输出。API中包含这些处理器:ConsoleHandler, SocketHandler, 和 FileHandler。如果你浏览API javadocs,你会看到列出的其他处理器,但是他们只支持其他处理器所使用的类。在标准API中只包括两个格式化工具—SimpleFormatter and XMLFormatter.

整个logging配置通过一个从JRE目录中的lib目录中读取得属性文件来完成。文件名为logging.properties。你也可以通过在记录器的实例中声明并加入一个处理器和/或格式化工具来动态地调整logging的属性。我创建过一个为缺省控制处理器建立文件处理器的小型测试类(列表A)。在缺省情况下,这个文件处理器使用XMLF格式化工具。你可以在列表B中看到文件(输出)。

你可以通过使用Java系统属性(java.util.logging配置类或java.util.logging配置文件)指定一个替换的属性文件或类来调整logging属性。配置类将有例示并负责进行配置。

标准API还是log4j ?
在对标准的logging API了解之后,我的观点是如果你需要一个强力的logging机制就应坚持使用log4j数据包。Logging API对于使用是足够的,但他缺少了许多log4j所具有的功能。例如,log4j具有一个文件轮转类,它可以在日期的基础上进行轮转(在logging API中你可以扩展FileHandler类,但是为什么要给自己增加工作量呢?)

log4j的另一个优势是你可以通过利用一个指定的属性文件加载配置对象来轻松地进行配置。Logging API将指定文件或类作系统属性的方法似乎难于管理。在我的项目中,我比较喜欢简单的起始形式。Log4j还具有更加强力的格式化系统,它可以使你在记录输出实现简单的模式而不会增加类导致格式化工具的扩展。众多的附加程序和处理器使得log4j数据包成为一个绝佳的选择,所有你所需要的都可能加以实现。

有许多方式可以使logging API成为一个强力的解决方案,但我认为log4j提供了一个更佳的解决方案。然而,如果你只是需要一些简单的控制或文件记录,logging API已经内建在JDK之中可以使用。