一 约定优于配置

约定优于配置(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 pathurl = 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就是配置文件。

staticpublic 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方法:

publicvoid 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自定义配置文件路径相关推荐

  1. log4j自定义配置文件(SpringMVC项目)

    问题来源 本周在实际项目中发现无法自定义的log4j-dev配置的error日志级别文件无法生效,项目启动后仍然采用默认的info级别日志进行打印.之所以自定义名称,是为了减少隔离不同环境的日志级别, ...

  2. springboot logback自定义配置文件路径

    //需要在项目启动项执行 static {System.setProperty("logging.config", System.getProperty("user.di ...

  3. Spring Web Flow 简单实现-自定义配置文件位置

    前言 在文章 Spring Web Flow 简单实现 中,我们把Web Flow 的的配置文件和 jsp 页面文件统一放置在了 WEB-INF 目录下,事实上,那种情况下我们不得不这样做. 这片文章 ...

  4. slf4j-log4j12加log4j自定义配置包路径日志输出

    项目日志在定位问题原因上起着重要的作用,有用的日志输出能提高解决问题的效率,所以日志配置还是很关键的,对一个项目来说有用的日志包路径一般都是项目自己包路径下的日志,集成的框架和依赖包中的包路径下的日志 ...

  5. java调用kettle自定义kettle.properties配置文件路径

    java调用kettle自定义kettle.properties配置文件路径 默认路径 java调用kettle的jar包时,在初始化环境的时候,会在指定路径创建并加载kettle的kettle.pr ...

  6. 因缺失log4j.properties 配置文件导致flume无法正常启动。

    因缺失log4j.properties 配置文件导致flume无法正常启动 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.报错:log4j:WARN No appenders ...

  7. java自定义配置文件_基于java读取并引用自定义配置文件

    基于java读取并引用自定义配置文件 首先在resources目录创建自定义的配置文件 配置文件的格式: 写工具类,得到配置参数 import java.io.IOException; import ...

  8. log4j多配置文件处理

    log4j多配置文件处理 关于log4j的常用配置以及相关配置格式,详细配置可以参考:http://blog.csdn.net/yeruby/article/details/51719333 关于we ...

  9. Tomcat下log4j设置文件路径和temp目录

    转自:http://www.cnblogs.com/dkblog/archive/2007/07/27/1980873.html 在Web应用中的如何设置日志文件的路径呢?最笨的方法是写绝对路径,但很 ...

  10. Log4j自定义Appender介绍

    最初想要在执行一段业务逻辑的时候调用一个外部接口记录审计信息,一直找不到一个比较优雅的方式,经过讨论觉得log4j自定义的appender或许可以实现此功能.后来就了解了一下log4j的这部分. Ap ...

最新文章

  1. react antd form 表单清空
  2. Java实用教程笔记 泛型与集合框架
  3. 互联网协议 — RTSP 实时流传输协议
  4. C语言程序设计输入x求函数y,C语言程序设计实践(OJ)-初识函数
  5. node:express:error---填坑之路
  6. java.lang.IllegalStateException: PathVariable/RequestParam annotation was empty on param 0.
  7. API网关—Spring Cloud Zuul
  8. 如何看懂串口通讯协议_一文看懂PLC的通讯方式——AB系统(一)
  9. 如何理解 Graph Convolutional Network(GCN)?
  10. python爬虫程序的流程图_Python即时网络爬虫项目: 内容提取器的定义(Python2.7版本)...
  11. css自动换行加前置_StudyNode -- CSS
  12. 【转载】印制板设计的流程及注意事项
  13. AJAX Wrapper for .NET
  14. 03 两个重要极限函数
  15. 网站运营模式之行业网站分析
  16. 读Zepto源码之Ajax模块
  17. MP4格式转换为AMV格式
  18. 基于深度学习的人脸识别技术综述
  19. udl 连mysql_几种常见的数据库连接方法
  20. 怎样查找MP3音乐链接地址 用于QQ空间背景

热门文章

  1. VS 2013 所有产品密钥
  2. lacp静态和动态区别_LACP基础
  3. Github上优秀的开源项目
  4. 系统集成项目管理工程师(软考中级)—— 第七章 知识产权 笔记分享
  5. 图神经网络——node2vec
  6. mysql 卸载服务
  7. ISO9001-2008标准(中英文对照)
  8. Ubuntu 安装Qt以及配置
  9. 机器人路径规划之RRT算法
  10. 【JSP】测试Ajax