有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

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


共 (5) 个答案

  1. # 1 楼答案

    我找到了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

  2. # 2 楼答案

    在log4j中。属性,配置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 {} \;
    
  3. # 3 楼答案

    您可以自定义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);
        }
    }
    
  4. # 4 楼答案

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

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

    chmod 755在包含的文件夹上

    编辑:

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

    编辑2:

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

    因此,crontab中应该包含的bash有如下内容:

    if [ ! -f /tomcat_dir/log4j.log ]
    then
      `touch /tomcat_dir/log4j.log`;
    fi
    
  5. # 5 楼答案

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

    解决方案是检查文件是否存在,如果不存在,则调用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中。属性文件:

    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进行了测试