1. 程式人生 > >log4j自定義配置檔案路徑

log4j自定義配置檔案路徑

一 約定優於配置

約定優於配置(convention over configuration),也稱作按約定程式設計,是一種軟體設計正規化,旨在減少軟體開發人員需做決定的數量,獲得簡單的好處,而又不失靈活性。大量的配置檔案,確實可以讓程式在一定程度上具有很大的靈活性,但是也要有度的限制,並不是越多越好;約定一些預設的配置,有助於減少配置檔案的數量。當然,全部使用約定而不支援配置也是不可取的,必然有失靈活性;因此約定優於配置不代表不是用配置,而是一種要同時提供約定和配置兩種方式。

rootAppender約定:
使用log4j列印日誌,需要配置日誌例項得輸出樣式以及目的地等等資訊,不是必須配置的。
log4j約定了一種無須配置的日誌例項的輸出方式,提供了一個基本的控制檯appender,所有建立的日誌例項列印的日誌都會按照這個appender輸出。
只需要在建立日誌例項之前呼叫預設初始化即可:

static {
    BasicConfigurator.configure();
    logger = LogManager.getLogger(Log4jOneTest.class);
} 

控制檯輸出格式如下,不輸出trace級別日誌:

配置檔案路徑的約定:
log4j約定了配置檔案在類路徑種的位置,無需在程式中指定配置檔案路徑,log4j會在其指定的預設類路徑下尋找配置,也就是在classpath得根路徑:
log4j配置檔案路徑

二 配置檔案如何載入

有時約定在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定義配置檔案路徑

一 約定優於配置 約定優於配置(convention over configuration),也稱作按約定程式設計,是一種軟體設計正規化,旨在減少軟體開發人員需做決定的數量,獲得簡單的好處,而又不失靈活性。大量的配置檔案,確實可以讓程式在一定程度上具有很大的

Springboot讀取配置檔案、pom檔案定義配置檔案

前言 很多人都知道讀取配置檔案,這是初級做法,上升一點難度是使用java bean的方式讀取自定義配置檔案,但是大家很少有知道讀取pom檔案資訊,接下來我都會講到。 正文 筆者還是基於Spring Boot ::        (v1.5.8.RE

springboot---讀取定義配置檔案

讀取自定義配置檔案 在有些時候,我們要配置一些資料,地址,路徑等操作,比如,上傳檔案的地址,新老路徑的定義,白名單介面等,這個時候需要在配置檔案裡面進行配置,而不是寫在程式碼裡面,在springboot裡面可以使用註解和實體兩種方式進行獲取到配置檔案裡面的配置資訊,我的做法是建立一個class,

TCP/IP協議學習(二) LWIP使用者定義配置檔案解析

 LWIP協議支援使用者配置,可以通過使用者裁剪實現最優化配置,LWIP預設包含opts.h作為系統預設配置,不過通過新增lwipopts.h檔案幷包含在opts.h標頭檔案之前就可以對lwip進行使用者裁剪,這裡給出相關引數的含義,不過具體專案還應該根據實際情況裁剪。 #ifn

hive定義配置檔案不生效

說明:只有在/opt/hive-0.13.1-cdh5.3.6/conf 目錄下執行/opt/hive-0.13.1-cdh5.3.6/bin/hive命令時才可以連線mysql資料庫。 在/opt/hive-0.13.1-cdh5.3.6 目錄下執行bin/hive命令連線的是預設的der

SpringBoot的定義配置方法一,通過定義配置檔案

  自定義配置的目的:通過自定義屬性,注入到程式中使用,可以靈活的更改配置資訊,修改自定義屬性值,達到修改程式的目的。 一、新建一個SpringBoot工程,目錄結構如下:   其中MyConfig.java檔案內容為:@Component與@ConfigurationPrope

Spring Boot Configuration 配置檔案讀取以及定義配置檔案

新增configuration  maven依賴 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configurati

php 定義配置檔案

info.conf.php //配置檔案 return array( 'name' =>'dana', 'address'=>'hunan' ); // 配置類 config.class.php class Config { protected sta

SpringBoot-配置檔案詳解之定義配置檔案

今天我們一起來學習一下如何自定義配置檔案,在這之前我們可能會把配置項寫在application.properties或者application.yml中。這是springboot預設讀取的配置檔案,但是

spring boot、maven定義配置檔案

在pom.xml中設定<profiles>標籤來指定配置檔案載入路徑 <profiles> <profile> <id>local</id> <

Javaweb讀取定義配置檔案

Java中經常出現自定義的 properties 配置檔案,可以簡化更換引數時的複雜度 第一種方式(可用): ResourceBundle:這個類主要用來解決國際化和本地化問題。 說的簡單點,這個類的作用就是讀取資源屬性檔案(properties),然後根據

SpringBoot定義配置檔案(xxx.properties)

轉載 :https://www.cnblogs.com/V1haoge/p/7183408.htmlSpringBoot中免除了大部分手動配置,但是對於一些特定的情況,還是需要我們進行手動配置的,SpringBoot為我們提供了application.properties配置檔案,讓我們可以進行自定義配置,來

SpringBoot定義配置檔案讀取

SpringBoot自定義配置檔案有兩種讀取方式 如在配置檔案中自定義如下配置 @Value註解讀取自定義配置檔案——用於逐個讀取自定義的配置 新建一個controller類如下: @Controller public class ConfigInfoControll

SpringBoot 之 定義配置檔案及讀取配置檔案application.properties或yml

讀取核心配置檔案核心配置檔案是指在resources根目錄下的application.properties或application.yml配置檔案,讀取這兩個配置檔案的方法有兩種,都比較簡單。 核心配置檔案application.properties內容如下: server.port=9090 test.m

spring boot 新增定義配置檔案並讀取屬性

"123" "pcq" spring 屬性檔案預設配置檔案是從application.properties讀取的, 但是我想把配置檔案分開,比如 業務的我想放在biz.properties, 客戶端配置的放在client.properties , 但是注入呢,經過測試可以這

4.Springboot 之 定義配置檔案及讀取配置檔案

讀取核心配置檔案 核心配置檔案是指在resources根目錄下的application.properties或application.yml配置檔案,讀取這兩個配置檔案的方法有兩種,都比較簡單。 核心配置檔案application.properties內容如下: server.port=9090 tes

SpringBoot之載入定義配置檔案

SpringBoot預設載入配置檔名為:application.properties和application.yml,如果需要使用自定義的配置檔案,則通過@PropertySource註解指定。   JavaBean: package org.springboot.model; imp

SpringBoot載入定義配置檔案

載入預設配置檔案可以直接裝配到類中: 載入自定義properties檔案: 在相應屬性上用@Value("${...}")繫結 還有一種應用場景:將屬性注入到靜態屬性上: 將對應的set方法(非靜態)上打上@Value("${...}")進行繫結. 改造mvc專

SpringBoot之定義配置檔案

1.通過@Value註解使用自定義的配置檔案@Value註解的工作原理(這一切都是在SpringBoot專案啟動時發生的)使用@Value獲取自定義的配置新建一個XX.properties檔案,在其中新增log4j.appender.stdout=org.apache.log

SpringBoot 系列-5 配置檔案定義配置檔案

自定義配置檔案也是放在resources下面 我們拿rabbitMq舉個列子 內容如下: 然後我們新建一個JAVA類 package com.example.demo; import org.springframework.beans.factory.annotatio