logback中使用properties文件

// 以爲前面廢話太多的請直接看後面的代碼結論。java

項目用的是springmvc,以前一個項目在使用log4j的時候,發現log對象內存溢出了,緣由是調測階段,爲了跟蹤每一個用戶的使用狀況,對於用戶都會生成一個流水號,一個流水號就生成一個log文件,後來一天上千個用戶,一個星期tomcat就掛了。linux

聽別人說logback算是log4j的升級版,也改用logback了。以後的項目,壓力稍微大些,根據需求,不須要作集羣,session同步等,只是後臺的http服務,就用nginx負載分流,不一樣的tomcat有本身的做用,配置文件會有差異。部署的時候發現每一個tomcat都要改一次本身的config.properties,還要改logback.xml,查了一下,看到網上有人成功地在logback.xml文件中引入properties文件了,可是本身嘗試一直不成功,最後在控制檯發現Could not find properties file [config.properties]獲得靈感,寫絕對路徑就能夠找到。nginx

那麼,爲啥spring就能夠找到classpath:config.properties呢?在網上找到一個說法,是spring框架對於classpath有作處理,會去找class根目錄,沒讀過源碼也不知道去哪裏找,看到的那個是有一段代碼,判斷classpath前綴的,因而就想到,本身能夠寫一個PropertyAction.java覆蓋logback的代碼,作了前綴判斷處理,代碼只驗證了一小塊,後面用url的方式沒實際使用過。代碼以下,註釋中寫的new部分是新增的。spring

 

package ch.qos.logback.core.joran.action;

import ch.qos.logback.core.joran.action.ActionUtil.Scope;
import ch.qos.logback.core.joran.spi.InterpretationContext;
import ch.qos.logback.core.pattern.util.RegularEscapeUtil;
import ch.qos.logback.core.util.Loader;
import ch.qos.logback.core.util.OptionHelper;
import org.xml.sax.Attributes;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Properties;

public class PropertyAction extends Action {
	static final String RESOURCE_ATTRIBUTE = "resource";
	static final String CLASSPATH_URL_PREFIX = "classpath"; // new
	static String INVALID_ATTRIBUTES = "In <property> element, either the \"file\" attribute alone, or the \"resource\" element alone, or both the \"name\" and \"value\" attributes must be set.";

	public PropertyAction() {
	}

	public void begin(InterpretationContext ec, String localName, Attributes attributes) {
		if("substitutionProperty".equals(localName)) {
			this.addWarn("[substitutionProperty] element has been deprecated. Please use the [property] element instead.");
		}

		String name = attributes.getValue("name");
		String value = attributes.getValue("value");
		String scopeStr = attributes.getValue("scope");
		Scope scope = ActionUtil.stringToScope(scopeStr);
		String resource;
		if(this.checkFileAttributeSanity(attributes)) {
			resource = attributes.getValue("file");
			resource = ec.subst(resource);
			if(resource.startsWith(CLASSPATH_URL_PREFIX)) { // new
				resource = this.getClass().getResource("/").getPath() + resource.substring(CLASSPATH_URL_PREFIX.length() + 1);
			}

			try {
				FileInputStream resourceURL = new FileInputStream(resource);
				this.loadAndSetProperties(ec, resourceURL, scope);
			} catch (FileNotFoundException var12) {
				this.addError("Could not find properties file [" + resource + "].");
			} catch (IOException var13) {
				this.addError("Could not read properties file [" + resource + "].", var13);
			}
		} else if(this.checkResourceAttributeSanity(attributes)) {
			resource = attributes.getValue("resource");
			resource = ec.subst(resource);
			if(resource.startsWith(CLASSPATH_URL_PREFIX)) { // new
				resource = this.getClass().getResource("/") + resource.substring(CLASSPATH_URL_PREFIX.length() + 1);
			}
			URL resourceURL1 = Loader.getResourceBySelfClassLoader(resource);
			if(resourceURL1 == null) {
				this.addError("Could not find resource [" + resource + "].");
			} else {
				try {
					InputStream e = resourceURL1.openStream();
					this.loadAndSetProperties(ec, e, scope);
				} catch (IOException var11) {
					this.addError("Could not read resource file [" + resource + "].", var11);
				}
			}
		} else if(this.checkValueNameAttributesSanity(attributes)) {
			value = RegularEscapeUtil.basicEscape(value);
			value = value.trim();
			value = ec.subst(value);
			ActionUtil.setProperty(ec, name, value, scope);
		} else {
			this.addError(INVALID_ATTRIBUTES);
		}

	}

	void loadAndSetProperties(InterpretationContext ec, InputStream istream, Scope scope) throws IOException {
		Properties props = new Properties();
		props.load(istream);
		istream.close();
		ActionUtil.setProperties(ec, props, scope);
	}

	boolean checkFileAttributeSanity(Attributes attributes) {
		String file = attributes.getValue("file");
		String name = attributes.getValue("name");
		String value = attributes.getValue("value");
		String resource = attributes.getValue("resource");
		return !OptionHelper.isEmpty(file) && OptionHelper.isEmpty(name) && OptionHelper.isEmpty(value) && OptionHelper.isEmpty(resource);
	}

	boolean checkResourceAttributeSanity(Attributes attributes) {
		String file = attributes.getValue("file");
		String name = attributes.getValue("name");
		String value = attributes.getValue("value");
		String resource = attributes.getValue("resource");
		return !OptionHelper.isEmpty(resource) && OptionHelper.isEmpty(name) && OptionHelper.isEmpty(value) && OptionHelper.isEmpty(file);
	}

	boolean checkValueNameAttributesSanity(Attributes attributes) {
		String file = attributes.getValue("file");
		String name = attributes.getValue("name");
		String value = attributes.getValue("value");
		String resource = attributes.getValue("resource");
		return !OptionHelper.isEmpty(name) && !OptionHelper.isEmpty(value) && OptionHelper.isEmpty(file) && OptionHelper.isEmpty(resource);
	}

	public void end(InterpretationContext ec, String name) {
	}

	public void finish(InterpretationContext ec) {
	}
}

 以上,在windows本地開發環境測過了,linux環境還沒測過,在logback.xml中只要引入properties位置就能夠了,思路就這樣,不知道其餘人是怎麼弄的,畢竟只是本身想的。windows

<property file="classpath:config.properties" />
<appender xxx>
    <File>${log.path}</File>
</appender>
相關文章
相關標籤/搜索