解决log4j不能按天生成日志问题

内容纲要

原文参考 http://blog.csdn.net/buoll/article/details/17389827

最近被LOG4J:ERROR Failed to rename折腾得差点放弃使用log4j了。
想象:log4j 不能按日生成新的日志文件,直接把原来的给覆盖了。

经过跟踪调试,问题出现在
DailyRollingFileAppender.Java

[java] view plain copy 在CODE上查看代码片派生到我的代码片

  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. }  

 

"Failed to rename ... "

renameTo失败很明显就是日志文件被占用,但是日志文件会被哪些线程占用?
在网上找了半天,终于发现
罪魁祸首竟然是

tomcat 的 server.xml中配置了

[html] view plain copy 在CODE上查看代码片派生到我的代码片

  1. <Context path="" docBase="xxxx" debug="0" reloadable="true"/>  

 

导致日志文件一直被占用,只有在停止tomcat时才被释放
。。。。。。。。。。。。。。。。。。。。。。。。 晕倒 。。。。。。。。。。。。。。

知道问题出现在哪就好解决了,当然是不要在server.xml中配置<Context path="" docBase="xxxx" debug="0" reloadable="true"/>

去掉该配置后,服务器的首页默认就在  webapps\ROOT\  
如果想让自己的项目变成默认首页,那只能在ROOT\ 下增加一个自己项目的首页的文件了。

如果我一定要 在server.xml中配置<Context path="" docBase="xxxx" debug="0" reloadable="true"/>
还有没有其他的解决办法?
那就只能修改log4j-1.2.xx.jar的 DailyRollingFileAppender文件,网上提供的方法都是将 renameTO 改成copy
具体做法是:
将DailyRollingFileAppender.java的

[java] view plain copy 在CODE上查看代码片派生到我的代码片

  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. }  

 

改为:

[java] view plain copy 在CODE上查看代码片派生到我的代码片

  1. File file = new File(fileName);    

  2. boolean result = copy(file, target);    

  3. if (result) {    

  4.  //网上很多地方只是简单的做复制操作,这样将导致日志文件越来越大。所以,这里应该增加清空日志的方法,在复制成功后,清空原来的日志  

  5.     FileWriter fw =  new FileWriter(file);    

  6.     fw.write("");    

  7.     fw.flush();    

  8.     fw.close();    

  9.     LogLog.debug(fileName + " -> " + scheduledFilename);    

  10. else {    

  11.     LogLog.error("Failed to rename [" + fileName + "] to ["    

  12.             + scheduledFilename + "].");    

  13. }  

 

并且增加copy方法

[java] view plain copy 在CODE上查看代码片派生到我的代码片

  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. }  

 

发表回复