最近被LOG4J:ERROR Failed to rename折腾得差点放弃使用log4j了。
出现的状况:log4j 不能按日生成新的日志文件,每次生成的时候都会报该错误

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

File file = new File(fileName);
boolean result = file.renameTo(target);
if (result) {
 LogLog.debug(fileName + " -> " + scheduledFilename);
} else {
 LogLog.error("Failed to rename [" + fileName + "] to [" + scheduledFilename + "].");
}
 

"Failed to rename ... "

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

tomcat 的 server.xml中配置了

<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的

 

File file = new File(fileName);
boolean result = file.renameTo(target);
if (result) {
 LogLog.debug(fileName + " -> " + scheduledFilename);
} else {
 LogLog.error("Failed to rename [" + fileName + "] to [" + scheduledFilename + "].");
}

改为:

File file = new File(fileName);  
boolean result = copy(file, target);  
if (result) {  
 //网上很多地方只是简单的做复制操作,这样将导致日志文件越来越大。所以,这里应该增加清空日志的方法,在复制成功后,清空原来的日志
    FileWriter fw =  new FileWriter(file);  
    fw.write("");  
    fw.flush();  
    fw.close();  
    LogLog.debug(fileName + " -> " + scheduledFilename);  
} else {  
    LogLog.error("Failed to rename [" + fileName + "] to ["  
            + scheduledFilename + "].");  
}

并且增加copy方法:

/**
 * Copies src file to dst file. If the dst file does not exist, it is
 * created.8KB cache
 * 
 * @param src
 * @param dst
 * @throws IOException
 */
boolean copy(File src, File dst) throws IOException {
 try {
  InputStream in = new FileInputStream(src);
 
  OutputStream out = new FileOutputStream(dst);
 
  // Transfer bytes from in to out
  byte[] buf = new byte[8192];
  int len;
  while ((len = in.read(buf)) > 0) {
   out.write(buf, 0, len);
  }
  in.close();
  out.close();
  return true;
 } catch (FileNotFoundException e) {
  LogLog.error("源文件不存在,或者目标文件无法被识别." );
  return false;
 } catch (IOException e) {
  LogLog.error("文件读写错误.");
  return false;
 }
}
 

代码参考:
http://duanni.iteye.com/blog/177271
http://redsky008.iteye.com/blog/1401765

这里提供修改好的jar,小伙伴可以直接下载,不用自己再改了。

log4j1.2.15修改版 欢迎下载

帖子状态

话题参与者

回复显示排序:

给大家安利一款免费的在线流程图设计软件:贼好用 ProcessFlow — 免费在线作图、实时协作 ProcessFlow是一个在线作图工具的聚合平台, 它可以在线画流程图、思维导图、UI原型图、UML、网络拓扑图、组织结构图等等, 您无需担心下载和更新的问题, 不管Mac还是Windows,一个浏览器就可以随时随地的发挥创意,规划工作,解放您的双手,让您腾出双手去成就别人的梦想。

Finally!
有没有特别的设计建议或更新的指南?
Finally!
您好,这边没有的。
tesla02 best answer
6 Jan,2019
Finally!
有没有特别的设计建议或更新的指南?
此帖子已被版主标记,收到太多否决票。

这是太大的预览图像,它应该更小,甚至五行。在一个页面上有30到60个页面,它是1800个项目 类别例如在附加组件类别有22749个项目,为什么不看到所有的项目,但只有那1800个项目?这是件坏事。

看起来您是个新人,欢迎免费注册社区,加入我们的大家庭,一起学习,一起成长。
提交你的评论
System.out.println("请输入你的代码块...");
话题
分类
喜欢
回复
浏览
活跃
原创社区
985
0
1.5k
原创社区
985
1
1.5k
20/12/25 22:32:21
javaWeb
985
1
1.5k
20/06/15 22:09:21
youtube
698
78
2.1k
3d
Settings

请插入代码块