log4j錯誤信息:log4j:ERROR Failed to rename [D:/logs/wmts_] to [D:/logs/wmts_2015-12-21.log ].
起因:部門網站使用B/S架構請求,請求過程中需要將日志文件記錄下來,以便出現問題進行查找,剛開始服務器上的日志文件能夠正常輸出,后來日志文件不能輸出,部門領導讓我查找原因並修改。
介紹:本人JAVA小白一枚,之前是學.Net出身,來到公司之后由於公司需要才轉的JAVA,日志輸出做的比較少所以部門經理剛交給我的時候心里還是小忐忑的。
目的:使用log4j的DailyRollingFileAppender每天生成一個日志文件,並在生成的日志文件之后添加日期作為標識,如wmts_2015-12-21.log。
試驗期:
1、(小白入門)
log4j.properties配置如下
1 log4j.appender.Info = org.apache.log4j.DailyRollingFileAppender 2 log4j.appender.Info.File = ${log4j.log.dir}/wmts_ 3 log4j.appender.Info.DatePattern = yyyy-MM-dd'.log' 4 log4j.appender.Info.Append = false 5 log4j.appender.Info.Threshold = INFO 6 log4j.appender.Info.layout = org.apache.log4j.PatternLayout 7 log4j.appender.Info.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %c:%r ] - [ %p ] %m%n
原以為每次請求都會生成類似“wmts_2015-12-21.log”的文件,后來才知道當天的日志會先創建在“wmts_”文件中,第二天才會以前一天的日期生成日志文件。
但是經過多次的試驗,一直沒有生成正確命名的日志文件。
2、(C/S嘗試)
(1)鑒於上面的試驗一直沒有成功,本人想到可能是本人的修煉還不夠,一上手就用成型的項目可能有些問題不好發現,所以本人寫了最簡單的C/S的Demo來跟蹤日志的生成。
log4j.properties的配置如下:
1 log4j.appender.R1=org.apache.log4j.RollingFileAppender 2 log4j.appender.R1.file=C:/demo.log 3 log4j.appender.R1.layout=org.apache.log4j.PatternLayout 4 log4j.appender.R1.layout.conversionPattern=%d %c (%M:%L) - %m%n
生成日志文件正常。
(2)更改log4j.properties為項目的配置:
1 log4j.appender.Info = org.apache.log4j.DailyRollingFileAppender 2 log4j.appender.Info.File = ${log4j.log.dir}/wmts_ 3 log4j.appender.Info.DatePattern = yyyy-MM-dd'.log' 4 log4j.appender.Info.Append = true 5 log4j.appender.Info.Threshold = INFO 6 log4j.appender.Info.layout = org.apache.log4j.PatternLayout 7 log4j.appender.Info.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss} [ %c:%r ] - [ %p ] %m%n
再次生成日志文件,此時eclipse的console輸出了錯誤代碼log4j:ERROR Failed to rename [D:/logs/wmts_] to [D:/logs/wmts_2015-12-21.log ].
這個錯誤提示幫我最后解決了問題。
3、問題解決
引起log4j:ERROR Failed to rename的條件
通常都是在配置文件采用
1 log4j.appender.A1=org.apache.log4j.DailyRollingFileAppender
或者
1 log4j.appender.A1=org.apache.log4j.RollingFileAppender
的情況下遇到"異常"提示。
原因:
1 File file = new File(fileName); 2 boolean result = file.renameTo(target); 3 if(result) { 4 LogLog.debug(fileName +" -> "+ scheduledFilename); 5 } else { 6 LogLog.error("Failed to rename ["+fileName+"] to ["+scheduledFilename+"]."); 7 }
源代碼中使用renameTo將前一天的文件重命名為log4j.properties配置的文件名,但是有的時候該文件會被占用,導致無法進行重命名,才會報上一步的錯誤。
大神們的解決辦法:在log4j中添加一個copy方法,在重命名前一天的日志文件時,將原文件拷貝一份,將拷貝的原文件命名為想要的文件名,來解決該問題。
copy方法的代碼如下:
1 /** 2 * Copies src file to dst file. If the dst file does not exist, it is 3 * created.8KB cache 4 * 5 * @param src 6 * @param dst 7 * @throws IOException 8 */ 9 boolean copy(File src, File dst) throws IOException { 10 try { 11 InputStream in = new FileInputStream(src); 12 13 OutputStream out = new FileOutputStream(dst); 14 15 // Transfer bytes from in to out 16 byte[] buf = new byte[8192]; 17 int len; 18 while ((len = in.read(buf)) > 0) { 19 out.write(buf, 0, len); 20 } 21 in.close(); 22 out.close(); 23 return true; 24 } catch (FileNotFoundException e) { 25 LogLog.error("源文件不存在,或者目標文件無法被識別." ); 26 return false; 27 } catch (IOException e) { 28 LogLog.error("文件讀寫錯誤."); 29 return false; 30 } 31 }
4、心得
問題解決之后回想之前的解決過程,刪除每次的日志文件的時候系統提示文件正在占用,停止eclipse的server之后才能刪除文件,當時如果認真思考這個問題可能就會發現日志輸出不正常的問題。於此給我敲響了警鍾,要多思考一些系統給出的提示信息。
附上打包好的log4j-1.2.15.jar文件
http://files.cnblogs.com/files/giser-liang/log4j-1.2.15.zip