log4j.xml引用Javaweb项目中配置文件的参数
2019獨(dú)角獸企業(yè)重金招聘Python工程師標(biāo)準(zhǔn)>>>
由于最近用阿里云日志服務(wù)整合log4j,在配置com.aliyun.openservices.log.log4j.LoghubAppender需要設(shè)置一些參數(shù),因?yàn)轫?xiàng)目中有統(tǒng)一的配置文件,所以想要可以直接在log4j.xml中通過${}來獲取參數(shù),參考下面的配置。
<appender name="AliyunSLS" class="com.aliyun.openservices.log.log4j.LoghubAppender"><param name="projectName" value="${Props.Log4j.AliyunSLS.projectName}"/><!-- 日志服務(wù)的project名,必選參數(shù) --><param name="logstore" value="${Props.Log4j.AliyunSLS.logstore}"/><!-- 日志服務(wù)的logstore名,必選參數(shù) --><param name="endpoint" value="${Props.Log4j.AliyunSLS.endpoint}"/><!-- 日志服務(wù)的http地址,必選參數(shù) --><param name="accessKeyId" value="${Props.Log4j.AliyunSLS.accessKeyId}"/><!-- 用戶身份標(biāo)識,必選參數(shù) --><param name="accessKey" value="${Props.Log4j.AliyunSLS.accessKey}"/><!-- 用戶身份標(biāo)識,必選參數(shù) --><param name="packageTimeoutInMS" value="${Props.Log4j.AliyunSLS.packageTimeoutInMS}"/><!-- 被緩存起來的日志的發(fā)送超時(shí)時(shí)間,如果緩存超時(shí),則會被立即發(fā)送,單位是毫秒,默認(rèn)值為3000,最小值為10,可選參數(shù) --><param name="logsCountPerPackage" value="${Props.Log4j.AliyunSLS.logsCountPerPackage}"/><!-- 每個(gè)緩存的日志包中包含日志數(shù)量的最大值,不能超過 4096,可選參數(shù) --><param name="logsBytesPerPackage" value="${Props.Log4j.AliyunSLS.logsBytesPerPackage}"/><!-- 每個(gè)緩存的日志包的大小的上限,不能超過 3MB,單位是字節(jié),可選參數(shù) --><param name="memPoolSizeInByte" value="${Props.Log4j.AliyunSLS.memPoolSizeInByte}"/><!-- Appender 實(shí)例可以使用的內(nèi)存的上限,單位是字節(jié),默認(rèn)是 100MB,可選參數(shù) --><param name="maxIOThreadSizeInPool" value="${Props.Log4j.AliyunSLS.maxIOThreadSizeInPool}"/><!-- 指定I/O線程池最大線程數(shù)量,主要用于發(fā)送數(shù)據(jù)到日志服務(wù),默認(rèn)是8,可選參數(shù) --><param name="retryTimes" value="${Props.Log4j.AliyunSLS.retryTimes}"/><!-- 指定發(fā)送失敗時(shí)重試的次數(shù),如果超過該值,會把失敗信息通過log4j的LogLog進(jìn)行輸出,默認(rèn)是3,可選參數(shù) --><param name="topic" value="${Props.Log4j.AliyunSLS.topic}"/><!-- 指定日志主題,可選參數(shù) --><!--<param name="source" value="Props.Log4j.AliyunSLS.source"/>--><!-- 指定日志來源,可選參數(shù) --><param name="timeFormat" value="${Props.Log4j.AliyunSLS.timeFormat}"/><!-- 設(shè)置時(shí)間格式,可選參數(shù) --><param name="timeZone" value="${Props.Log4j.AliyunSLS.timeZone}"/><!-- 設(shè)置時(shí)區(qū),可選參數(shù) --><param name="Threshold" value="${Props.Log4j.AliyunSLS.Threshold}"/><!-- 輸出WARN級別及以上的消息 --></appender>log4j.xml中通過${}引用的變量是系統(tǒng)變量,即通過System.getProperty()獲取,顯然這里我們只需要將我們需要的變量設(shè)置到系統(tǒng)變量中即可,第一種方法就是在啟動的時(shí)候指定系統(tǒng)變量,這種方法不方便,每次啟動都要手動輸入變量的值。第二種就是我們只要確保在日志服務(wù)啟動前將參數(shù)設(shè)置到系統(tǒng)變量中就可以了。這里介紹一種通過自定義LoggerFactory的方式來實(shí)現(xiàn)。
通過查看源碼知道,log4j在解析log4j.xml的時(shí)候最先解析的是<loggerFactory/>節(jié)點(diǎn),該節(jié)點(diǎn)代表的是日志生成工廠接口org.apache.log4j.spi.LoggerFactory,代碼如下:
package org.apache.log4j.spi;import org.apache.log4j.Logger;public interface LoggerFactory {Logger makeNewLoggerInstance(String var1); }默認(rèn)情況下,log4j會加載LoggerFactory的默認(rèn)實(shí)現(xiàn)類org.apache.log4j.DefaultCategoryFactory,代碼如下:
package org.apache.log4j;import org.apache.log4j.spi.LoggerFactory;class DefaultCategoryFactory implements LoggerFactory {DefaultCategoryFactory() {}public Logger makeNewLoggerInstance(String name) {return new Logger(name);} }DefaultCategoryFactory.makeNewLoggerInstance(name)直接生成Logger,需要注意的是Logger的構(gòu)造方法是受保護(hù)的,也就是我們沒辦法在其他包中通過new?Logger(name)來生成一個(gè)Logger實(shí)例,代碼如下:
public class Logger extends Category {private static final String FQCN;protected Logger(String name) {super(name);}... }由源碼可以看出,LoggerFactory的實(shí)現(xiàn)非常簡單,接下來看一下如何實(shí)現(xiàn)。
?
1、由于Logger的構(gòu)造方法是受保護(hù)的,所以我們只要通過自定義Logger子類,就可以使用Logger的功能了
public class Log4jLogger extends Logger {public Log4jLogger(String name) {super(name);} }2、實(shí)現(xiàn)LoggerFactory接口
public class Log4jLoggerFactory implements LoggerFactory {private static final String LOG4J_PROPERTY_PREFIX_KEY = "log4jPropertyPrefix";//默認(rèn)以Props.Log4j.開頭的參數(shù)加載到系統(tǒng)變量中private static final String DEFAULT_LOG4J_PROPERTY_PREFIX = "Props.Log4j.";static {loadLog4jPropsToSystem();}//加載參數(shù)到系統(tǒng)變量中//PropertiesUtils由系統(tǒng)自定義的獲取配置文件的工具類,根據(jù)自己的需要自行實(shí)現(xiàn)private static void loadLog4jPropsToSystem() {//如果配置了log4jPropertyPrefix,則以該參數(shù)作為參數(shù)開頭標(biāo)識String prefixsParam = PropertiesUtils.getStringValue(LOG4J_PROPERTY_PREFIX_KEY);String[] prefixs = null;if (StringUtil.isNotBlank(prefixsParam)) {prefixs = prefixsParam.split(",");} else {prefixs = new String[] {DEFAULT_LOG4J_PROPERTY_PREFIX};}//獲取所有系統(tǒng)配置文件信息Map<Object, Object> allProperties = PropertiesUtils.getAllProperties();if (allProperties != null && !allProperties.isEmpty()) {for (Map.Entry<Object, Object> e : allProperties.entrySet()) {String key = e.getKey().toString();for (String pf : prefixs) {if (key.startsWith(pf)) {System.setProperty(key, e.getValue().toString());System.out.println("Set log4j property[" + key + "=" + e.getValue().toString() + "] into System. ");break;}}}}}@Overridepublic Logger makeNewLoggerInstance(String name) {return new Log4jLogger(name);}}3、在log4j.xml中配置自定義LoggerFactory,<loggerFactory/>配置在最前面
<log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/'><!-- 自定義log4j日志生成工廠,可以加載配置文件中參數(shù)設(shè)置到系統(tǒng)參數(shù)中,默認(rèn)加載以Props.Log4j.開頭的參數(shù),可以通過log4jPropertyPrefix配置加載哪些參數(shù),有多個(gè)的話用逗號分隔 --><loggerFactory class="自己的包路徑.Log4jLoggerFactory"/>... </log4j:configuration>到這里就完畢了,配置文件中的參數(shù)就可以給log4j.xml使用了。
轉(zhuǎn)載于:https://my.oschina.net/linchuhao23/blog/2248889
總結(jié)
以上是生活随笔為你收集整理的log4j.xml引用Javaweb项目中配置文件的参数的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [react] 状态管理器解决了什么问题
- 下一篇: Java之泛型T T与T的用法