引起log4j:ERROR Failed to rename的原因
根据Log4J的配置文件,使用LOG4J的DailyRollingFileAppender.java实现每隔一段时间记录一次日志文件,但LOG4J在对原文件改名时,总是提示log4j:ERROR Failed to rename的错误,究其原因,主要是还有进程在使用原来的LOG文件,而通过分析LOG4J的源码,发现LOG4J是采用RENAME的方式对原来的LOG文件改名再生成新文件。
引起log4j:ERROR Failed to rename的条件
通常都是在配置文件采用Java代码 
log4j.appender.A1=org.apache.log4j.DailyRollingFileAppender
或者  
log4j.appender.A1=org.apache.log4j.RollingFileAppender
的情况下遇到"异常"提示。
和异常相关的log4j源代码
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类的renameTo方法的作用是:“改名或者移动文件作用;在同一个目录下renameTo是改名,在不同目录下是移动”,所以在对一个被其他线程所锁定的文件进行改名时,肯定是会报错的。
解决办法
修改log4j的源代码, 将 
boolean result = file.renameTo(target);
改为
boolean result = copy(file, target);
然后再添加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;   
    }
}
附件:DailyRollingFileAppender.zip
	posted on 2011-11-10 11:48 
飞翔天使 阅读(8694) 
评论(1)  编辑  收藏  所属分类: 
log4j