Log4j不会在删除时重新创建文件

时间:2012-03-30 06:07:48

标签: java linux tomcat logging log4j

我在Tomcat中有一个使用log4j进行日志记录的Web应用程序 如果在Web应用程序运行时删除日志文件,则不会重新创建文件? 如何配置log4j以在删除时重新创建文件而无需重新启动Tomcat?

5 个答案:

答案 0 :(得分:3)

如果您的tomcat位于Linux服务器上,并且您使用对日志文件夹没有执行权限的特定用户启动它,则您的log4j将不会重新创建您的日志,因为它可能只具有读/写权限。

如果是这种情况,请尝试:

包含文件夹

上的

chmod 755

编辑:

第二种可能性是某些操作系统仅在文件不再使用时才完成“删除”操作。如果是这种情况,你的tomcat仍然可以“看到”那里的日志。

EDIT2:

在这种情况下,每隔几分钟创建一个cron作业,检查文件是否在那里。如果不是只是重新创建它。我会在几分钟内提供解决方案。

所以应该在你的crontab中的bash会有类似的东西:

if [ ! -f /tomcat_dir/log4j.log ]
then
  `touch /tomcat_dir/log4j.log`;
fi

答案 1 :(得分:1)

在log4j.properties中,配置RollingFileAppender

#------------------------------------------------------------------------------
#
#  Rolling File Appender
#
#------------------------------------------------------------------------------
log4j.appender.rfile = org.apache.log4j.RollingFileAppender
log4j.appender.rfile.File = logs/server.log
log4j.appender.rfile.Append = false
log4j.appender.rfile.MaxFileSize=10240KB
log4j.appender.rfile.MaxBackupIndex=10
log4j.appender.rfile.layout = org.apache.log4j.PatternLayout
log4j.appender.rfile.layout.ConversionPattern = %d %-5p [%C] (%t) %m (%F:%L)%n

配置每日cron作业(在/etc/crond.daily/中使用sh脚本)清除$ DAYS旧日志

find $LOG_ROOT/log/server.log* -mtime +$DAYS -exec rm {} \;

答案 2 :(得分:0)

我遍历了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对此进行了测试

答案 3 :(得分:0)

我找到了Log4j2的解决方案。

简短
检测文件删除时,我们可以手动初始化翻转过程。

可以使用RollingFileManager初始化翻转:

final LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
// You should know only appender name.
RollingFileAppender appender = (RollingFileAppender) ctx.getConfiguration().getAppenders().get(appenderName);

if (appender != null) {
    // Manually start rollover logic.
    appender.getManager().rollover();
}

更长的是here

答案 4 :(得分:0)

您可以自定义RollingFileAppender并检查文件是否存在。 此代码在每次记录之前检查文件是否存在,并在文件丢失时创建文件。

public class CustomRollingFileAppender extends RollingFileAppender {

// ... Constructor

@Override
    public void append(LoggingEvent event) {
        if (!new File(this.fileName).exists()) {
            try {
                setFile(this.fileName, fileAppend, bufferedIO, bufferSize);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        super.append(event);
    }
}