浅析log4j(日常使用)

下面从三个方面来简单介绍log4j的使用。
第一部分介绍log4j的背景
第二部分介绍Log4j的配置文件log4j.xml
第三部分介绍log4j在代码中的使用

一、背景

Log4j 是Apache的一个开放源代码项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件、甚至是套接口服务器、NT的事件记录器、UNIX Syslog守护进程等;我们也可以控制每一条日志的输出格式;通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。最令人感兴趣的就是,这些可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码。



附上demo:
[img]http://dl.iteye.com/upload/attachment/0066/2772/90a02ae6-7e8b-373a-b52c-8a559dd9d8d7.png[/img]


二、log4j.xml


<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE log4j:configuration SYSTEM "dtd/log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">

<appender name="stdout" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss} %5p %c:%m%n" /><!-- 5代表五个空格,而且一定要在%后 -->
</layout>
</appender>

<appender name="testLog" class="org.apache.log4j.DailyRollingFileAppender"><!-- 每日产生一个文件 -->
<param name="File" value="test.log" /><!-- 项目根目录 -->
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss} %5p %l:%m%n" />
</layout>
</appender>
<!--
additivity它是 Logger是否继承 rootLogger 的 输出源(appender) 的标志位。具体说,默认情况下子Logger会继承父Logger的appender,也就是说子Logger会在父Logger的appender里输出。
若是additivity设为false,则子Logger只会在自己的appender里输出,而不会在父Logger的appender里输出。
这里的父logger都是root,即控制台输出
-->
<logger name="test_log" additivity="true"><!-- 别名级别 -->
<level value="info" /><!-- 输出级别(开关) -->
<appender-ref ref="testLog" /><!-- 引用输出配置 -->
</logger>
<logger name="start.StartServer" additivity="false"><!-- 类级别 -->
<level value="info" />
<appender-ref ref="testLog" />
</logger>
<logger name="start" additivity="false"><!-- 包级别 -->
<level value="info" />
<appender-ref ref="testLog" />
</logger>
<root>
<level value="info" />
<appender-ref ref="stdout" />
</root>
</log4j:configuration>


上面是我的demo中的配置文件,只是简单的使用了几个常用的功能(太多懒得写 :wink: ),下面详细介绍:

配置最多的大概就是appender和logger了,appender描述了日志要输出的明细,其中包括日志类型、日志目的地、日志格式等;而logger主要定义了日志命名、日志输出级别,引用的appender等。

1、appender:

name 定义了此appender的别名;
class定义了日志的类型,有以下几个类型:
org.apache.log4j.ConsoleAppender(控制台),
org.apache.log4j.FileAppender(文件),
org.apache.log4j.DailyRollingFileAppender(每天产生一个日志文件),
org.apache.log4j.RollingFileAppender(文件大小到达指定尺寸的时候产生一个新的文件)
org.apache.log4j.WriterAppender(将日志信息以流格式发送到任意指定的地方)

layout 定义了日志的输出格式,包括:
org.apache.log4j.HTMLLayout(以HTML表格形式布局),
   org.apache.log4j.PatternLayout(可以灵活地指定布局模式),
   org.apache.log4j.SimpleLayout(包含日志信息的级别和信息字符串),
   org.apache.log4j.TTCCLayout(包含日志产生的时间、线程、类别等等信息)

ConversionPattern 参数定义了详细的日志格式:Log4J采用类似C语言中的printf函数的打印格式格式化日志信息,打印参数如下:
%m 输出代码中指定的消息
   %p 输出优先级,即DEBUG,INFO,WARN,ERROR,FATAL
   %r 输出自应用启动到输出该log信息耗费的毫秒数
   %c 输出所属的类目,通常就是所在类的全名
   %t 输出产生该日志事件的线程名
   %n 输出一个回车换行符,Windows平台为“rn”,Unix平台为“n”
   %d 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:
%d{yyy MMM dd HH:mm:ss,SSS},输出类似:2002年10月18日 22:10:28,921
   %l 输出日志事件的发生位置,包括类目名、发生的线程,以及在代码中的行数。举例:Testlog4.main(TestLog4.java:10)

上面例子中的5代表五个空格,而且一定要在%后 。

file 参数定义了输出的目的地目录(除了控制台),可以使用绝对路径和相对路径,一般使用相对路径,如例子中所示将会在项目根目录中产生日志文件;绝对路径如:E:\\log\\log.txt。


2、logger

logger相对来说配置比较简单,常用的有四个属性:
name 定义了logger的命名级别,这个会在第三部分即代码中详细讲到。

additivity 用于说明是否继承父logger的输出(默认为true),例子中的父logger都是rootLogger,即控制台输出;如果为true,即在日志输出到文件的同时亦输出到控制台(所以有时我们看到控制台有两次输出,其实有一次是本logger,另外一次是父logger),否则不输出。

level 定义了此logger的日志输出级别,从大到小包括:OFF、FATAL、ERROR、WARN、INFO、DEBUG、ALL。例如设置了all,则all前面的都会输出,如果设置了off,则只有off可以输出。通常在代码编写阶段,使用debug用作测试,待项目正式使用时设置为debug以上,这样就不用把以前写的debug语句都一句一句地删掉,省了不少时间。当然,对于小程序完全可以用System.out.println()解决~

最后一个appender-ref,从字面意思就可以看出,这个就是引用上面所定义的appender了,这里就不多说了。

3、root
root定义了根logger,也是默认输出,是其它logger的父logger。


三、代码应用

1、加载
默认下,就算不手动加载,log4j也会从根目录下开始循环目录寻找log4j.xml配置文件,如果你放在根目录下,可以不用手动加载,但当你有特别的需求时,手动加载配置文件会节省不少时间,下面是加载代码:
DOMConfigurator.configure(StartServer.class.getClassLoader()
.getResource("log4j.xml"));

上面示例中加载的是xml格式的配置文件,当然你也可以使用property文件来加载,但个人比较喜欢xml格式,简单清晰~,附上其他加载方式:
BasicConfigurator.configure (): 自动快速地使用缺省Log4j环境。
   PropertyConfigurator.configure ( String configFilename) :读取使用Java的特性文件编写的配置文件(键值对文件)。
   DOMConfigurator.configure ( String filename ) :读取XML形式的配置文件。


2、使用方式

这部分的重点就是讲述上面第二部提到的logger的命名级别,分为三个级别:别名、类文件、包;
别名级别:
<logger name="test_log" additivity="true"><!-- 别名级别 -->

别名级别只需简单定义了名字,然后在代码中指定这个名字就可以使用了:
// 获取log
LogFactory.getLog("test_log").info("hello world");// 别名级别


类级别:
<logger name="start.StartServer" additivity="false"><!-- 类级别 -->

定义要使用这个logger的类的全限定名(不用.class) ,只有使用这个类名才能使用这个logger(不限制在此类,即在其它类中也可以向下面这样使用):
LogFactory.getLog(StartServer.class).info("second world");// 类级别


包级别:
如果每次使用都要记住使用哪个logger的名字有时会变得很繁琐,所以log4j提供了包级别的命名方式:
<logger name="start" additivity="false"><!-- 包级别 -->

这样,只要在start包下的类都可以使用本身作为参数来使用logger,而无需记住其它logger名字:
package start;

import org.apache.commons.logging.LogFactory;

/**
* @author minghua.l
* @date 2012-4-9 下午07:14:30
*/
public class ServerTo {

/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
LogFactory.getLog(ServerTo.class).info("last world");// 包级别

}

}



有时为了使用方便,也许需要额外写一个logUtils来方便使用日志,这就要看具体的项目需求了,这里提供一个简单的例子:


package util;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
* @author minghua.l
* @date 2012-3-31 下午04:44:31
*/
public class LogUtils {

private static Log testLog = LogFactory.getLog("test_log");

public static Log getTestLog() {
return testLog;
}
public static void testLogOnInfo(String content) {
testLog.info(content);
}

public static void testLogOnDebug(String content) {
testLog.debug(content);
}
}


最后,附上一个使用log4j的小技巧:
// 先判断再记录可有效提高性能,当这个记录器的级别》info时,就不用拼接下面两个字符串了(还要生成对象),
//否则是先拼接再判断的(例如info()方法内部还会进行infoEnabled判断,这是传进来的已经是准备好了的对象了
// 当拼接中可能要耗时大时(如调用其它耗时方法),会降低性能
if(LogFactory.getLog("test_log").isInfoEnabled()) {
LogFactory.getLog("test_log").info("enter infoenabled" + " ok");
}


参考资料:
http://baike.baidu.com/view/25347.htm
http://www.iteye.com/topic/378077
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值