• log4j源码阅读


    基于log4j1.2.17的源代码阅读

    org.apache.log4j.xml.DOMConfigurator 类是log4j的xml配置文件初始化类

    org.apache.log4j.PropertyConfigurator 类是log4j的properties形式配置文件的初始化类

    今天看的是前者

      /**
         A static version of {@link #doConfigure(String, LoggerRepository)}.  */
      static
      public
      void configure(String filename) throws FactoryConfigurationError {
        new DOMConfigurator().doConfigure(filename, 
    				      LogManager.getLoggerRepository());
      }
    

    一般我们都是讲log4j.xml配置文件放到与src同目录下,方便在class path 的当前路径进行查找(不能放置到src目录里面,不然打包之后也会被打包到类目录下)

     public
      void doConfigure(final String filename, LoggerRepository repository) {
        ParseAction action = new ParseAction() {
              public Document parse(final DocumentBuilder parser) throws SAXException, IOException {
                  return parser.parse(new File(filename));
              }
              public String toString() { 
                  return "file [" + filename + "]"; 
              }
        };
        doConfigure(action, repository);
      }
      
    

    repositroy的作用目前还没有看到

    先看下是如何解析xml和初始化相关对象的。

    最终会调用DOMConfigurator 类当中的方法

    /**
         Used internally to configure the log4j framework by parsing a DOM
         tree of XML elements based on <a
         href="doc-files/log4j.dtd">log4j.dtd</a>.
         
      */
      protected
      void parse(Element element) {
    
        String rootElementName = element.getTagName();
    
        if (!rootElementName.equals(CONFIGURATION_TAG)) {
          if(rootElementName.equals(OLD_CONFIGURATION_TAG)) {
    	LogLog.warn("The <"+OLD_CONFIGURATION_TAG+
    		     "> element has been deprecated.");
    	LogLog.warn("Use the <"+CONFIGURATION_TAG+"> element instead.");
          } else {
    	LogLog.error("DOM element is - not a <"+CONFIGURATION_TAG+"> element.");
    	return;
          }
        }
    
    
        String debugAttrib = subst(element.getAttribute(INTERNAL_DEBUG_ATTR));
          
        LogLog.debug("debug attribute= "" + debugAttrib +"".");
        // if the log4j.dtd is not specified in the XML file, then the
        // "debug" attribute is returned as the empty string.
        if(!debugAttrib.equals("") && !debugAttrib.equals("null")) {      
          LogLog.setInternalDebugging(OptionConverter.toBoolean(debugAttrib, true));
        } else {
          LogLog.debug("Ignoring " + INTERNAL_DEBUG_ATTR + " attribute.");
        }
    
          //
          //   reset repository before configuration if reset="true"
          //       on configuration element.
          //
        String resetAttrib = subst(element.getAttribute(RESET_ATTR));
        LogLog.debug("reset attribute= "" + resetAttrib +"".");
        if(!("".equals(resetAttrib))) {
             if (OptionConverter.toBoolean(resetAttrib, false)) {
                 repository.resetConfiguration();
             }
        }
    
    
    
        String confDebug = subst(element.getAttribute(CONFIG_DEBUG_ATTR));
        if(!confDebug.equals("") && !confDebug.equals("null")) {      
          LogLog.warn("The ""+CONFIG_DEBUG_ATTR+"" attribute is deprecated.");
          LogLog.warn("Use the ""+INTERNAL_DEBUG_ATTR+"" attribute instead.");
          LogLog.setInternalDebugging(OptionConverter.toBoolean(confDebug, true));
        }
    
        String thresholdStr = subst(element.getAttribute(THRESHOLD_ATTR));
        LogLog.debug("Threshold ="" + thresholdStr +"".");
        if(!"".equals(thresholdStr) && !"null".equals(thresholdStr)) {
          repository.setThreshold(thresholdStr);
        }
    
        //Hashtable appenderBag = new Hashtable(11);
    
        /* Building Appender objects, placing them in a local namespace
           for future reference */
    
        // First configure each category factory under the root element.
        // Category factories need to be configured before any of
        // categories they support.
        //
        String   tagName = null;
        Element  currentElement = null;
        Node     currentNode = null;
        NodeList children = element.getChildNodes();
        final int length = children.getLength();
    
        for (int loop = 0; loop < length; loop++) {
          currentNode = children.item(loop);
          if (currentNode.getNodeType() == Node.ELEMENT_NODE) {
    	currentElement = (Element) currentNode;
    	tagName = currentElement.getTagName();
    
    	if (tagName.equals(CATEGORY_FACTORY_TAG) || tagName.equals(LOGGER_FACTORY_TAG)) {
    	  parseCategoryFactory(currentElement);
    	}
          }
        }
        
        for (int loop = 0; loop < length; loop++) {
          currentNode = children.item(loop);
          if (currentNode.getNodeType() == Node.ELEMENT_NODE) {
    	currentElement = (Element) currentNode;
    	tagName = currentElement.getTagName();
    
    	if (tagName.equals(CATEGORY) || tagName.equals(LOGGER)) {
    	  parseCategory(currentElement);
    	} else if (tagName.equals(ROOT_TAG)) {
    	  parseRoot(currentElement);
    	} else if(tagName.equals(RENDERER_TAG)) {
    	  parseRenderer(currentElement);
        } else if(tagName.equals(THROWABLE_RENDERER_TAG)) {
            if (repository instanceof ThrowableRendererSupport) {
                ThrowableRenderer tr = parseThrowableRenderer(currentElement);
                if (tr != null) {
                    ((ThrowableRendererSupport) repository).setThrowableRenderer(tr);
                }
            }
        } else if (!(tagName.equals(APPENDER_TAG)
                || tagName.equals(CATEGORY_FACTORY_TAG)
                || tagName.equals(LOGGER_FACTORY_TAG))) {
            quietParseUnrecognizedElement(repository, currentElement, props);
        }
          }
        }
      }
    

    通过分析这个方法我们可以看到

    1)log4j.xml 中的根tag必须开头是log4j:configuration 

       如果不是,将会返回错误,并且同时检查是否是老的标签

    OLD_CONFIGURATION_TAG ------configuration 如果是的话就打出warn日志,不是打出error日志
    2)
    在Log4j的源代码当中我们也发现了很多Log日志 ,在Log4j还没有加载完成的时候,利用的是什么打印的呢?
    import org.apache.log4j.helpers.LogLog; 利用的就是这个内部帮助类,当我们在log4j.xml的根tag上标注debug=“true”的时候,就会发现这些log日志也打出了,主要是log4j的初始化日志,在quartz当中也可以看到类似的初始化日志
  • 相关阅读:
    IDEA效率快捷键
    常用文件/文件夹操作
    git log状态下退出方法
    ImageList 构造函数
    ImageList 控件
    【转】图像分割代码合集
    【转】图像分割论文及代码资源汇总
    SLIC 算法
    c/c++内存分配详解
    c++内存分配
  • 原文地址:https://www.cnblogs.com/wuxinliulei/p/5177201.html
Copyright © 2020-2023  润新知