zoukankan      html  css  js  c++  java
  • Log4j源码分析及配置拓展

    Log4j源码分析及配置拓展

    Log4jjava中非常广泛的日志记录组件,使用非常简单。在工程中加入Log4jjar包后,再加上简单的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>

     

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

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

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

    package com.lsc.config;

    publicclass ExtDOMConfigurator extends DOMConfigurator{

      

        staticpublicvoid configure(URL url) throws FactoryConfigurationError {

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

         }

        

       @Override

       publicvoid parseLevel(Element element, Logger logger, boolean isRoot) {

     

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

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

          }    

       }

     

       @Override

       protectedvoid 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;

    publicclass Log4jTest {

     

       publicstaticvoid 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");

       }

     

    }

  • 相关阅读:
    复习一下 .Net: delegate(委托)、event(事件) 的基础知识,从头到尾实现事件!
    雕虫小技: 给枯燥的 .Net 控制台程序(字符界面)来点儿心跳 (关于退格 '\b' 的使用)
    .Net Remoting 事件回调 Client 函数方法完整实例: C# 实现控制台网络聊天室 (Console Remoting ChatRoom)
    一气呵成得到 MSSQL DB 中所有表的字段默认值约束的 DDL SQL 脚本
    根据数据生成 INSERT INTO ... 的 SQL (.Net C#, TSQL Store Procedure 分别实现)
    .Net/C# 与 J2EE/Java Web Service 互操作完整实例
    TSQL: 关于 Varbinary(Hex,Int) 与 Varchar(HexString) 之间的(数据类型)转换
    Linux零碎记录之ulimit【堆栈大小、stack size、进程数限制、文件句柄限制、linux用户空间限制】
    svn之svn:ignore命令行设置
    C语言零碎记录之extern
  • 原文地址:https://www.cnblogs.com/lsc183/p/2672304.html
Copyright © 2011-2022 走看看