logback中使用properties文件
2016-06-30 00:00
926 查看
// 觉得前面废话太多的请直接看后面的代码结论。
项目用的是springmvc,之前一个项目在使用log4j的时候,发现log对象内存溢出了,原因是调测阶段,为了跟踪每个用户的使用情况,对于用户都会生成一个流水号,一个流水号就生成一个log文件,后来一天上千个用户,一个星期tomcat就挂了。
听别人说logback算是log4j的升级版,也改用logback了。之后的项目,压力稍微大些,根据需求,不需要做集群,session同步等,只是后台的http服务,就用nginx负载分流,不同的tomcat有自己的作用,配置文件会有差别。部署的时候发现每个tomcat都要改一次自己的config.properties,还要改logback.xml,查了一下,看到网上有人成功地在logback.xml文件中引入properties文件了,但是自己尝试一直不成功,最后在控制台发现Could not find properties file [config.properties]得到灵感,写绝对路径就可以找到。
那么,为啥spring就可以找到classpath:config.properties呢?在网上找到一个说法,是spring框架对于classpath有做处理,会去找class根目录,没读过源码也不知道去哪里找,看到的那个是有一段代码,判断classpath前缀的,于是就想到,自己可以写一个PropertyAction.java覆盖logback的代码,做了前缀判断处理,代码只验证了一小块,后面用url的方式没实际使用过。代码如下,注释中写的new部分是新增的。
以上,在windows本地开发环境测过了,linux环境还没测过,在logback.xml中只要引入properties位置就可以了,思路就这样,不知道其他人是怎么弄的,毕竟只是自己想的。
项目用的是springmvc,之前一个项目在使用log4j的时候,发现log对象内存溢出了,原因是调测阶段,为了跟踪每个用户的使用情况,对于用户都会生成一个流水号,一个流水号就生成一个log文件,后来一天上千个用户,一个星期tomcat就挂了。
听别人说logback算是log4j的升级版,也改用logback了。之后的项目,压力稍微大些,根据需求,不需要做集群,session同步等,只是后台的http服务,就用nginx负载分流,不同的tomcat有自己的作用,配置文件会有差别。部署的时候发现每个tomcat都要改一次自己的config.properties,还要改logback.xml,查了一下,看到网上有人成功地在logback.xml文件中引入properties文件了,但是自己尝试一直不成功,最后在控制台发现Could not find properties file [config.properties]得到灵感,写绝对路径就可以找到。
那么,为啥spring就可以找到classpath:config.properties呢?在网上找到一个说法,是spring框架对于classpath有做处理,会去找class根目录,没读过源码也不知道去哪里找,看到的那个是有一段代码,判断classpath前缀的,于是就想到,自己可以写一个PropertyAction.java覆盖logback的代码,做了前缀判断处理,代码只验证了一小块,后面用url的方式没实际使用过。代码如下,注释中写的new部分是新增的。
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位置就可以了,思路就这样,不知道其他人是怎么弄的,毕竟只是自己想的。
<property file="classpath:config.properties" /> <appender xxx> <File>${log.path}</File> </appender>
相关文章推荐
- 一个jar包里的网站
- 一个jar包里的网站之文件上传
- 一个jar包里的网站之返回对媒体类型
- Spring和ThreadLocal
- Spring Boot 开发微服务
- Spring AOP动态代理-切面
- Spring整合Quartz(JobDetailBean方式)
- Spring整合Quartz(JobDetailBean方式)
- 模拟Spring的简单实现
- Spring整合WebSocket应用示例(上)
- spring+html5实现安全传输随机数字密码键盘
- Spring中属性注入详解
- 监听器获取Spring配置文件的方法
- Java利用Sping框架编写RPC远程过程调用服务的教程
- springmvc 发送ajax出现中文乱码的解决方法汇总
- SpringMVC框架下JQuery传递并解析Json格式的数据是如何实现的
- 详解Java的MyBatis框架和Spring框架的整合运用
- struts2 spring整合fieldError问题
- Android 读取Properties配置文件的小例子