您的位置:首页 > 编程语言 > Java开发

Commons-logging + Log4j 入门指南

2010-05-12 09:38 106 查看
为什么要用日志(

Log




?



这个……就不必说了吧。

为什么不用

System.out.println()?



功能太弱;不易于控制。如果暂时不想输出了怎么
办?如果想输出到文件怎么办?如果想部分输出怎么办?……

为什么同时使用

commons-logging




Log4j?


为什么不仅使用其中之一?


Commons-loggin

的目的是为“所有的
Java

日志实现”提供一个统一的接口,它自身的日志功能平常
弱(只有一个简单的
SimpleLog?

),
所以一般不会单独使用它。

Log4j

的功能非常全面强大,是目前的首选。我发现几乎所有的
Java

开源项目都会用到
Log4j

,但我同时发现,所有用到
Log4j

的项目一般也同时会用到
commons-loggin

。我想,大家都不希望自己的项
目与
Log4j

绑定的
太紧密吧。另外一个我能想到的“同时使用
commons-logging


Log4j

”的原因是,简化使用和配置。

强调一点,“同时使用
commons-logging


Log4j

”,与“单独使用
Log4j

”相比,并不会带来更大的学习、配置和维护成本,
反而更加简化了我们的工作。我想这也是为什么“所有用到
Log4j


项目一般也同时会用到
commons-loggin


的原因之一吧。

Commons-logging


能帮我们做什么?


l )

提供一个统一的日志接口,简单了操作,同时避免项目与某个日志实现系统紧密
a

耦合

2)

很贴心的帮我们自动选择适当的日志实现系统(这一点非常好!)

3)

它甚至不需要配置

这里看一下它怎么“‘很贴心的’帮我们
‘自动选择’‘适当的’日志实现系统”:


1)

首先在
classpath

下寻找自己的配置文件
commons-logging.properties

,如果
找到,则使用其中定义的
Log


现类;

2)

如果找不到
commons-logging.properties

文件,则在查找是否已定义系统环境变量
org.apache.commons.logging.Log


找到则使用其定义的
Log


现类;

3)

否则,查看
classpath

中是否有
Log4j

的包,如果发现,则自动使用
Log4j

作为日志实现类;

4)

否则,使用
JDK

自身的日志实现类(
JDK1.4

以后才有日志实现类);

5)

否则,使用
commons-logging

自己提供的一个简单的日志实现类
SimpleLog



(以上顺序不保证完全准确,请参考官方文档)

可见,
commons-logging

总是能找到一个日志实现类,并
且尽可能找到一个“最合适”的日志实现类。我说它“很贴心”实际上是因为:
1

、可以不需要配置文件;
2

、自动判断有没有
Log4j

包,有则自动使用之;
3

、最悲观的情况下也总能保证提供一个日志实现(
SimpleLog

)。

可以看到,
commons-logging

对编程者和
Log4j

都非常友好。

为了简化配置
commons-logging

,一般不使用
commons-logging

的配置文件,也不设置与
commons-logging

相关的系统环境变量,而只需

Log4j


Jar

包放置到
classpash

中就可以了。这样就很简单地完成了
commons-logging


Log4j

的融合。如果不想用
Log4j

了怎么办?只需将
classpath

中的
Log4j


Jar

包删除即可。

就这么简单!

代码应该怎么写?

我们在需要输出日志信息的“每一人”类中做如下
的三个工作:

1

、导入所有需的
commongs-logging

类:

import org.apache.commons.logging.Log;

import org.apache.commons.logging.LogFactory;

如果愿意简化的话,还可以两行合为一行:

import org.apache.commons.logging.*;

2

、在自己的类中定义一个
org.apache.commons.logging.Log

类的私有静态类成员:

private static Log log = LogFactory.getLog(YouClassName.class);

注意这里定义的是
static

成员,以避免产生多个实例。

LogFactory.getLog()

方法的参数使用的是当前类的
class

,这是目前被普通认为的最好的方式。为什么不写作
LogFactory.getLog(this.getClass())


因为
static

类成
员访问不到
this


针!

3

、使用
org.apache.commons.logging.Log


的成员方法输出日志信息:

log.debug("111");

log.info("222");

log.warn("333");

log.error("444");

log.fatal("555");

这里的
log

,就是上面第二步中定义的类成员变量,其类型是
org.apache.commons.logging.Log


通过该类的成员方法,我们就可以将不同性质的日志信息输出到目的地(目的地是哪里?视配置可定,可能是
stdout

,也可能是文件,还可能是发送到邮件,甚至发送短
信到手机……详见下文对
log4j.properties


介绍):

l debug()

输出“调试”级别的日志信息;

l info()

输出“信息”级别的日志信息;

l warn()

输出“警告”级别的日志信息;

l error()

输出“错误”级别的日志信息;

l fatal()

输出“致命错误”级别的日志信息;

根据不同的性质,日志信息通常被分成不同的级
别,从低到高依次是:“调试(
DEBUG

)”
“信息(
INFO

)”
“警告(
WARN

)”
“错误(
ERROR

)”
“致命错误(
FATAL

)”。
为什么要把日志信息分成不同的级别呢?这实际上是方便我们更好的控制它。比如,通过
Log4j

的配置文件,我们可以设置“输出‘调试’及以上级别的日志信息”(即“调试”
“信息”“警告”“错误”“致命错误”),这对项目开发人员可能是有用的;我们还可以设置“输出“警告”及以上级别的日志信息”(即“警告”“错误”“致
命错误”),这对项目最终用户可能是有用的。

仅从字面上理解,也可以大致得出结论:最常用的应该是
debug()


info()

;而
warn()


error()


fatal()

仅在相应事件发生后才使用。

从上面三个步骤可以看出,使用
commons-logging

的日志接口非常的简单,不需
要记忆太多东西:仅仅用到了两个类
Log,
LogFactory

,并且两个类的方法都非常少(后者只用到一个方法,前者经常用到的也只是上面第三步中列出
的几个),同时参数又非常简单。

上面所介绍的方法是目前被普通应用的,可以说是
被标准化了的方法,几乎所有的人都是这么用。如果不信,或想确认一下,就去下载几个知名的
Java

开源项目源代码看一下吧。

下面给出一个完整的
Java

类的代码:

package liigo.testlog;

import org.apache.commons.logging.Log;

import org.apache.commons.logging.LogFactory;

public class TestLog

{

private static Log log = LogFactory.getLog(TestLog.class);

public void test()

{

log.debug("111");

log.info("222");

log.warn("333");

log.error("444");

log.fatal("555");

}

public static void main(String[] args)

{

TestLog testLog = new TestLog();

testLog.test();

}

}

只要保证
commons-logging


jar

包在
classpath

中,上述代码肯定可以很顺利的编译通过。那
它的执行结果是怎么样的呢?恐怕会有很大的不同,请继续往下看。

Log4j

在哪里呢?它发挥作用了吗?

应该注意到,我们上面给出的源代码,完全没有涉
及到
Log4j

——这
正是我们所希望的,这也正是
commons-logging


要达到的目标之一。

可是,怎么才能让
Log4j

发挥它的作用呢?答案很简单,只需满足“
classpath

中有
Log4j


jar

包”。前面已经说过了,
commons-logging

会自动发现并应用
Log4j

。所以只要它存在,它就发挥作用。(它不存在呢?
自然就不发挥作用,
commons-logging


另行选择其它的日志实现类。)

注意:配置文件
log4j.properties


Log4j

来说是必须的。如果
classpath

中没有该配置文件,或者配置不对,将会引
发运行时异常。

这样,要正确地应用
Log4j

输出日志信息,
log4j.properties

的作用就很重要了。好在该
文件有通用的模板,复制一份(稍加修改)就可以使用。几乎每一个
Java


目目录内都会有一个
log4j.properties


件,可下载几个
Java


源项目源代码查看。本文最后也附一个模板性质的
log4j.properties


件,直接复制过去就可以用,或者根据自己的需要稍加修改变.下面将会给出我用的
log4j.properties

文件:

# Set root category priority to DEBUG and its
only appender to A1.

#############################

#set
output method

#output to System.out

log4j.rootCategory=DEBUG,
A1

#output to following file

log4j.rootLogger=DEBUG, R

log4j.logger.com.chinacti.km=DEBUG

log4j.logger.org.hibernate=INFO

#log4j.logger.com.chinacti.mobile.knowbase=DEBUG

#log4j.logger.com.chinacti.kb=DEBUG

#log4j.logger.com.chinacti.mobile.other=DEBUG

############################

# A1 is set to be a FileAppender which
outputs to System.out.

#log4j.appender.A1=org.apache.log4j.ConsoleAppender

log4j.appender.A1=org.apache.log4j.FileAppender

log4j.appender.A1.File=C:/jakarta-tomcat-4.1.24-LE-jdk14/logs/framework.log

# A1 uses PatternLayout.

log4j.appender.A1.layout=org.apache.log4j.PatternLayout

log4j.appender.A1.layout.ConversionPattern=%d
[%t] %-5p %c - %m%n

#log4j.appender.A1.layout.ConversionPattern=%5p
[%d{HH:mm:ss,SSS}] %c{4} %x - %m%n

log4j.appender.R=org.apache.log4j.RollingFileAppender

################################

#set
log output file name and it`s directory

#For Windows

log4j.appender.R.File=C:/Program
Files/tomcat5/logs/km.log

#For Linux

#log4j.appender.R.File=/usr/local/tomcat/logs/ioffice.log

###############################

log4j.appender.R.MaxFileSize=10000KB

#
Keep one backup file

log4j.appender.R.MaxBackupIndex=10

log4j.appender.R.layout=org.apache.log4j.PatternLayout

#log4j.appender.R.layout.ConversionPattern=%5p
[%d{yyyy-MM-dd HH:mm:ss,SSS}] %c{4} %x - %m%n

log4j.appender.R.layout.ConversionPattern=%d
[%t] %-5p %c - %m%n
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  log4j import java jar output jdk