Java 項目中少不了要和log4j等日志架構打交道, 開發環境和生産環境下日志檔案的輸出路徑總是不一緻, 本文借鑒 Tomcat 的配置方式 “${catalina.home}/logs/catalina.out”, 通過相對路徑的方式設定日志的輸出路徑, 有其他解決方案的小夥伴, 請直接評論區交流呀😄
目錄
- 1 日志路徑帶來的痛點
- 2 log4j.properties檔案的配置
- 3 徹底解決痛點
- 3.1 單獨的Java程式包 (非Java Web項目)
- 3.2 Web項目
- 4 附錄 - 擷取目前項目、類路徑的幾種方式
- 參考資料
- 版權聲明
Java 項目中少不了要和log4j等日志架構打交道, 開發環境和生産環境下日志檔案的輸出路徑總是不一緻, 設定為絕對路徑的方式缺少了靈活性, 每次變更項目路徑都要修改檔案, 目前想到的最佳實作方式是: 根據項目位置自動加載并配置檔案路徑.
本文借鑒 Tomcat 的配置方式 “${catalina.home}/logs/catalina.out”, 通過相對路徑的方式設定日志的輸出路徑, 有其他解決方案的小夥伴, 請直接評論區交流哦😯
# 設定要輸出的日志的級别 - 注意: properties檔案中的注釋資訊隻能處于行首, 不要跟在行尾
log4j.rootLogger=INFO,stdout,logfile
### 輸出到控制台, Java程式運作時的标準輸出資訊
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
# 2019-05-25 19:09:46
log4j.appender.stdout.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss} [%t] [%c] [%p] - %m%n
### 輸出到日志檔案
# 按天滾動生成, 不支援MaxFileSize, 而RollingFileAppender支援
log4j.appender.logfile=org.apache.log4j.DailyRollingFileAppender
# 項目的logs目錄下
# log4j.appender.logfile.File=${base.dir}/logs/elastic-server.log
log4j.appender.logfile.Append=true
# 輸出INFO及以上的日志, 按日期滾動就無須配置單個日志檔案的最大體積了
log4j.appender.logfile.Threshold=INFO
# log4j.appender.logfile.MaxFileSize=100MB
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss} [%t] [%c] [%p] - %m%n
單獨的Java程式包, 需要通過指令
java -jar
或
java -cp
的方式啟動;
我們可以在啟動指令中加入系統運作時變量, 在log4j加載配置檔案之前通過
System.getProperties("path")
讀取此變量, 即可實作靈活加載目前路徑.
(1) 啟動腳本設定:
假設目前項目的目錄結構為:
/Projects/KafkaConsumer
丨 bin 項目的啟動腳本
丨 conf 項目的配置檔案
丨 lib 項目的其他依賴包
丨 bogs 項目的日志輸出路徑
啟動腳本位于bin目錄下, 内容示例如下:
# 擷取目前腳本所處的目錄, 然後進入其上級目錄, 最後pwd輸出該目錄, 最終的結果是/Project/KafkaConsumer
base_dir=$(cd `dirname $0`; cd ..; pwd)
# 擷取Java運作程式的位置, 并指定主類
java_bin=$(which java)
main_class="org.shoufeng.elastic.ConsumerMain"
# 通過-cp、擴充CLASSPATH、指定主類的方式啟動項目,
# 并通過“-D”的方式向此程式的運作時環境中設定目前項目的路徑,
# 即可在程式中通過System.getProperty("base.dir")擷取此路徑
nohup ${java_bin} -Dbase.dir=${base_dir} -cp ${CLASSPATH}:${base_dir}/conf:${base_dir}/lib/* ${main_class} >> /dev/null &
(2) Java程式讀取變量:
實log4j的FileAppender本身支援動态設定檔案路徑, 如:
log4j.appender.logfile.File=${base.log}/logs/app.log
其中“${base.log}”是一個變量, 會被
System Property
中的
base.log
的值代替, 代碼中的使用方式為:
public static void main(String[] args) {
// 擷取系統運作時變量中的日志檔案的輸出路徑
// 此變量需要在啟動指令中通過-D的方式設定
String baseDir = System.getProperty("base.dir");
if (baseDir == null) {
// 開發環境中使用
baseDir = System.getProperty("user.dir");
System.setProperty("base.dir", baseDir);
}
log.info("==== 系統運作路徑: " + System.getProperty("base.dir") + " ====");
// 其他處理邏輯......
}
需要注意的是, 這種方式設定的環境變量隻在目前Java程序(也就是目前項目)中有效, 并不會影響到其他項目.
如果是Web項目, 可通過修改Web容器的環境變量方式實作. 以 Tomcat 為例:
# log4j的配置檔案支援伺服器的vm環境變量, 格式類似${catalina.home}
log4j.appender.R=org.apache.log4j.RollingFileAppender
log4j.appender.R.File=${catalina.home}/logs/logs_tomcat.log
log4j.appender.R.MaxFileSize=100MB
${catalina.home}
是在
${tomcat_home}/bin/catalina.sh
中通過-D參數設定的:
-Dcatalina.home="$CATALINA_HOME"
基于這個思路, 我們也可以向Web容器的VM參數中設定一個參數, 比如
-Dmylog.home="/Project/logs"
, 建立日志對象時即可使用.
public static void main(String[] args) {
// 擷取 class 檔案的絕對路徑, 定位到具體的包名, 結果如:
// /Projects/KafkaConsumer/target/classes/org/shoufeng/consumer/
System.out.println(KafkaConsumer.class.getResource(""));
// 擷取 class 檔案的絕對路徑, 如: /Projects/KafkaConsumer/target/classes/,
// 如果在bin目錄下通過java -jar等指令啟動時, 結果就是 /Projects/KafkaConsumer/bin/
System.out.println(ClassLoader.getSystemResource(""));
System.out.println(KafkaConsumer.class.getResource("/"));
System.out.println(KafkaConsumer.class.getClassLoader().getResource(""));
System.out.println(Thread.currentThread().getContextClassLoader().getResource(""));
// 說明: 上述4種用法的傳回結果類型都是URL, 其toString()傳回的内容以"file:"開頭, 可通過“.toString().substring(5)”去除
// 推薦: 使用“.getPath()”就可以直接擷取到路徑
// 擷取工程的絕對路徑, 如: /Projects/KafkaConsumer,
// 若在bin中通過java -jar等指令啟動, 路徑就變成了: /Projects/KafkaConsumer/bin
System.out.println(System.getProperty("user.dir"));
}
log4j 産生的日志位置設定 和 catalina.home、catalina.base
作者: 瘦風(https://healchow.com)
出處: 部落格園 瘦風的部落格(https://www.cnblogs.com/shoufeng)
感謝閱讀, 如果文章有幫助或啟發到你, 點個[好文要頂👆] 或 [推薦👍] 吧😜
本文版權歸部落客所有, 歡迎轉載, 但 [必須在文章頁面明顯位置标明原文連結], 否則部落客保留追究相關人員法律責任的權利.