Tomcat6下配置log4j
log4j配置到tomcat6可以看这里, tomcat6下配置log4j
引起log4j:ERROR Failed to rename的原因
引起log4j:ERROR Failed to rename的原因大致为
引起log4j:ERROR Failed to rename的条件
通常都是在配置文件采用
和异常相关的log4j源代码
查看log4j的源代码,和 log4j:ERROR Failed to rename异常相关的代码为
重点在这里
解决办法
解决办法为修改log4j的源代码, 修改
为
然后再添加copy()方法.
log4j配置到tomcat6可以看这里, tomcat6下配置log4j
引起log4j:ERROR Failed to rename的原因
引起log4j:ERROR Failed to rename的原因大致为
引起log4j:ERROR Failed to rename的条件
通常都是在配置文件采用
log4j.appender.A1=org.apache.log4j.DailyRollingFileAppender
或者
log4j.appender.A1=org.apache.log4j.RollingFileAppender
的情况下遇到"异常"提示.
和异常相关的log4j源代码
查看log4j的源代码,和 log4j:ERROR Failed to rename异常相关的代码为
- Rollover the current file to a new file.
- */
- void rollOver() throws IOException {
- /* Compute filename, but only if datePattern is specified */
- if (datePattern == null) {
- errorHandler.error("Missing DatePattern option in rollOver().");
- return;
- }
- String datedFilename = fileName+sdf.format(now);
- // It is too early to roll over because we are still within the
- // bounds of the current interval. Rollover will occur once the
- // next interval is reached.
- if (scheduledFilename.equals(datedFilename)) {
- return;
- }
- // close current file, and rename it to datedFilename
- this.closeFile();
- File target = new File(scheduledFilename);
- if (target.exists()) {
- target.delete();
- }
- 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+"].");
- }
- try {
- // This will also close the file. This is OK since multiple
- // close operations are safe.
- this.setFile(fileName, false, this.bufferedIO, this.bufferSize);
- }
- catch(IOException e) {
- errorHandler.error("setFile("+fileName+", false) call failed.");
- }
- scheduledFilename = datedFilename;
- }
- /**
- * This method differentiates DailyRollingFileAppender from its
- * super class.
- *
- * <p>Before actually logging, this method will check whether it is
- * time to do a rollover. If it is, it will schedule the next
- * rollover time and then rollover.
- * */
- protected void subAppend(LoggingEvent event) {
- long n = System.currentTimeMillis();
- if (n >= nextCheck) {
- now.setTime(n);
- nextCheck = rc.getNextCheckMillis(now);
- try {
- rollOver();
- }
- catch(IOException ioe) {
- LogLog.error("rollOver() failed.", ioe);
- }
- }
- super.subAppend(event);
- }
- }
/**
Rollover the current file to a new file.
*/
void rollOver() throws IOException {
/* Compute filename, but only if datePattern is specified */
if (datePattern == null) {
errorHandler.error("Missing DatePattern option in rollOver().");
return;
}
String datedFilename = fileName+sdf.format(now);
// It is too early to roll over because we are still within the
// bounds of the current interval. Rollover will occur once the
// next interval is reached.
if (scheduledFilename.equals(datedFilename)) {
return;
}
// close current file, and rename it to datedFilename
this.closeFile();
File target = new File(scheduledFilename);
if (target.exists()) {
target.delete();
}
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+"].");
}
try {
// This will also close the file. This is OK since multiple
// close operations are safe.
this.setFile(fileName, false, this.bufferedIO, this.bufferSize);
}
catch(IOException e) {
errorHandler.error("setFile("+fileName+", false) call failed.");
}
scheduledFilename = datedFilename;
}
/**
* This method differentiates DailyRollingFileAppender from its
* super class.
*
* <p>Before actually logging, this method will check whether it is
* time to do a rollover. If it is, it will schedule the next
* rollover time and then rollover.
* */
protected void subAppend(LoggingEvent event) {
long n = System.currentTimeMillis();
if (n >= nextCheck) {
now.setTime(n);
nextCheck = rc.getNextCheckMillis(now);
try {
rollOver();
}
catch(IOException ioe) {
LogLog.error("rollOver() failed.", ioe);
}
}
super.subAppend(event);
}
}
重点在这里
- 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 = file.renameTo(target);
if(result) {
LogLog.debug(fileName +" -> "+ scheduledFilename);
} else {
LogLog.error("Failed to rename ["+fileName+"] to ["+scheduledFilename+"].");
}
解决办法
解决办法为修改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;
- }
- }
/**
* 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;
}
}
此方法借鉴自 File Copy in Java 和 Java File Copy
后面的话
修改后的代码可以正常运行在tomcat6下, log文件替换正常. 没有高负载和集群环境下测试. 如有问题,还请大家积极反馈. 如果你有更好的办法请告诉我.
附件 : 包括修改后的org.apache.log4j.DailyRollingFileAppender类的源代码和已编译好的文件.
请用DailyRollingFileAppender.class替换log4j-1.2.15.jar包里相应的类.
原文章地址及附件地址:http://duanni.iteye.com/blog/177271