好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

Log4j源码分析及配置拓展

Log4j源码分析及配置拓展

Log4j源码分析及配置拓展

Log4j 是 java中 非常广泛的日志记录组件,使用非常简单。在工程中加入 Log4j 的 jar 包后,再加上简单的 Log4j.xml 或者 Log4j.properties 等配置文件 后就可以使用。其背后的实现原理是什么呢?假如我们的项目很大,各个配置文件的属性需要写在一个文件中,这样便于实施人员修改。那该怎么办?

先来讨论Log4j实例化原理。使用 Logger logger = Logger. getLogger (Log4jTest. class ) 就 能获得 Logger 的实例。进入 getLogger 方法(在 eclipse 中按住 Ctrl 键后左键单击方法名),可以看见 Logger 实例实例是由 LogManager 来创建的,它会读取 Log4j.xml 或者 Log4j.properties 等配置文件,其配置文件中的属性又是谁去读的呢,进一步跟踪,在 OptionConverter.class 类中 selectAndConfigure 方法中可以看到如下代码:

if (clazz ==  null  && filename !=  null  && filename.endsWith( ".xml" )) {

      clazz =  "org.apache.log4j.xml.DOMConfigurator" ;

    }

 

    if (clazz !=  null ) {

      LogLog. debug ( "Preferred configurator class: "  + clazz);

      configurator = (Configurator)  instantiateByClassName (clazz,

                        Configurator. class ,

                        null );

      if (configurator ==  null ) {

       LogLog. error ( "Could not instantiate configurator [" +clazz+ "]." );

       return ;

      }

    }  else  {

      configurator =  new  PropertyConfigurator();

    }

 

表示其配置类是由 org.apache.log4j.xml.DOMConfigurator 来实现的,我们也可以在系统变量中设置。 DOMConfigurator 类中定义了很多常量,用来表示 Log4j.xml 等配置文件的各个属性。

现在我们假设项目中的 Log4j.xml 中的配置文件是下面这样的。

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">

 

<log4j:configuration xmlns:log4j= " http://jakarta.apache.org/log4j/

     <appender name= "DailyRollingFileAppender"  class= "org.apache.log4j.DailyRollingFileAppender" >

        < param name="File" value="${file}" />

        <param name= "DatePattern"  value= "'.'yyyy-MM-dd'.log'"  />

        <layout class= "org.apache.log4j.PatternLayout" >

            <param name= "ConversionPattern"  value= "[%d{dd HH:mm:ss,SSS\} %-5p] [%t] %c{1}.%M(%L) - %m%n" />

        </layout>

     </appender>

     <root>

        <level value= "${level}"  />

        <appender-ref ref= "CONSOLE"  />

        <appender-ref ref= "DailyRollingFileAppender" />

     </root>

 

</log4j:configuration>

 

可以看到有两条红线选中的代码,其中 File 和 level 并没有直接赋值,这两个值需要从项目中总的配置文件中读取,其他开源组件的配置文件中经常修改的属性也写在这个总的配置文件中,这样不仅仅是对开发人员,还对实施人员都方便多了。那么如何实现这个需求呢?

只需写一个拓展类, 继承自 DOMConfigurator.class 类 ,重写其中的某些方法,并设置系统变量 log4j.configuratorClass 为 继承自 DOMConfigurator.class 的拓展类,代码如下:

拓展类: parseLevel 和 setParameter 方法中的逻辑代码可以自行处理。

package com.lsc.config;

public class  ExtDOMConfigurator  extends  DOMConfigurator{

  

      static public void  configure(URL url)  throws  FactoryConfigurationError {

         new  ExtDOMConfigurator().doConfigure(url, LogManager. getLoggerRepository ());

       }

     

    @Override

    public void  parseLevel(Element element, Logger logger,  boolean  isRoot) {

 

       if  (element.getAttribute( "value" ).contains( "level" )) {

         element.setAttribute( "value" ,  "info" );

       }      

    }

 

    @Override

    protected void  setParameter(Element elem, PropertySetter propSetter) {

           if  (elem.getAttribute( "value" ).contains( "f" )) {

         elem.setAttribute( "value" ,  "E:/bizfuse/log/bizfuse.log" );

       }

       super .setParameter(elem, propSetter);

    }

 

}

 

测试类:

package com.lsc;

public class  Log4jTest {

 

    public static void  main(String[] args) {

       URL url = Log4j. class .getResource( "/log4j.xml" );

       System. setProperty ( "log4j.configuratorClass" ,  "com.lsc.config.ExtDOMConfigurator" );

       ExtDOMConfigurator. configure (url);

       Logger logger = Logger. getLogger (Log4jTest. class );

       logger.info( new  Date() +  "     test" );

    }

 

}

作者: Leo_wl

    

出处: http://HdhCmsTestcnblogs测试数据/Leo_wl/

    

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

版权信息

查看更多关于Log4j源码分析及配置拓展的详细内容...

  阅读:62次

上一篇: Lucene 简单手记

下一篇:泛型