需求: 把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 本文的主要参考