[Log4j] Log4j 的配置和配置文件加载顺序

需求:  把log4j.properties 配置问题放置到工程外面的指定文件夹。  具体原因参考http://blog.csdn.net/lihe2008125/article/details/7764247。

默认情况下,log4j 会自动加载classpath 中的配置文件。而且没有打包的log4j.properties 优先于大在jar 包中的log4j.properties 文件。(这里可以回忆一下自己项目中的配置)

也可以在web项目的web.xml里面配置一个Listener。

想到了两种方法:1  Log4j 支持使用java 类配置自己使用什么配置文件。2 利用类加载机制,把log4j.properties 文件加载到classpath 的最前面,让log4j 自己去加载。


由于想部署多个实例,而且不想修改java 程序,所以采用第2种方法。


项目中有采取了在tomcat 的catalina.sh 中添加

JAVA_OPTS="$JAVA_OPTS -Dlog4j.configuration=file:/lc_iims/properties/Crawl26101/log4j.properties -XX:MaxPermSize=256m -Xms256m -Xmx1024m"
来解决Log4j 的配置文件问题。


遇到的问题: 就是把log4j.properties 文件加载到classpath 路径的前面,但是没有起到作用。

原因: 这时log4j 会优先加载jar 包中的log4j.properties 文件。


原理,可以参考如下源码  org.apache.log4j.LogManager 类。

部分源码如下:

static
/*     */   {
/*  80 */     Hierarchy h = new Hierarchy(new RootLogger(Level.DEBUG));
/*  81 */     repositorySelector = new DefaultRepositorySelector(h);
/*     */ 
/*  84 */     String override = OptionConverter.getSystemProperty("log4j.defaultInitOverride", null);
/*     */ 
/*  89 */     if ((override != null) && (!("false".equalsIgnoreCase(override))))
/*     */       return;
/*  91 */     String configurationOptionStr = OptionConverter.getSystemProperty("log4j.configuration", null);
/*     */ 
/*  95 */     String configuratorClassName = OptionConverter.getSystemProperty("log4j.configuratorClass", null);
/*     */ 
/*  99 */     URL url = null;
/*     */ 
/* 104 */     if (configurationOptionStr == null) {
/* 105 */       url = Loader.getResource("log4j.xml");
/* 106 */       if (url == null)
/* 107 */         url = Loader.getResource("log4j.properties");
/*     */     }
/*     */     else {
/*     */       try {
/* 111 */         url = new URL(configurationOptionStr);
/*     */       }
/*     */       catch (MalformedURLException ex)
/*     */       {
/* 115 */         url = Loader.getResource(configurationOptionStr);
/*     */       }
/*     */ 
/*     */     }
/*     */ 
/* 122 */     if (url != null) {
/* 123 */       LogLog.debug("Using URL [" + url + "] for automatic log4j configuration.");
/*     */       try {
/* 125 */         OptionConverter.selectAndConfigure(url, configuratorClassName, getLoggerRepository());
/*     */       }
/*     */       catch (NoClassDefFoundError e) {
/* 128 */         LogLog.warn("Error during default initialization", e);
/*     */       }
/*     */     } else {
/* 131 */       LogLog.debug("Could not find resource: [" + configurationOptionStr + "].");
/*     */     }
/*     */   }
/*     */ }


可以看出支持log4j.defaultInitOverride 和log4j.configuration 和log4j.configuratorClass 系统属性配置。可以看到主要是调用

                    url = Loader.getResource("log4j.xml");
/* 106 */       if (url == null)
/* 107 */         url = Loader.getResource("log4j.properties");


而在Loader.getResource(String)  方法中是这样实现的:

public static URL getResource(String resource)
/*     */   {
/*  88 */     ClassLoader classLoader = null;
/*  89 */     URL url = null;
/*     */     try
/*     */     {
/*  92 */       if (!(java1)) {
/*  93 */         classLoader = getTCL();
/*  94 */         if (classLoader != null) {
/*  95 */           LogLog.debug("Trying to find [" + resource + "] using context classloader " + classLoader + ".");
/*     */ 
/*  97 */           url = classLoader.getResource(resource);
/*  98 */           if (url != null) {
/*  99 */             return url;
/*     */           }
/*     */ 
/*     */         }
/*     */ 
/*     */       }
/*     */ 
/* 106 */       classLoader = Loader.class.getClassLoader();
/* 107 */       if (classLoader != null) {
/* 108 */         LogLog.debug("Trying to find [" + resource + "] using " + classLoader + " class loader.");
/*     */ 
/* 110 */         url = classLoader.getResource(resource);
/* 111 */         if (url != null)
/* 112 */           return url;
/*     */       }
/*     */     }
/*     */     catch (Throwable t) {
/* 116 */       LogLog.warn("Caught Exception while in Loader.getResource. This may be innocuous.", t);
/*     */     }
/*     */ 
/* 123 */     LogLog.debug("Trying to find [" + resource + "] using ClassLoader.getSystemResource().");
/*     */ 
/* 125 */     return ClassLoader.getSystemResource(resource);
/*     */   }

从debug 信息中可以看出加载顺序:

1  Trying to find [" + resource + "] using context classloader " + classLoader + "."       加载本工程中的配置文件

2  Trying to find [" + resource + "] using " + classLoader + " class loader.          加载jar 包中的配置文件

3   Trying to find [" + resource + "] using ClassLoader.getSystemResource().      加载系统类路径的配置文件


ps: 其实,log4j 真的很猛,他还支持异步写日志。 

可以参考http://raymondhekk.iteye.com/blog/229937

log4j日志异步化大幅提升系统性能     来了解

参考  1  http://topic.csdn.net/u/20101123/09/a697e3c5-2142-4597-91b8-5fad66da24bb.html       log4j 的简单入门

          2  http://www.iteye.com/topic/378077        本文的主要参考

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值