log4j自定义配置文件路径
来源:互联网 发布:网络劫持是什么意思 编辑:程序博客网 时间:2024/06/05 19:36
一 约定优于配置
约定优于配置(convention over configuration),也称作按约定编程,是一种软件设计范式,旨在减少软件开发人员需做决定的数量,获得简单的好处,而又不失灵活性。大量的配置文件,确实可以让程序在一定程度上具有很大的灵活性,但是也要有度的限制,并不是越多越好;约定一些默认的配置,有助于减少配置文件的数量。当然,全部使用约定而不支持配置也是不可取的,必然有失灵活性;因此约定优于配置不代表不是用配置,而是一种要同时提供约定和配置两种方式。
rootAppender约定:
使用log4j打印日志,需要配置日志实例得输出样式以及目的地等等信息,不是必须配置的。
log4j约定了一种无须配置的日志实例的输出方式,提供了一个基本的控制台appender,所有创建的日志实例打印的日志都会按照这个appender输出。
只需要在创建日志实例之前调用默认初始化即可:
static { BasicConfigurator.configure(); logger = LogManager.getLogger(Log4jOneTest.class);}
控制台输出格式如下,不输出trace级别日志:
配置文件路径的约定:
log4j约定了配置文件在类路径种的位置,无需在程序中指定配置文件路径,log4j会在其指定的默认类路径下寻找配置,也就是在classpath得根路径:
二 配置文件如何加载
有时约定在classpaht根路径下的配置文件多了,会导致配置文件没有层次结构,很难发现配置文件的功能;因此此时需要自定义log4j配置文件的路径。
寻找配置文件:
通常,log4j在创建日志实例时都是通过调用LogManager的getLogger(String/Class)方法,分析LogManager的源码,LogManager在初始化时做了以下操作:
static { // By default we use a DefaultRepositorySelector which always returns 'h'. Hierarchy h = new Hierarchy(new RootLogger((Level) Level.DEBUG)); repositorySelector = new DefaultRepositorySelector(h); /** Search for the properties file log4j.properties in the CLASSPATH. */ // 获取名为log4j.defaultInitOverride的vm变量,该变量决定日志的初始化是否被重载 String override = OptionConverter.getSystemProperty(DEFAULT_INIT_OVERRIDE_KEY, null); // if there is no default init override, then get the resource // specified by the user or the default config file. if (override == null || "false".equalsIgnoreCase(override)) { // DEFAULT_CONFIGURATION_KEY的值为log4j.configuration,获取名为log4j.configuration的vm变量 String configurationOptionStr = OptionConverter.getSystemProperty( DEFAULT_CONFIGURATION_KEY, null); String configuratorClassName = OptionConverter.getSystemProperty( CONFIGURATOR_CLASS_KEY, null); URL url = null; // if the user has not specified the log4j.configuration // property, we search first for the file "log4j.xml" and then // "log4j.properties" // 如果在vm系统变量中没有找到log4j.configuration,则先在classpath根目录找log4j.xml, // 再寻找log4j.properties文件 if (configurationOptionStr == null) { url = Loader.getResource(DEFAULT_XML_CONFIGURATION_FILE); if (url == null) { url = Loader.getResource(DEFAULT_CONFIGURATION_FILE); } } else { // 若配置了vm系统变量log4j.configuration,则使用该变量的值作为配置文件的类路径 try { url = new URL(configurationOptionStr); } catch (MalformedURLException ex) { // so, resource is not a URL: // attempt to get the resource from the class path url = Loader.getResource(configurationOptionStr); } } // If we have a non-null url, then delegate the rest of the // configuration to the OptionConverter.selectAndConfigure // method. if (url != null) { LogLog.debug("Using URL [" + url + "] for automatic log4j configuration."); try { OptionConverter.selectAndConfigure(url, configuratorClassName, LogManager.getLoggerRepository()); } catch (NoClassDefFoundError e) { LogLog.warn("Error during default initialization", e); } } else { // 没有找到配置文件则报错 LogLog.debug("Could not find resource: [" + configurationOptionStr + "]."); } } else { LogLog.debug("Default initialization of overridden by " + DEFAULT_INIT_OVERRIDE_KEY + "property."); } }
因此,LogManager在初始化时:
1.查找log4j.defaultInitOverrideVM系统变量,确认初始化是否重载;
2.没要被重载的情况下,查找log4j.configurationVM系统变量,确认是否自定义配置文件路径;
3.没要配置log4j.configurationVM系统变量,顺序查找根类路径下的log4j.xml,log4j.properties
使用配置文件:
分析LogManager,在查找到配置文件后,调用了:
OptionConverter.selectAndConfigure(url, configuratorClassName, LogManager.getLoggerRepository());
来处理配置,其中url就是配置文件。
static public void selectAndConfigure(URL url, String clazz, LoggerRepository hierarchy) { Configurator configurator = null; String filename = url.getFile(); // 根据配置文件名后缀选择使用DOMConfigurator还是PropertyConfigurator来处理 if (clazz == null && filename != null && filename.endsWith(".xml")) { clazz = "org.apache.log4j.xml.DOMConfigurator"; } if (clazz != null) { LogLog.debug("Preferred configurator class: " + clazz); configurator = (Configurator) instantiateByClassName(clazz, Configurator.class, null); if (configurator == null) { LogLog.error("Could not instantiate configurator [" + clazz + "]."); return; } } else { configurator = new PropertyConfigurator(); } // 处理配置 configurator.doConfigure(url, hierarchy); }
最后看看DOMConfigurator处理配置文件的doConfigure方法:
public void doConfigure(final URL url, LoggerRepository repository) { ParseAction action = new ParseAction() { public Document parse(final DocumentBuilder parser) throws SAXException, IOException { URLConnection uConn = url.openConnection(); uConn.setUseCaches(false); InputStream stream = uConn.getInputStream(); try { InputSource src = new InputSource(stream); src.setSystemId(url.toString()); return parser.parse(src); } finally { stream.close(); } } public String toString() { return "url [" + url.toString() + "]"; } }; doConfigure(action, repository); }
可以看到读取了配置文件内容。PropertyConfigurator也是一样的
三 自定义配置文件路径
了解了log4j如何加载配置文件之后,就可以自定义配置文件路径了;
设值vm系统变量:
简单的,在获取logManager初始化值前,通过设置vm系统变量log4j.configuration的值为配置文件路径,可以达到目的:
static { String customizedPath = "log/log4j.xml"; System.setProperty("log4j.configuration", customizedPath); logger = LogManager.getLogger(Log4jOneTest.class);}
PropertyConfigurator或DOMConfigurator:
DOMConfigurator中有一个doConfigure()的static版本,对应xml配置方式,PropertyConfigurator也一样,对应properties配置方式,通过调用这个方法也能指定配置文件位置:
static public void configure(URL url) throws FactoryConfigurationError { new DOMConfigurator().doConfigure(url, LogManager.getLoggerRepository());}
具体如下:
static { String customizedPath = "log/log4j.xml"; DOMConfigurator.configure(getResource(customizedPath)); logger = LogManager.getLogger(Log4jOneTest.class);}
参考: 《 关于Log4j的初始化》
- log4j自定义配置文件路径
- maven多级项目使用 slf4j+log4j,以及自定义配置文件路径
- log4j配置文件相对路径
- 设置Log4j配置文件路径
- 自定义Log4j配置文件位置
- LOG4J配置文件的存放路径
- 程序自定义加载log4j配置文件
- log4j 配置文件中设置相对路径
- Log4J配置文件日志文件路径问题
- log4j配置文件 不在classpath路径的初始化
- 更改log4j的默认配置文件路径
- 非web环境log4j配置文件加载路径
- log4j从配置文件中读取路径
- log4j更改配置文件log4j.properties的默认路径
- Log4j 配置文件(log4j.properties)的所在路径问题
- log4j配置文件log4j.properties的默认路径问题
- Shiro 自定义核心配置文件路径
- 如何自定义获取log4j的配置文件
- Java类加载器ClassLoader总结
- 快排函数qsort调用的使用细则
- Dlib机器学习库安装
- Bootstrap-table使用详细介绍
- [golang]beego列表分页
- log4j自定义配置文件路径
- hdu 1284 钱币兑换问题(完全背包)
- 1000句最常用英语口语 (一)
- Linux芯片级移植与底层驱动(基于3.7.4内核)
- 报表查询中count用法
- Sublime安装,包管理
- php:细说PHP之文章发布操作实例
- android常用的各大开放平台网址
- 浅谈weblogic与tomcat的区别