Log4j FileAppender重新创建已删除的文件

时间:2012-08-24 09:04:29

标签: java log4j fileappender

我正在使用Log4j作为我正在处理的项目中的日志框架。我有以下情况:Log4j配置为将日志写入日志文件。在某些时候,此日志文件将复制到另一个目标并删除。日志框架继续工作,但日志不会写入日志文件,因为它已被删除。有没有办法告诉Log4j重新创建文件并继续将日志写入日志文件。

祝你好运, 拉希德

5 个答案:

答案 0 :(得分:1)

确保您可以在log4j文件中声明此行

    log4j.appender.rollingFile.File=D:/myapp/mylog.log

如果您已经声明了它,您可以根据需要删除或替换日志文件。然后重新运行程序,并在此路径中创建新的日志文件。

答案 1 :(得分:1)

我研究log4j的源代码并发现log4j无法创建新的日志文件,它只是在日志文件被删除时将错误信息打印到system.err

    /** 
     This method determines if there is a sense in attempting to append. 

     <p>It checks whether there is a set output target and also if 
     there is a set layout. If these checks fail, then the boolean 
     value <code>false</code> is returned. */  

  protected   boolean checkEntryConditions() {  
    if(this.closed) {  
      LogLog.warn("Not allowed to write to a closed appender.");  
      return false;  
    }  

    if(this.qw == null) {  
      errorHandler.error("No output stream or file set for the appender named ["+  
            name+"].");  
      return false;  
    }  

    if(this.layout == null) {  
      errorHandler.error("No layout set for the appender named ["+ name+"].");  
      return false;  
    }  
    return true;  
  }  

我认为有两种解决方法

  1. 创建另一个cron线程来监控日志文件
  2. 在getLog或getInstance(singleton)中添加判断,检查日志文件是否存在,如果没有则初始化log4j

答案 2 :(得分:1)

试试这个课程

package wodong.test;
import java.io.File;
import java.io.IOException;

import org.apache.log4j.FileAppender;
import org.apache.log4j.spi.LoggingEvent;

public class LastFileAppender extends FileAppender {
    @Override
    public void append(LoggingEvent event) {
        checkLogFileExist();
        super.append(event);
    }
    private void checkLogFileExist(){
        File logFile = new File(super.fileName);
        if (!logFile.exists()) {
            try {
                logFile.createNewFile();
            } catch (IOException e) {
                System.out.println("Error while create new log file.");
            }
        }
    }
}

还要编辑log4j配置文件

log4j.appender.R=wodong.test.LastFileAppender

答案 3 :(得分:1)

我遍历了log4j的源代码。初始化FileAppender / RollingFileAppender后,将创建一个指向该文件的FileOutputStream实例。创建了一个新的FileDescriptor对象来表示此文件连接。这就是原因,其他解决方案(例如,通过Cron监视文件和通过覆盖在append方法中创建文件)对我不起作用,因为新文件描述符已分配给新文件。 Log4j Writer仍指向旧的FileDescriptor。

解决方案是检查文件是否存在以及是否不调用FileAppender类中存在的activeOptions方法。

package org.apache.log4j;

import java.io.File;
import org.apache.log4j.spi.LoggingEvent;

public class ModifiedRollingFileAppender extends RollingFileAppender {

    @Override 
    public void append(LoggingEvent event) {
        checkLogFileExist();
        super.append(event);
    }

    private void checkLogFileExist(){
        File logFile = new File(super.fileName);
        if (!logFile.exists()) {
            this.activateOptions();
        }
    }
}

最后将其添加到log4j.properties文件:

log4j.rootLogger=DEBUG, A1
log4j.appender.A1=org.apache.log4j.ModifiedRollingFileAppender
log4j.appender.A1.File=/path/to/file
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%d{yy/MM/dd HH:mm:ss,SSS} %p %c{1}: %m%n

//Skip the below lines for FileAppender
log4j.appender.A1.MaxFileSize=10MB
log4j.appender.A1.MaxBackupIndex=2

注意:我已经针对log4j 1.2.17对此进行了测试

答案 4 :(得分:0)

试试这个。我现在没有Linux机器,所以我不确定它是否可以解决性能问题。

package wodong.test;
import java.io.File;
import java.io.IOException;

import org.apache.log4j.FileAppender;
import org.apache.log4j.spi.LoggingEvent;

public class LastFileAppender extends FileAppender {
    @Override
    public void append(LoggingEvent event) {

        checkLogFileExist();
        super.append(event);
    }

    private void checkLogFileExist() {
        if (qw == null) {
            File logFile = new File(super.fileName);
            if (!logFile.exists()) {
                try {
                    logFile.createNewFile();
                } catch (IOException e) {
                    System.out.println("Error while create new log file.");
                }
            }
        }
    }
}