`

Commons-logging [ Log4j 用法]

    博客分类:
  • Java
阅读更多
一 :为什么同时使用commons-logging和Log4j?为什么不仅使用其中之一?

Commons-loggin的目的是为“所有的Java日志实现”提供一个统一的接口,它自身的日志功能平常弱(只有一个简单的SimpleLog?),所以一般不会单独使用它。Log4j的功能非常全面强大,是目前的首选。我发现几乎所有的Java开源项目都会用到Log4j,但我同时发现,所有用到Log4j的项目一般也同时会用到commons-loggin。我想,大家都不希望自己的项目与Log4j绑定的太紧密吧。另外一个我能想到的“同时使用commons-logging和Log4j”的原因是,简化使用和配置。

二 :Commons-logging能帮我们做什么?

提供一个统一的日志接口,简单了操作,同时避免项目与某个日志实现系统紧密a耦合很贴心的帮我们自动选择适当的日志实现系统(这一点非常好!)它甚至不需要配置

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

1)  首先在classpath下寻找自己的配置文件commons-logging.properties,如果找到,则使用其中定义的Log实现类;

2)  如果找不到commons-logging.properties文件,则在查找是否已定义系统环境变量org.apache.commons.logging.Log,找到则使用其定义的Log实现类;



建立一个叫 :CATALINA_OPTS 的环境变量
给他的值 : - Dorg.apache.commons.logging.Log = org.apache.commons.logging.impl.SimpleLog  - Dorg.apache.commons.logging.simplelog.defaultlog = warn

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的介绍):
 
debug() 输出“调试”级别的日志信息; info() 输出“信息”级别的日志信息; warn() 输出“警告”级别的日志信息; error() 输出“错误”级别的日志信息; 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文件适当作一些介绍。
      这里顺便提示一点:如果不用commons-logging,仅仅单独使用Log4j,操作上反而要稍微麻烦一些,因为Log4j需要多一点点的初始化代码(相比commons-logging而言):



1 import org.apache.log4j.Logger; 2 import org.apache.log4j.PropertyConfigurator; 3 public class TestLog4j { 4 static Logger logger = Logger.getLogger(TestLog4j. class ); // First step 5 public static void main(String args[]) { 6 PropertyConfigurator.configure( " log4j.properties " ); // Second step 7 logger.debug( " Here is some DEBUG " ); // Third step 8 logger.info( " Here is some INFO " ); 9 logger.warn( " Here is some WARN " ); 10 logger.error( " Here is some ERROR " ); 11 logger.fatal( " Here is some FATAL " ); 12 } 13 }

不过也就多出一行。但这至少说明,引用commons-logging并没有使问题复杂化,反而简单了一些。在这里1+1就小于2了。这也验证了前面的结论。

总结
将commons-logging和Log4j的jar包都放置到classpath下,同时也将Log4j的配置文件放到classpath中,两者就可以很好的合作。
采用Log4j配合commons-logging作为日志系统,是目前Java领域非常非常流行的模式,使用非常非常的普遍。两者的结合带来的结果就是:简单 + 强大。

commons-logging提供了简捷、统一的接口,不需要额外配置,简单;

Log4j功能非常全面、强大;

commons-logging仅仅对Log4j(当然还包括其它LOG实现)作了一层包装,具体的日志输出还是在内部转交给身后的Log4j来处理;而Log4j虽然做了所有的事情,却甘作绿叶,从不以真身示人。

两者堪称绝配。

对log4j.properties的一点介绍
下面对log4j.properties文件内容作一点点介绍,以后文所附log4j.properties文件为例:

除去以#开头的注释以及空行,第一行有用的内容是:

1  log4j.rootLogger  =  DEBUG, CONSOLE,A1
log4j.rootLogger是最最重要的一个属性了,它定义日志信息的“输出级别”和“输出目的地”。
关键看“=”后面的值,“DEBUG, CONSOLE,A1”这里我们要把它分成两部分:第一个逗号之前的是第一部分,指定“输出级别”;后面的是第二部分,指定“输出目的地”。可以同时指定多个“输出目的地”,以逗号隔开。
具体到上面这一行:它指定的“输出级别”是“DEBUG”;它指定的“输出目的地”是“CONSOLE”和“A1”。

注意:
      “输出级别”有可选的五个值,分别是DEBUG、INFO、WARN、ERROR、FATAL,它们是由Log4j系统定义的。

        “输出目的地”就是我们自己定义的了,就在log4j.properties的后面部分,此文件定义的“输出目的地”有CONSOLE、FILE、ROLLING_FILE、SOCKET、LF5_APPENDER、MAIL、DATABASE、A1、im。该文件之所以可作主模板,就是因为它比较全面地定义了各种常见的输出目的地(控制台、文件、电子邮件、数据库等)。

好,下面详细解释“log4j.rootLogger=DEBUG, CONSOLE,A1”这一行:

        指定“输出级别”是“DEBUG”,即,仅输出级别大于等于“调试(DEBUG)”的日志信息。如果此处指定的是“WARN”则仅调用warn()、error()、fatal()方法输出的日志信息才被输出到“输出目的地”,而调用debug()、info()方法输出的日志信息不被输出到“输出目的地”。明白了吗?Log4j就是以这种方式来过滤控制日志信息的输出与否,这也是对日志信息进行级别分类的目的。
        指定“输出目的地”是“CONSOLE”和“A1”,即,将指定的日志信息(根据日志级别已进行了过滤)同时输出到的“控制台”和“SampleMessages.log4j文件”。


为什么说“CONSOLE”表示将日志信息输出到“控制台”呢?那就要看一下后文的定义了:

# 应用于控制台

1 log4j.appender.CONSOLE = org.apache.log4j.ConsoleAppender
2 log4j.appender.Threshold = DEBUG
3 log4j.appender.CONSOLE.Target = System.out
4 log4j.appender.CONSOLE.layout = org.apache.log4j.PatternLayout
5 log4j.appender.CONSOLE.layout.ConversionPattern = [framework]  % d  -   % c  -%- 4r [ % t]  %- 5p  % c  % x  -   % m % n
6  #log4j.appender.CONSOLE.layout.ConversionPattern = [start] % d  {DATE} [DATE] % n % p[PRIORITY] % n % x[NDC] % n % t[THREAD] n % c[CATEGORY] % n % m[MESSAGE] % n % n
为什么说“A1”表示将日志信息输出到“SampleMessages.log4j文件”呢?还要看后文的定义:

1 log4j.appender.A1 = org.apache.log4j.DailyRollingFileAppender
2 log4j.appender.A1.File = SampleMessages.log4j
3 log4j.appender.A1.DatePattern = yyyyMMdd - HH ' .log4j '
4 log4j.appender.A1.layout = org.apache.log4j.xml.XMLLayout
注意:这里的定义没有指定输出文件的路径,它的路径实际上是 java.user.path的值。
您应该已经注意到,在定义“输出目的地”时,还可以指定日志格式、时间、布局等相关信息。略过。

好了,我可以根据需要,将这一行修改为:

1 log4j.rootLogger  =  ERROR, CONSOLE,FILE,MAIL
将“错误(ERROR)”及“致命错误(FATAL)”级别的日志信息同时输出到控制台、文件,并且发电子邮件向系统管理员报告。是不是很爽?(如果将“调试(DEBUG)”级别的日志信息邮件给管理员,恐怕迟早会把他/她的邮箱涨爆,哪怕用的是Gmail!再次理解了“将日志信息分为不同级别”的意图了吧?)

附:一个有用的log4j.properties文件模板


 
##Log4J的配置之简单使它遍及于越来越多的应用中了  

 

##Log4J配置文件实现了输出到控制台、文件、回滚文件、发送日志邮件、输出到数据库日志表、自定义标签等全套功能。择其一二使用就够用了。  



##此文件(log4j.properties)内容来自网络,非本文作者liigo原创。  

log4j.rootLogger = DEBUG, CONSOLE,A1  

log4j.addivity.org.apache = true    

 

# 应用于控制台   

log4j.appender.CONSOLE = org.apache.log4j.ConsoleAppender   

log4j.appender.Threshold = DEBUG   

log4j.appender.CONSOLE.Target = System.out   

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

log4j.appender.CONSOLE.layout.ConversionPattern = [framework]  % d  -   % c  -%- 4r [ % t]  %- 5p  % c  % x  -   % m % n   

#log4j.appender.CONSOLE.layout.ConversionPattern = [start] % d  {DATE} [DATE] % n % p[PRIORITY] % n % x[NDC] % n % t[THREAD] n % c[CATEGORY] % n % m[MESSAGE] % n % n   

 

#应用于文件  

log4j.appender.FILE = org.apache.log4j.FileAppender   

log4j.appender.FILE.File = file.log   

log4j.appender.FILE.Append = false    

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

log4j.appender.FILE.layout.ConversionPattern = [framework]  % d  -   % c  -%- 4r [ % t]  %- 5p  % c  % x  -   % m % n   

# Use  this  layout  for  LogFactor  5  analysis   

 

# 应用于文件回滚   

log4j.appender.ROLLING_FILE = org.apache.log4j.RollingFileAppender   

log4j.appender.ROLLING_FILE.Threshold = ERROR   

log4j.appender.ROLLING_FILE.File = rolling.log   

log4j.appender.ROLLING_FILE.Append = true    

log4j.appender.ROLLING_FILE.MaxFileSize = 10KB   

log4j.appender.ROLLING_FILE.MaxBackupIndex = 1    

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

log4j.appender.ROLLING_FILE.layout.ConversionPattern = [framework]  % d  -   % c  -%- 4r [ % t]  %- 5p  % c  % x  -   % m % n   

 

#应用于socket   

log4j.appender.SOCKET = org.apache.log4j.RollingFileAppender   

log4j.appender.SOCKET.RemoteHost = localhost   

log4j.appender.SOCKET.Port = 5001    

log4j.appender.SOCKET.LocationInfo = true    

# Set up  for  Log Facter  5    

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

log4j.appender.SOCET.layout.ConversionPattern = [start] % d  {DATE} [DATE] % n % p[PRIORITY] % n % x[NDC] % n % t[THREAD] % n % c[CATEGORY] % n % m[MESSAGE] % n % n   

 

# Log Factor  5  Appender   

log4j.appender.LF5_APPENDER = org.apache.log4j.lf5.LF5Appender   

log4j.appender.LF5_APPENDER.MaxNumberOfRecords = 2000    

 

# 发送日志给邮件   

log4j.appender.MAIL = org.apache.log4j.net.SMTPAppender   

log4j.appender.MAIL.Threshold = FATA  

log4j.appender.MAIL.BufferSize = 10    

log4j.appender.MAIL.From = web@www.wuset.com  

log4j.appender.MAIL.SMTPHost = www.wusetu.com   

log4j.appender.MAIL.Subject = Log4J Message   

log4j.appender.MAIL.To = web@www.wusetu.com  

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

log4j.appender.MAIL.layout.ConversionPattern = [framework]  % d  -   % c  -%- 4r [ % t]  %- 5p  % c  % x  -   % m % n   

 



# 用数据库   

log4j.appender.DATABASE = org.apache.log4j.jdbc.JDBCAppender   

log4j.appender.DATABASE.URL = jdbc:mysql: // localhost:3306/test    

log4j.appender.DATABASE.driver = com.mysql.jdbc.Driver   

log4j.appender.DATABASE.user = root   

log4j.appender.DATABASE.password =    

log4j.appender.DATABASE.sql = INSERT INTO LOG4J (Message) VALUES ( ' [framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n ' )   

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

log4j.appender.DATABASE.layout.ConversionPattern = [framework]  % d  -   % c  -%- 4r [ % t]  %- 5p  % c  % x  -   % m % n   

log4j.appender.A1 = org.apache.log4j.DailyRollingFileAppender   

log4j.appender.A1.File = SampleMessages.log4j   

log4j.appender.A1.DatePattern = yyyyMMdd - HH ' .log4j '    

log4j.appender.A1.layout = org.apache.log4j.xml.XMLLayout   



#自定义Appender   

log4j.appender.im  =  net.cybercorlin.util.logger.appender.IMAppender   

log4j.appender.im.host  =  mail.cybercorlin.net   

log4j.appender.im.username  =  username   

log4j.appender.im.password  =  password   

log4j.appender.im.recipient  =  corlin@cybercorlin.net  

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

log4j.appender.im.layout.ConversionPattern  = [framework]  % d  -   % c  -%- 4r [ % t]  %- 5p  % c  % x  -   % m % n  


分享到:
评论

相关推荐

    Commons-logging + Log4j 使用

    这是一个讲解commons-logging 和log4j的使用方法,里面有一些例子供大家参考。

    Log4j 2.0 使用说明

    文档中介绍 log4j2 的怎么配置和使用

    JSF+Spring+Hibernate小例子

    基于网上很多朋友在问JSF+Spring+Hibernate的使用方法,于是抽空写了个小例子希望大家提出宝贵意见。 采用DBUnit测试 mysql数据库脚本: 新建test数据库,初始化脚本 create table tt(id int primary key,name ...

    jcl-over-slf4j-1.7.25.jar 由于下载次数较多,所需积分上去了,我已下调

    java 界里有许多实现日志功能的工具,最早得到广泛使用的是 log4j,许多应用程序的日志部分都交给了 log4j,不过作为组件开发者,他们希望自己的组件不要紧紧依赖某一个工具,毕竟在同一个时候还有很多其他很多日志...

    MyEclipse_9创建SSH2开发环境必须的独立包

    struts2 相关包-------------------------------------------------- xwork-2.0.5.jar webwork的核心库 ognl-2.6.11.jar OGNL...slf4j-log4j12-1.5.0.jar slf4j log4j支持包 log4j-1.2.15.jar slf4j-api-1.5.0.jar

    log4j将记录日志保存到数据库

    系统必须包含commons-logging-xxx.jar,log4j-xxx.jar这两个JAR包,XXX为版本号。  二、操作步骤  1、创建日志表 要把日志持久化,必须在数据库中创建一张用来存储日志信息的表,表内字段为日志 的一个主要...

    WSDL2Java工具包

    1、下载WSDL2JAVA.rar包,其中包含activation.jar,axis-ant.jar,axis.jar,commons- discovery-0.2.jar,commons-logging-1.0.4.jar,jaxrpc.jar,log4j- 1.2.8.jar,mail.jar,saaj.jar,wsdl4j-1.5.1.jar。...

    JDBC操作封装 IO流操作封装 CRC效验码生成

    log4j-1.2.16.jar mysql 驱动务必使用5.0以上版本 连接池的初始化、创建等仔细看构造函数的doc文档,就知道如何操作。我自己用着很方便。 有两个初始化方法,分别用于初始化多个数据库对象,或者单个数据库对象。 ...

    廖雪峰 Java 教程.doc

    使用Log4j 使用SLF4J和Logback 反射 Class类 访问字段 调用方法 调用构造方法 获取继承关系 动态代理 注解 使用注解 定义注解 处理注解 泛型 什么是泛型 使用泛型 编写泛型 擦拭法 extends通配符 ...

    基于EXT SSI的简单树实现

    一个基于EXT实现的树,先上图。...1 导入 commons-logging-1.1.jar log4j-1.2.14.jar 2 写log4j.properties 3 在代码中使用方式 static Log log = LogFactory.getLog("Action类"); log.debug("result is " + result);

    jpivot学习总结.doc

    4. JPivot标签库使用详解 4.1. Introduce JPivot 是一套基于 Mondrian 的 OLAP 前端展现工具,它提供了一套标签库来解决的 OLAP 的展现层问题。 在一个 JSP 页面当中,如果要使用 JPivot 标签库,除了要配置相关的...

    Hibernate中文API

    请参见发布包中的lib/目录下的README.txt,以获取更多关于所需和可选的第三方库文件信息(事实上,Log4j并不是必须的库文件,但被许多开发者所喜欢)。 接下来我们创建一个类,用来代表那些我们希望储存在数据库里...

    (2.0版本)自己写的struts2+hibernate+spring实例

    1.1-beta-7.jar jdbc2_0-stdext.jar jta.jar log4j-1.2.11.jar xerces-2.6.2.jar xml-apis.jar c3p0-0.9.0.jar concurrent-1.3.2.jar connector.jar jboss-cache.jar jboss...

    Spring 3 Reference中文

    1.3.2.3 使用Log4J .. 19 第二部分 Spring 3 的新特性.. 21 第2 章 Spring 3.0 的新特性和增强 21 2.1 Java 5.. 21 2.2 改进的文档. 21 2.3 新的文章和教程. 21 2.4 新的模块组织方式...

    +Flex+集成到+Java+EE+应用程序的最佳实践(完整源代码)

    commons-logging.jar flex-messaging-common.jar flex-messaging-core.jar flex-messaging-proxy.jar flex-messaging-remoting.jar 在 web.xml 中添加 HttpFlexSession 和 Servlet 映射。...

    将 Flex 集成到 Java EE 应用程序的最佳实践(完整源代码)

    commons-logging.jar flex-messaging-common.jar flex-messaging-core.jar flex-messaging-proxy.jar flex-messaging-remoting.jar 在 web.xml 中添加 HttpFlexSession 和 Servlet 映射。HttpFlexSession ...

    飞qjava源码-PdfLayoutManager:向PDFBox添加换行、分页、表格和样式

    Log4J 或 apache commons Logging。 用法 例子: API 文档可从 maven 中心获得。 我认为旧(2.0 之前)版本的 PDFBox 中的字符编码问题已得到修复。 因此,我删除了俄语的音译代码,该代码还将任何“高 ANSI 字符”...

    spring3.1中文参考文档

    1.3.2.3 使用Log4J ............................................................................................................................. 20 第二部分 Spring 3的新特性...............................

Global site tag (gtag.js) - Google Analytics