Java日志指南
作者:网络转载 发布时间:[ 2015/7/20 10:19:19 ] 推荐标签:测试开发技术 编程语言
ConsoleAppender
ConsoleAppender是常用的Appenders之一,它只是将日志消息显示到控制台上。许多日志框架都将其作为默认的Appender,并且在基本的配置中进行预配置。例如,在Log4j中ConsoleAppender的配置参数如下所示。

一个完整的Log4j2的配置文件如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp">
<Appenders>
<Console name="MyAppender" target="SYSTEM_OUT">
<PatternLayout pattern="%m%n"/>
</Console>
</Appenders>
<Loggers>
<Root level="error">
<AppenderRef ref="MyAppender"/>
</Root>
</Loggers>
</Configuration>
这个配置文件创建了一个名为MyAppender的ConsoleAppender,它使用PatternLayout来对日志事件进行格式化,然后再将其输出到System.out。<Loggers>元素对定义在程序代码中的Loggers进行了配置。在这里,我们只配置了一个LoggerConfig,即名为Root的Logger,它会接收哪些日志级别在ERROR以上的日志消息。如果我们使用logger.error()来记录一个消息,那么它会出现在控制台上,像这样:
An unexpected error occurred.
你也可以使用Logback实现完全一样的效果:
<configuration>
<appender name="MyAppender" class="ch.qos.Logback.core.ConsoleAppender">
<encoder>
<pattern>%m%n</pattern>
</encoder>
</appender>
<root level="error">
<appender-ref ref="MyAppender" />
</root>
</configuration>
FileAppenders
FileAppenders将日志记录写入到文件中,它负责打开、关闭文件,向文件中追加日志记录,并对文件进行加锁,以免数据被破坏或者覆盖。
在Log4j中,如果想创建一个FileAppender,需要指定目标文件的名字,写入方式是追加还是覆盖,以及是否需要在写入日志时对文件进行加锁:
...
<Appenders>
<File name="MyFileAppender" fileName="myLog.log" append="true" locking="true">
<PatternLayout pattern="%m%n"/>
</File>
</Appenders>
...
这样我们创建了一个名为MyFileAppender的FileAppender,并且在向文件中追加日志时会对文件进行加锁操作。
如果使用Logback,你可以同时启用prudent模式来保证文件的完整性。虽然Prudent模式增加了写入文件所花费的时间,但它可以保证在多个FileAppender甚至多个Java程序向同一个文件写入日志时,文件的完整性。
...
<appender name="FileAppender" class="ch.qos.Logback.core.FileAppender">
<file>myLog.log</file>
<append>true</append>
<prudent>true</prudent>
<encoder>
<pattern>%m%n</pattern>
</encoder>
</appender>
...
SyslogAppender
SyslogAppenders将日志记录发送给本地或者远程系统的日志服务。syslog是一个接收日志事件服务,这些日志事件来自操作系统、进程、其它服务或者其它设备。事件的范围可以从诊断信息到用户登录硬件失败等。syslog的事件按照设备进行分类,它指定了正在记录的事件的类型。例如,auth facility表明这个事件是和安全以及认证有关。
Log4j和Logback都内置支持SyslogAppenders。在Log4j中,我们创建SyslogAppender时,需要指定syslog服务监听的主机号、端口号以及协议。下面的示例演示了如何设定装置:
...
<Appenders>
<Syslog name="SyslogAppender" host="localhost" port="514" protocol="UDP" facility="Auth" />
</Appenders>
...
在Logback中,我们可以实现同样的效果:
...
<appender name="SyslogAppender" class="ch.qos.Logback.classic.net.SyslogAppender">
<syslogHost>localhost</syslogHost>
<port>514</port>
<facility>Auth</facility>
</appender>
...
其它Appender
我们已经介绍了一些经常用到的Appenders,还有很多其它Appender。它们添加了新功能或者在其它的一些Appender基础上实现了新功能。例如,Log4j中的RollingFileAppender扩展了FileAppender,它可以在满足特定条件时自动创建新的日志文件;SMTPAppender会将日志内容以邮件的形式发送出去;FailoverAppender会在处理日志的过程中,如果一个或者多个Appender失败,自动切换到其他Appender上。
如果想了解更多关于其他Appender的信息,可以查看Log4j Appender参考以及Logback Appender参考。
Layouts
Layouts将日志记录的内容从一种数据形式转换成另外一种。日志框架为纯文本、HTML、syslog、XML、JSON、序列化以及其它日志提供了Layouts。
请注意:在java.util.logging中Layouts也被称为Formatters。
例如,java.util.logging提供了两种Layouts:SimpleFormatter和XMLFormatter。默认情况下,ConsoleHandlers使用SimpleFormatter,它输出的纯文本日志记录像这样:
Mar 31, 2015 10:47:51 AM MyClass main
SEVERE: An exception occurred.
而默认情况下,FileHandlers使用XMLFormatter,它的输出像这样:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE log SYSTEM "logger.dtd">
<log>
<record>
<date>2015-03-31T10:47:51</date>
<millis>1427903275893</millis>
<sequence>0</sequence>
<logger>MyClass</logger>
<level>SEVERE</level>
<class>MyClass</class>
<method>main</method>
<thread>1</thread>
<message>An exception occurred.</message>
</record>
</log>
配置Layout
我们通常使用配置文件对Layouts进行配置。从Java 7开始,我们也可以使用system property来配置SimpleFormatter。
例如,在Log4j和Logback中常用的Layouts是PatternLayout。它可以让你决定日志事件中的哪些部分需要输出,这是通过转换模式(Conversion Pattern)完成的,转换模式在每一条日志事件的数据中扮演了“占位符”的角色。例如,Log4j默认的PatternLayout使用了如下转换模式:
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
%d{HH:mm:ss.SSS} 将日期转换成时、分、秒和毫秒的形式,%level显示日志事件的严重程度,%C显示生成日志事件的类的名字,%t显示Logger的当前线程,%m显示时间的消息,后,%n为下一个日志事件进行了换行。
改变Layouts
如果在java.util.logging中使用一个不同的Layout,需要将Appender的formatter属性设置成你想要的Layout。在代码中,你可以创建一个新的Handler,调用setFormatter方法,然后通过logger.AddHandler()方法将Handler放到Logger上面。下面的示例创建了一个ConsoleAppender,它使用XMLFormatter来对日志进行格式化,而不是使用默认的SimpleFormatter:
Handler ch = new ConsoleHandler();
ch.setFormatter(new XMLFormatter());
logger.addHandler(ch);
这样Logger会将下面的信息输出到控制台上:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE log SYSTEM "logger.dtd">
<log>
<record>
<date>2015-03-31T10:47:51</date>
<millis>1427813271000</millis>
<sequence>0</sequence>
<logger>MyClass</logger>
<level>SEVERE</level>
<class>MyClass</class>
<method>main</method>
<thread>1</thread>
<message>An exception occurred.</message>
</record>
如果想了解更多信息,你可以查看Log4j Layouts参考以及Logback Layouts参考。
使用自定义Layouts
自定义Layouts可以让你指定Appender应该如何输出日志记录。从Java SE 7开始,尽管你可以调整SimpleLogger的输出,但有一个限制,即只能够调整简单的纯文本消息。对于更高级的格式,例如HTML或者JSON,你需要一个自定义Layout或者一个单独的框架。
如果想了解更多使用java.util.logging创建自定义Layouts的信息,你可以查看Jakob Jenkov的Java日志指南中的Java Logging: Formatters章节。
日志级别
日志级别提供了一种方式,我们可以用它来根据严重程度对日志进行分类和识别。java.util.logging 按照严重程度从重到轻,提供了以下级别:
SEVERE(高级别)
WARNING
INFO
CONFIG
FINE
FINER
FINEST(低级别)
另外, 还有两个日志级别:ALL和OFF。ALL会让Logger输出所有消息,而OFF则会关闭日志功能。
设置日志级别
在设定日志级别后,Logger会自动忽略那些低于设定级别的日志消息。例如,下面的语句会让Logger忽略那些低于WARNING级别的日志消息:
logger.setLevel(Level.WARNING);
然后,Logger会记录任何WARNING或者更高级别的日志消息。我们也可以在配置文件中设置Logger的日志级别:
...
<Loggers>
<Logger name="MyLogger" level="warning">
...

sales@spasvo.com