Java 配置log4j日志文件路徑 (附-獲取當(dāng)前類路徑的多種操作)
Java 項(xiàng)目中少不了要和log4j等日志框架打交道, 開發(fā)環(huán)境和生產(chǎn)環(huán)境下日志文件的輸出路徑總是不一致, 設(shè)置為絕對(duì)路徑的方式缺少了靈活性, 每次變更項(xiàng)目路徑都要修改文件, 目前想到的最佳實(shí)現(xiàn)方式是: 根據(jù)項(xiàng)目位置自動(dòng)加載并配置文件路徑.
本文借鑒 Tomcat 的配置方式 “${catalina.home}/logs/catalina.out”, 通過相對(duì)路徑的方式設(shè)置日志的輸出路徑, 有其他解決方案的小伙伴, 請(qǐng)直接評(píng)論區(qū)交流哦😯
2 log4j.properties文件的配置# 設(shè)置要輸出的日志的級(jí)別 - 注意: properties文件中的注釋信息只能處于行首, 不要跟在行尾log4j.rootLogger=INFO,stdout,logfile### 輸出到控制臺(tái), Java程序運(yùn)行時(shí)的標(biāo)準(zhǔn)輸出信息log4j.appender.stdout=org.apache.log4j.ConsoleAppenderlog4j.appender.stdout.Target=System.outlog4j.appender.stdout.layout=org.apache.log4j.PatternLayout# 2019-05-25 19:09:46log4j.appender.stdout.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss} [%t] [%c] [%p] - %m%n### 輸出到日志文件# 按天滾動(dòng)生成, 不支持MaxFileSize, 而RollingFileAppender支持log4j.appender.logfile=org.apache.log4j.DailyRollingFileAppender# 項(xiàng)目的logs目錄下# log4j.appender.logfile.File=${base.dir}/logs/elastic-server.loglog4j.appender.logfile.Append=true# 輸出INFO及以上的日志, 按日期滾動(dòng)就無須配置單個(gè)日志文件的最大體積了log4j.appender.logfile.Threshold=INFO# log4j.appender.logfile.MaxFileSize=100MBlog4j.appender.logfile.layout=org.apache.log4j.PatternLayoutlog4j.appender.logfile.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss} [%t] [%c] [%p] - %m%n3 徹底解決痛點(diǎn)
3.1 單獨(dú)的Java程序包 (非Java Web項(xiàng)目)
單獨(dú)的Java程序包, 需要通過命令java -jar或java -cp的方式啟動(dòng);
我們可以在啟動(dòng)命令中加入系統(tǒng)運(yùn)行時(shí)變量, 在log4j加載配置文件之前通過System.getProperties('path')讀取此變量, 即可實(shí)現(xiàn)靈活加載當(dāng)前路徑.
(1) 啟動(dòng)腳本設(shè)置:
假設(shè)當(dāng)前項(xiàng)目的目錄結(jié)構(gòu)為:
/Projects/KafkaConsumer丨 bin 項(xiàng)目的啟動(dòng)腳本丨 conf 項(xiàng)目的配置文件丨 lib 項(xiàng)目的其他依賴包丨 bogs 項(xiàng)目的日志輸出路徑
啟動(dòng)腳本位于bin目錄下, 內(nèi)容示例如下:
# 獲取當(dāng)前腳本所處的目錄, 然后進(jìn)入其上級(jí)目錄, 最后pwd輸出該目錄, 最終的結(jié)果是/Project/KafkaConsumerbase_dir=$(cd `dirname $0`; cd ..; pwd)# 獲取Java運(yùn)行程序的位置, 并指定主類java_bin=$(which java)main_class='org.shoufeng.elastic.ConsumerMain'# 通過-cp、擴(kuò)展CLASSPATH、指定主類的方式啟動(dòng)項(xiàng)目, # 并通過“-D”的方式向此程序的運(yùn)行時(shí)環(huán)境中設(shè)置當(dāng)前項(xiàng)目的路徑,# 即可在程序中通過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程序讀取變量:
實(shí)log4j的FileAppender本身支持動(dòng)態(tài)設(shè)置文件路徑, 如:
log4j.appender.logfile.File=${base.log}/logs/app.log
其中“${base.log}”是一個(gè)變量, 會(huì)被System Property中的base.log的值代替, 代碼中的使用方式為:
public static void main(String[] args) { // 獲取系統(tǒng)運(yùn)行時(shí)變量中的日志文件的輸出路徑 // 此變量需要在啟動(dòng)命令中通過-D的方式設(shè)置 String baseDir = System.getProperty('base.dir'); if (baseDir == null) { // 開發(fā)環(huán)境中使用 baseDir = System.getProperty('user.dir'); System.setProperty('base.dir', baseDir); } log.info('==== 系統(tǒng)運(yùn)行路徑: ' + System.getProperty('base.dir') + ' ===='); // 其他處理邏輯......}
需要注意的是, 這種方式設(shè)置的環(huán)境變量只在當(dāng)前Java進(jìn)程(也就是當(dāng)前項(xiàng)目)中有效, 并不會(huì)影響到其他項(xiàng)目.
3.2 Web項(xiàng)目
如果是Web項(xiàng)目, 可通過修改Web容器的環(huán)境變量方式實(shí)現(xiàn). 以 Tomcat 為例:
# log4j的配置文件支持服務(wù)器的vm環(huán)境變量, 格式類似${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參數(shù)設(shè)置的:
-Dcatalina.home='$CATALINA_HOME'
基于這個(gè)思路, 我們也可以向Web容器的VM參數(shù)中設(shè)置一個(gè)參數(shù), 比如-Dmylog.home='/Project/logs', 創(chuàng)建日志對(duì)象時(shí)即可使用.
4 附錄 - 獲取當(dāng)前項(xiàng)目、類路徑的幾種方式public static void main(String[] args) { // 獲取 class 文件的絕對(duì)路徑, 定位到具體的包名, 結(jié)果如: // /Projects/KafkaConsumer/target/classes/org/shoufeng/consumer/ System.out.println(KafkaConsumer.class.getResource('')); // 獲取 class 文件的絕對(duì)路徑, 如: /Projects/KafkaConsumer/target/classes/, // 如果在bin目錄下通過java -jar等命令啟動(dòng)時(shí), 結(jié)果就是 /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種用法的返回結(jié)果類型都是URL, 其toString()返回的內(nèi)容以'file:'開頭, 可通過“.toString().substring(5)”去除 // 推薦: 使用“.getPath()”就可以直接獲取到路徑 // 獲取工程的絕對(duì)路徑, 如: /Projects/KafkaConsumer, // 若在bin中通過java -jar等命令啟動(dòng), 路徑就變成了: /Projects/KafkaConsumer/bin System.out.println(System.getProperty('user.dir'));}
補(bǔ)充知識(shí):在web中使用log4j時(shí),配置日志文件的存放位置
廢話不多說,直接上代碼。
log4j.properties配置如下
log4j.rootLogger = info,out1,out2log4j.appender.out1=org.apache.log4j.FileAppenderlog4j.appender.out1.File=test.loglog4j.appender.out1.layout=org.apache.log4j.PatternLayoutlog4j.appender.out1.layout.ConversionPattern=%d %-5p - %m at %l%nlog4j.appender.out2=org.apache.log4j.ConsoleAppenderlog4j.appender.out2.layout=org.apache.log4j.PatternLayoutlog4j.appender.out2.layout.ConversionPattern=%d %-5p - %m at %l%n
問題一:這個(gè)test.log文件會(huì)存放在哪呢?
經(jīng)測(cè)試發(fā)現(xiàn),test.log這個(gè)相對(duì)路徑相對(duì)的是user.dir系統(tǒng)參數(shù)的值。
假如我的tomcat的安裝路徑為D:apache-tomcat-6.0.16,則user.dir=D:apache-tomcat-6.0.16bin,當(dāng)不確定時(shí),我們可以用System.getProperties()將所有的系統(tǒng)參數(shù)在jsp中打印出來。
問題二:
如果我們將test.log改為絕對(duì)路徑/test.log,這個(gè)test.log文件又會(huì)存放在哪呢?
經(jīng)測(cè)試發(fā)現(xiàn),/test.log這個(gè)絕對(duì)路徑的根路徑是user.dir系統(tǒng)參數(shù)的根路徑,即test.log會(huì)存放在D:test.log。
補(bǔ)充:
我們?cè)趌og4j.properties文件中還可以通過${系統(tǒng)參數(shù)}的方式來指明日志文件存放路徑。
如
log4j.appender.out1.File=${user.dir}/logs/test.log
以上這篇Java 配置log4j日志文件路徑 (附-獲取當(dāng)前類路徑的多種操作)就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持好吧啦網(wǎng)。
相關(guān)文章:
1. 基于javaweb+jsp實(shí)現(xiàn)學(xué)生宿舍管理系統(tǒng)2. 如何封裝一個(gè)Ajax函數(shù)3. ASP.NET MVC實(shí)現(xiàn)樹形導(dǎo)航菜單4. 多級(jí)聯(lián)動(dòng)下拉選擇框,動(dòng)態(tài)獲取下一級(jí)5. jsp網(wǎng)頁實(shí)現(xiàn)貪吃蛇小游戲6. Ajax常用封裝庫——Axios的使用7. jsp+servlet簡(jiǎn)單實(shí)現(xiàn)上傳文件功能(保存目錄改進(jìn))8. CSS Hack大全-教你如何區(qū)分出IE6-IE10、FireFox、Chrome、Opera9. 怎樣打開XML文件?xml文件如何打開?10. Python數(shù)據(jù)分析JupyterNotebook3魔法命令詳解及示例
